From 5251d11ed350eb6245867f2882f7ad6a38f16565 Mon Sep 17 00:00:00 2001 From: "SukHyung, Kang" Date: Thu, 8 Jul 2021 17:27:20 +0900 Subject: [PATCH 01/16] Add display name for cion db Change-Id: I5fb7078dc6268b20acdf4778aa13c238fac4d6a7 Signed-off-by: SukHyung, Kang --- CMakeLists.txt | 3 +- include/eventsystem_daemon.h | 10 + src/{ => esd_cion}/esd_cion.c | 0 src/esd_cion/esd_cion_db.c | 456 ++++++++++++++++++++++++++++++++++++++++++ src/esd_cion_db.c | 206 ------------------- src/esd_main.c | 158 ++++++++++++++- 6 files changed, 624 insertions(+), 209 deletions(-) rename src/{ => esd_cion}/esd_cion.c (100%) create mode 100644 src/esd_cion/esd_cion_db.c delete mode 100644 src/esd_cion_db.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 66e0a4e..cbdc5cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(esd C) AUX_SOURCE_DIRECTORY(src/ SRCS) +AUX_SOURCE_DIRECTORY(src/esd_cion/ CION_SRCS) SET(VERSION 0.0.1) SET(VERSION_MAJOR 0) @@ -53,7 +54,7 @@ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") ##build eventsystem daemon -add_executable(esd ${SRCS}) +add_executable(esd ${SRCS} ${CION_SRCS}) TARGET_LINK_LIBRARIES(esd eventsystem pkgmgr-client ${pkgs_LDFLAGS}) SET_TARGET_PROPERTIES(esd PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE") SET_TARGET_PROPERTIES(esd PROPERTIES LINK_FLAGS "-pie -Wl,-z,relro") diff --git a/include/eventsystem_daemon.h b/include/eventsystem_daemon.h index 5f600ce..879a62e 100644 --- a/include/eventsystem_daemon.h +++ b/include/eventsystem_daemon.h @@ -54,6 +54,16 @@ void __esd_cion_finalize(void); int esd_cion_db_init(void); int esd_cion_get_uuid_with_generate(const char* appid, char** uuid); +int esd_cion_set_display_name(const char *appid, const char *service_name, + char *display_name); +int esd_cion_get_display_name(const char *appid, const char *service_name, + char **display_name); +int esd_cion_set_enabled(const char *appid, const char *service_name, + bool enabled); +int esd_cion_get_enabled(const char *appid, const char *service_name, + int *enabled); +int esd_cion_get_enabled_service_list(const char *service_name, + const char *display_name, GList **list); #ifdef __cplusplus } diff --git a/src/esd_cion.c b/src/esd_cion/esd_cion.c similarity index 100% rename from src/esd_cion.c rename to src/esd_cion/esd_cion.c diff --git a/src/esd_cion/esd_cion_db.c b/src/esd_cion/esd_cion_db.c new file mode 100644 index 0000000..2cf7fd9 --- /dev/null +++ b/src/esd_cion/esd_cion_db.c @@ -0,0 +1,456 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eventsystem_daemon.h" + +#define DBPATH tzplatform_mkpath(TZ_SYS_DB, ".cion.db") + +#define CREATE_CION_TABLE " \ +PRAGMA user_version = 50; \ +PRAGMA journal_mode = PERSIST; \ +PRAGMA foreign_keys = ON; \ +BEGIN EXCLUSIVE TRANSACTION; \ +CREATE TABLE IF NOT EXISTS cion_uuid ( \ + appid TEXT NOT NULL, \ + uuid TEXT NOT NULL, \ + PRIMARY KEY(appid) \ +); \ +CREATE TABLE IF NOT EXISTS cion_display_name ( \ + service_name TEXT NOT NULL, \ + appid TEXT NOT NULL, \ + display_name TEXT NULL, \ + enabled INTEGER DEFAULT 0, \ + PRIMARY KEY(service_name, appid) , \ + FOREIGN KEY(appid) REFERENCES cion_uuid (appid) ON DELETE CASCADE \ +); \ +COMMIT TRANSACTION; " + +static int __check_table_exist(sqlite3 *db) { + int ret; + const char *val; + sqlite3_stmt *stmt = NULL; + const char query[] = + "SELECT name FROM sqlite_master WHERE type='table'" + " ORDER BY name ASC"; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + _E("prepare error: %s", sqlite3_errmsg(db)); + ret = -1; + goto out; + } + + ret = sqlite3_step(stmt); + if (ret != SQLITE_ROW) { + _E("fail to get row"); + ret = -1; + goto out; + } + + val = (const char*)sqlite3_column_text(stmt, 0); + if (val == NULL) { + _E("name is NULL"); + ret = -1; + goto out; + } + + if (strcmp("cion", val) != 0) { + ret = -1; + goto out; + } + + ret = 0; + +out: + sqlite3_finalize(stmt); + + return ret; +} + +static int __create_table(sqlite3 *db) { + int ret; + char *errmsg = NULL; + + ret = sqlite3_exec(db, CREATE_CION_TABLE, + NULL, NULL, &errmsg); + if (ret != SQLITE_OK) { + _E("create table fail : %s", errmsg); + sqlite3_free(errmsg); + return -1; + } + + return 0; +} + +int esd_cion_db_init(void) { + sqlite3 *db = NULL; + + if (sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) { + sqlite3_close_v2(db); + unlink(DBPATH); + + if (sqlite3_open_v2(DBPATH, &db, + SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, + NULL) != SQLITE_OK) { + _E("Fail to create db"); + unlink(DBPATH); + return -1; + } + } + + if (__check_table_exist(db) < 0) { + if (__create_table(db) < 0) { + sqlite3_close_v2(db); + _E("Fail to create table"); + return -1; + } + } + + sqlite3_close_v2(db); + + return 0; +} + +sqlite3 *esd_cion_db_open() { + sqlite3 *db; + + if (access(DBPATH, R_OK | W_OK) != 0) + return NULL; + + if (sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) + return NULL; + + return db; +} + +int esd_cion_db_close(sqlite3 **db) { + if (db == NULL || *db == NULL) + return 0; + + if (sqlite3_close(*db) != SQLITE_OK) { + _E("Failed to close db"); + return 0; + } + + *db = NULL; + + return 0; +} + +static const char *__esd_cion_generate_uuid() { + uuid_t uu; + char _uuid[37]; + char *uuid; + + uuid_generate_random(uu); + uuid_unparse(uu, _uuid); + + uuid = strdup(_uuid); + + return uuid; +} + +static int __esd_cion_get_uuid(sqlite3 *db, const char *appid, char **uuid) { + int ret = -1; + char *query; + sqlite3_stmt *stmt; + + query = sqlite3_mprintf("SELECT uuid FROM cion_uuid " + "WHERE appid = %Q", appid); + if (query == NULL) + goto out; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) + goto out; + + ret = sqlite3_step(stmt); + if (ret == SQLITE_ROW) { + ret = 0; + *uuid = strdup((char*)sqlite3_column_text(stmt, 0)); + } + +out: + sqlite3_free(query); + sqlite3_finalize(stmt); + + return ret; +} + +static int __esd_cion_set_uuid(sqlite3 *db, const char *appid, const char *uuid) { + int ret = -1; + char *query; + sqlite3_stmt *stmt; + + query = sqlite3_mprintf("INSERT INTO cion_uuid (appid, uuid) " + "VALUES (%Q, %Q) ", appid, uuid); + if (query == NULL) + goto out; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) + goto out; + + ret = sqlite3_step(stmt); + if (ret == SQLITE_OK || ret == SQLITE_DONE) + ret = 0; + +out: + sqlite3_free(query); + sqlite3_finalize(stmt); + + return ret; +} + +int esd_cion_get_uuid_with_generate(const char *appid, char **uuid) { + int ret = 0; + sqlite3 *db; + const char *_uuid; + + db = esd_cion_db_open(); + if (!db) { + _E("db open fail"); + return -1; + } + + if (__esd_cion_get_uuid(db, appid, uuid) != 0) { + _uuid = __esd_cion_generate_uuid(); + ret = __esd_cion_set_uuid(db, appid, _uuid); + if (ret == 0) + *uuid = (char*)_uuid; + else + free((char*)_uuid); + + _E("get uuid generate"); + } + + esd_cion_db_close(&db); + + return ret; +} + +int esd_cion_set_display_name(const char *appid, const char *service_name, + char *display_name) { + int ret = -1; + sqlite3 *db; + char *query = NULL; + sqlite3_stmt *stmt = NULL; + char *_uuid; + + db = esd_cion_db_open(); + if (!db) { + _E("db open fail"); + return -1; + } + + if (__esd_cion_get_uuid(db, appid, &_uuid) == 0) { + free(_uuid); + } else { + _uuid = (char*)__esd_cion_generate_uuid(); + ret = __esd_cion_set_uuid(db, appid, _uuid); + if (ret != 0) { + free(_uuid); + goto out; + } + _E("set uuid generate"); + } + + query = sqlite3_mprintf("INSERT INTO cion_display_name " + "(service_name, appid, display_name) " + "VALUES (%Q, %Q, %Q) ON CONFLICT(service_name, appid)" + "DO UPDATE SET display_name = %Q " + "WHERE service_name = %Q AND appid = %Q ", service_name, appid, display_name, + display_name, service_name, appid); + if (query == NULL) + goto out; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) + goto out; + + ret = sqlite3_step(stmt); + _E("set name step: %d", ret); + + if (ret == SQLITE_OK || ret == SQLITE_DONE) + ret = 0; + +out: + sqlite3_free(query); + sqlite3_finalize(stmt); + esd_cion_db_close(&db); + + return ret; +} + +int esd_cion_get_display_name(const char *appid, const char *service_name, + char **display_name) { + int ret = -1; + sqlite3 *db; + char *query = NULL; + sqlite3_stmt *stmt = NULL; + char *_name = NULL; + + db = esd_cion_db_open(); + if (!db) { + _E("db open fail"); + return -1; + } + + query = sqlite3_mprintf("SELECT display_name FROM cion_display_name " + "WHERE appid = %Q AND service_name = %Q", appid, service_name); + if (query == NULL) + goto out; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) + goto out; + + ret = sqlite3_step(stmt); + if (ret == SQLITE_ROW) { + ret = 0; + + _name = (char*)sqlite3_column_text(stmt, 0); + + if (_name != NULL) + *display_name = strdup(_name); + else + _E("get display name null"); + + } else if (ret == SQLITE_DONE){ + _E("get display name not exist"); + ret = 0; + } + +out: + sqlite3_free(query); + sqlite3_finalize(stmt); + esd_cion_db_close(&db); + + return ret; +} + +int esd_cion_set_enabled(const char *appid, const char *service_name, + bool enabled) { + int ret = -1; + sqlite3 *db; + char *query = NULL; + sqlite3_stmt *stmt = NULL; + + db = esd_cion_db_open(); + if (!db) { + _E("db open fail"); + return -1; + } + + query = sqlite3_mprintf("UPDATE cion_display_name SET enabled = %i " + "WHERE appid = %Q AND service_name = %Q", enabled? 1 : 0 , + appid, service_name); + if (query == NULL) + goto out; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) + goto out; + + ret = sqlite3_step(stmt); + if (ret == SQLITE_OK || ret == SQLITE_DONE) + ret = 0; + +out: + sqlite3_free(query); + sqlite3_finalize(stmt); + esd_cion_db_close(&db); + + return ret; +} + +int esd_cion_get_enabled(const char *appid, const char *service_name, + int *enabled) { + int ret = -1; + sqlite3 *db; + char *query = NULL; + sqlite3_stmt *stmt = NULL; + + db = esd_cion_db_open(); + if (!db) { + _E("db open fail"); + return -1; + } + + query = sqlite3_mprintf("SELECT enabled FROM cion_display_name " + "WHERE appid = %Q AND service_name = %Q", appid, service_name); + if (query == NULL) + goto out; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) + goto out; + + ret = sqlite3_step(stmt); + if (ret == SQLITE_ROW) { + ret = 0; + + *enabled = sqlite3_column_int(stmt, 0); + } else if (ret == SQLITE_DONE){ + _E("get enabled not exist"); + ret = 0; + } + +out: + sqlite3_free(query); + sqlite3_finalize(stmt); + esd_cion_db_close(&db); + + return ret; +} + +int esd_cion_get_enabled_service_list(const char *service_name, + const char *display_name, GList **list) +{ + int ret = -1; + sqlite3 *db; + char *query = NULL; + sqlite3_stmt *stmt = NULL; + char *appid; + + db = esd_cion_db_open(); + if (!db) { + _E("db open fail"); + return -1; + } + + if (display_name) + query = sqlite3_mprintf("SELECT appid FROM cion_display_name " + "WHERE service_name = %Q AND display_name = %Q AND enabled = 1", + service_name, display_name); + else + query = sqlite3_mprintf("SELECT appid FROM cion_display_name " + "WHERE service_name = %Q AND enabled = 1", service_name); + if (query == NULL) + goto out; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) + goto out; + + while(sqlite3_step(stmt) == SQLITE_ROW) { + appid = strdup((char*)sqlite3_column_text(stmt, 0)); + _E("get appid list : %s", appid); + + *list = g_list_append(*list, appid); + } + +out: + sqlite3_free(query); + sqlite3_finalize(stmt); + esd_cion_db_close(&db); + + return ret; +} diff --git a/src/esd_cion_db.c b/src/esd_cion_db.c deleted file mode 100644 index 2c34c62..0000000 --- a/src/esd_cion_db.c +++ /dev/null @@ -1,206 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "eventsystem_daemon.h" - -#define DBPATH tzplatform_mkpath(TZ_SYS_DB, ".cion.db") - -#define CREATE_CION_TABLE " \ -PRAGMA user_version = 50; \ -PRAGMA journal_mode = PERSIST; \ -PRAGMA foreign_keys = ON; \ -BEGIN EXCLUSIVE TRANSACTION; \ -CREATE TABLE IF NOT EXISTS cion_info ( \ - appid TEXT NOT NULL, \ - uuid TEXT NOT NULL, \ - PRIMARY KEY (appid) \ -); \ -COMMIT TRANSACTION; " - -static int __check_table_exist(sqlite3 *db) { - int ret; - const char *val; - sqlite3_stmt *stmt = NULL; - const char query[] = - "SELECT name FROM sqlite_master WHERE type='table'" - " ORDER BY name ASC"; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _E("prepare error: %s", sqlite3_errmsg(db)); - ret = -1; - goto out; - } - - ret = sqlite3_step(stmt); - if (ret != SQLITE_ROW) { - _E("fail to get row"); - ret = -1; - goto out; - } - - val = (const char*)sqlite3_column_text(stmt, 0); - if (val == NULL) { - _E("name is NULL"); - ret = -1; - goto out; - } - - if (strcmp("cion", val) != 0) { - ret = -1; - goto out; - } - - ret = 0; - -out: - sqlite3_finalize(stmt); - - return ret; -} - -static int __create_table(sqlite3 *db) { - int ret; - char *errmsg = NULL; - - ret = sqlite3_exec(db, CREATE_CION_TABLE, - NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - _E("create table fail : %s", errmsg); - sqlite3_free(errmsg); - return -1; - } - - return 0; -} - -int esd_cion_db_init(void) { - sqlite3 *db = NULL; - - if (sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) { - sqlite3_close_v2(db); - unlink(DBPATH); - - if (sqlite3_open_v2(DBPATH, &db, - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - NULL) != SQLITE_OK) { - _E("Fail to create db"); - unlink(DBPATH); - return -1; - } - } - - if (__check_table_exist(db) < 0) { - if (__create_table(db) < 0) { - sqlite3_close_v2(db); - _E("Fail to create table"); - return -1; - } - } - - sqlite3_close_v2(db); - - return 0; -} - -sqlite3 *esd_cion_db_open() { - sqlite3 *db; - - if (access(DBPATH, R_OK | W_OK) != 0) - return NULL; - - if (sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) - return NULL; - - return db; -} - -int esd_cion_db_close(sqlite3 **db) { - if (db == NULL || *db == NULL) - return 0; - - if (sqlite3_close(*db) != SQLITE_OK) { - _E("Failed to close db"); - return 0; - } - - *db = NULL; - - return 0; -} - -static const char *__esd_cion_generate_uuid() { - uuid_t uu; - char _uuid[37]; - char *uuid; - - uuid_generate_random(uu); - uuid_unparse(uu, _uuid); - - uuid = strdup(_uuid); - - return uuid; -} - -int esd_cion_get_uuid_with_generate(const char *appid, char **uuid) { - int ret; - sqlite3 *db; - char *query = NULL; - sqlite3_stmt *stmt = NULL; - const char *_uuid; - - db = esd_cion_db_open(); - if (!db) { - _E("db open fail"); - return -1; - } - - query = sqlite3_mprintf("SELECT uuid FROM cion_info " - "WHERE appid = %Q", appid); - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - ret = -1; - goto out; - } - - ret = sqlite3_step(stmt); - if (ret == SQLITE_ROW) { - ret = 0; - *uuid = strdup((char*)sqlite3_column_text(stmt, 0)); - } else { - sqlite3_free(query); - sqlite3_finalize(stmt); - stmt = NULL; - - _uuid = __esd_cion_generate_uuid(); - query = sqlite3_mprintf("INSERT INTO cion_info (appid, uuid) " - "VALUES (%Q, %Q) ", appid, _uuid); - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - ret = -1; - goto out; - } - - ret = sqlite3_step(stmt); - if (ret == SQLITE_OK || ret == SQLITE_DONE) { - ret = 0; - *uuid = strdup(_uuid); - } else { - ret = -1; - } - } - -out: - sqlite3_free(query); - sqlite3_finalize(stmt); - esd_cion_db_close(&db); - - return ret; -} diff --git a/src/esd_main.c b/src/esd_main.c index 9d4480e..dabb5ce 100644 --- a/src/esd_main.c +++ b/src/esd_main.c @@ -1246,10 +1246,30 @@ static const gchar introspection_xml[] = " " " " " " -" " +" " " " " " " " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " ""; @@ -1844,6 +1864,132 @@ out: g_dbus_method_invocation_return_value(invocation, param); } +static void set_display_name_method_call(GDBusConnection *connection, + const gchar *sender, GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + GVariant *param = NULL; + int result = ES_R_OK; + char app_id[128] = { 0, }; + int sender_pid; + char *display_name = NULL; + char *service_name = NULL; + + sender_pid = __get_sender_pid(connection, sender); + if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) { + _E("failed to get appid by pid"); + result = ES_R_ERROR; + goto out; + } + + g_variant_get(parameters, "(&s&s)", &service_name, &display_name); + + if (esd_cion_set_display_name(app_id, service_name, display_name) != 0) + result = ES_R_ERROR; + +out: + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); +} + +static void get_display_name_method_call(GDBusConnection *connection, + const gchar *sender, GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + GVariant *param = NULL; + int result = ES_R_OK; + char app_id[128] = { 0, }; + int sender_pid; + char *service_name = NULL; + char *display_name = NULL; + + sender_pid = __get_sender_pid(connection, sender); + if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) { + _E("failed to get appid by pid"); + result = ES_R_ERROR; + goto out; + } + + g_variant_get(parameters, "(&s)", &service_name); + + if (esd_cion_get_display_name(app_id, service_name, &display_name) == 0) { + if (display_name != NULL) { + param = g_variant_new("(is)", result, display_name); + free(display_name); + } else { + goto out; + } + } else { + result = ES_R_ERROR; + } + +out: + if (param == NULL) + param = g_variant_new("(is)", result, ""); + + g_dbus_method_invocation_return_value(invocation, param); +} + +static void set_enabled_method_call(GDBusConnection *connection, + const gchar *sender, GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + GVariant *param = NULL; + int result = ES_R_OK; + char app_id[128] = { 0, }; + int sender_pid; + gboolean enabled; + char *service_name = NULL; + + sender_pid = __get_sender_pid(connection, sender); + if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) { + _E("failed to get appid by pid"); + result = ES_R_ERROR; + goto out; + } + + g_variant_get(parameters, "(&sb)", &service_name, &enabled); + + if (esd_cion_set_enabled(app_id, service_name, (bool)enabled) != 0) + result = ES_R_ERROR; + +out: + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); +} + +static void get_enabled_method_call(GDBusConnection *connection, + const gchar *sender, GVariant *parameters, + GDBusMethodInvocation *invocation) +{ + GVariant *param = NULL; + int result = ES_R_OK; + char app_id[128] = { 0, }; + int sender_pid; + char *service_name = NULL; + int enabled; + + sender_pid = __get_sender_pid(connection, sender); + if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) { + _E("failed to get appid by pid"); + result = ES_R_ERROR; + goto out; + } + + g_variant_get(parameters, "(&s)", &service_name); + + if (esd_cion_get_enabled(app_id, service_name, &enabled) == 0) + param = g_variant_new("(ib)", result, (bool)enabled); + else + result = ES_R_ERROR; + +out: + if (param == NULL) + param = g_variant_new("(ib)", result, false); + + g_dbus_method_invocation_return_value(invocation, param); +} + static void handle_method_call(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, @@ -1870,8 +2016,16 @@ static void handle_method_call(GDBusConnection *connection, check_last_data_method_call(connection, sender, parameters, invocation); } else if (g_strcmp0(method_name, "LaunchOnEventFromUserEvent") == 0) { launch_on_event_from_userevent(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "GetUuid") == 0) { + } else if (g_strcmp0(method_name, "CionGetUuid") == 0) { get_uuid_method_call(connection, sender, parameters, invocation); + } else if (g_strcmp0(method_name, "CionSetDisplayName") == 0) { + set_display_name_method_call(connection, sender, parameters, invocation); + } else if (g_strcmp0(method_name, "CionGetDisplayName") == 0) { + get_display_name_method_call(connection, sender, parameters, invocation); + } else if (g_strcmp0(method_name, "CionSetEnabled") == 0) { + set_enabled_method_call(connection, sender, parameters, invocation); + } else if (g_strcmp0(method_name, "CionGetEnabled") == 0) { + get_enabled_method_call(connection, sender, parameters, invocation); } } -- 2.7.4 From a141d3e9fdf5db7af96ac46a54486d719878e2f7 Mon Sep 17 00:00:00 2001 From: Inkyun Kil Date: Thu, 19 Aug 2021 14:07:08 +0900 Subject: [PATCH 02/16] Add Cion Server - Discovery ondemand list for cion - Ondemand Launch Application for cion Related patch : https://review.tizen.org/gerrit/c/platform/core/appfw/cion/+/261308 https://review.tizen.org/gerrit/c/platform/core/appfw/cion/+/262199 Change-Id: I71ae650acf99c7cacef2b3e0bfbacb2bfe8b45d6 Signed-off-by: Inkyun Kil --- CMakeLists.txt | 8 +- include/eventsystem_daemon.h | 19 +- packaging/esd.spec | 3 + src/esd_cion/cion_ondemand_server.cc | 366 +++++++++++++++++++++++++++++++++++ src/esd_cion/cion_ondemand_server.h | 62 ++++++ src/esd_cion/cion_peer_info.cc | 35 ++++ src/esd_cion/cion_peer_info.h | 36 ++++ src/esd_cion/esd_cion.c | 316 ------------------------------ src/esd_cion/esd_cion.cc | 62 ++++++ src/esd_cion/esd_cion_db.c | 51 +++-- src/esd_main.c | 3 +- 11 files changed, 623 insertions(+), 338 deletions(-) create mode 100644 src/esd_cion/cion_ondemand_server.cc create mode 100644 src/esd_cion/cion_ondemand_server.h create mode 100644 src/esd_cion/cion_peer_info.cc create mode 100644 src/esd_cion/cion_peer_info.h delete mode 100644 src/esd_cion/esd_cion.c create mode 100644 src/esd_cion/esd_cion.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index cbdc5cb..d207d7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(esd C) +PROJECT(esd C CXX) AUX_SOURCE_DIRECTORY(src/ SRCS) AUX_SOURCE_DIRECTORY(src/esd_cion/ CION_SRCS) @@ -23,6 +23,7 @@ INCLUDE(FindPkgConfig) pkg_check_modules(pkgs REQUIRED dlog bundle + parcel pkgmgr-info glib-2.0 gio-2.0 @@ -37,6 +38,8 @@ pkg_check_modules(pkgs REQUIRED security-manager sqlite3 uuid + cion + capi-system-info ) FOREACH(flag ${pkgs_CFLAGS}) @@ -48,6 +51,7 @@ ENDFOREACH(flag) ## Additional flag SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -Wall -Werror") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++14 -Werror") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") ## Linker flags @@ -56,7 +60,7 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") ##build eventsystem daemon add_executable(esd ${SRCS} ${CION_SRCS}) TARGET_LINK_LIBRARIES(esd eventsystem pkgmgr-client ${pkgs_LDFLAGS}) -SET_TARGET_PROPERTIES(esd PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE") +SET_TARGET_PROPERTIES(esd PROPERTIES COMPILE_FLAGS ${CFLAGS} ${CXXFLAGS} "-fPIE") SET_TARGET_PROPERTIES(esd PROPERTIES LINK_FLAGS "-pie -Wl,-z,relro") # pkgconfig file diff --git a/include/eventsystem_daemon.h b/include/eventsystem_daemon.h index 879a62e..706a89b 100644 --- a/include/eventsystem_daemon.h +++ b/include/eventsystem_daemon.h @@ -25,6 +25,9 @@ extern "C" { #endif +#include +#include + #undef LOG_TAG #define LOG_TAG "ESD" @@ -48,9 +51,18 @@ extern "C" { #define SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED "StartupFinished" #define SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED "UserSessionStartupFinished" +typedef struct cion_service_info { + char *service_name; + char *appid; + char *display_name; +} cion_service_info_s; + int __esd_register_vconf_callbacks(void); -int __esd_cion_init(void); -void __esd_cion_finalize(void); + +int _esd_cion_init(void); +void _esd_cion_adds_enabled_app(const char *service_name, const char *app_id, + const char *display_name); +void _esd_cion_removes_enabled_app(const char *service_name, const char *app_id); int esd_cion_db_init(void); int esd_cion_get_uuid_with_generate(const char* appid, char** uuid); @@ -62,8 +74,7 @@ int esd_cion_set_enabled(const char *appid, const char *service_name, bool enabled); int esd_cion_get_enabled(const char *appid, const char *service_name, int *enabled); -int esd_cion_get_enabled_service_list(const char *service_name, - const char *display_name, GList **list); +int esd_cion_get_enabled_service_list(GList **list); #ifdef __cplusplus } diff --git a/packaging/esd.spec b/packaging/esd.spec index 6d7c3c5..4bcc907 100644 --- a/packaging/esd.spec +++ b/packaging/esd.spec @@ -9,6 +9,7 @@ Source1: esd.service BuildRequires: cmake BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(bundle) +BuildRequires: pkgconfig(parcel) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(pkgmgr-info) BuildRequires: pkgconfig(appsvc) @@ -26,6 +27,8 @@ BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(security-manager) BuildRequires: pkgconfig(uuid) BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(cion) +BuildRequires: pkgconfig(capi-system-info) Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig diff --git a/src/esd_cion/cion_ondemand_server.cc b/src/esd_cion/cion_ondemand_server.cc new file mode 100644 index 0000000..0d5965e --- /dev/null +++ b/src/esd_cion/cion_ondemand_server.cc @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eventsystem_daemon.h" +#include "cion_ondemand_server.h" +#include "cion_peer_info.h" + + +namespace { + +std::string GetAppVersion(const char* appid) { + char *pkgid; + char *pkg_version = NULL; + pkgmgrinfo_appinfo_h appinfo = NULL; + + int retval = pkgmgrinfo_appinfo_get_usr_appinfo(appid, getuid(), &appinfo); + if (retval != PMINFO_R_OK) + return {}; + + retval = pkgmgrinfo_appinfo_get_pkgid(appinfo, &pkgid); + if (retval != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(appinfo); + return {}; + } + + pkgmgrinfo_pkginfo_h pkginfo = NULL; + retval = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkginfo); + if (retval != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(appinfo); + return {}; + } + + retval = pkgmgrinfo_pkginfo_get_version(pkginfo, &pkg_version); + if (retval != PMINFO_R_OK) { + pkgmgrinfo_appinfo_destroy_appinfo(appinfo); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + return {}; + } + + std::string version(pkg_version); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + pkgmgrinfo_appinfo_destroy_appinfo(appinfo); + + return version; +} + +std::string GetSystemInfoPlatformString(const char* key) { + char* val = nullptr; + int ret = system_info_get_platform_string(key, &val); + if (ret != SYSTEM_INFO_ERROR_NONE || !val) + return {}; + + std::string val_str = val; + free(val); + + return val_str; +} + +std::string GetVconfString(const char* key) { + char* val = vconf_get_str(key); + if (val == nullptr) + return {}; + + std::string val_str = val; + free(val); + + return val_str; +} + +void FreeList(gpointer data) { + cion_service_info_s *info = (cion_service_info_s *)data; + + free(info->appid); + free(info->service_name); + if (info->display_name) + free(info->display_name); + free(info); +} + +std::string device_id = GetSystemInfoPlatformString("http://tizen.org/system/tizenid"); +std::string device_name = GetVconfString(VCONFKEY_SETAPPL_DEVICE_NAME_STR); +std::string device_platform = "Tizen"; +std::string device_platform_version = + GetSystemInfoPlatformString("http://tizen.org/feature/platform.version"); +std::string device_type = GetSystemInfoPlatformString("http://tizen.org/system/device_type"); + +} // namespace + +CionOndemandServer::CionOndemandServer(std::string service_name, + std::string display_name) + : cion::channel::ServerChannel(service_name, display_name) { + LoadOndemandServiceList(); +} + +CionOndemandServer::CionOndemandServer(std::string service_name, + std::string display_name, cion::SecurityInfo security) : + cion::channel::ServerChannel(service_name, display_name, + std::move(security)) { + LoadOndemandServiceList(); +} + +void CionOndemandServer::OnConnectionResult(std::shared_ptr info, + const cion::ConnectionResult& result) { +} + +void CionOndemandServer::OnDisconnected(std::shared_ptr peer) { +} + +std::vector CionOndemandServer::OnDataReceived( + const std::vector& data, std::shared_ptr peer) { + std::string return_data("returned"); + + std::vector v(return_data.begin(), return_data.end()); + return v; +} + +void CionOndemandServer::OnPayloadReceived(std::shared_ptr data, + std::shared_ptr peer, + IPayloadReceiver::PayloadTransferStatus status) { +} + +void CionOndemandServer::OnConnectionRequest( + std::shared_ptr peer) { +} + +void CionOndemandServer::OnOndemandListRequested( + std::shared_ptr data, + std::shared_ptr peer) { + std::vector raw; + + _D("[Request Ondemand List]"); + + if (data->GetType() == cion::IPayload::PayloadType::File) + return; + + std::shared_ptr data_payload = + std::dynamic_pointer_cast(data); + std::vector requested_data = data_payload->GetData(); + tizen_base::Parcel ondemand_parcel(requested_data.data(), + requested_data.size()); + + std::string list_header = ondemand_parcel.ReadString(); + std::string list_service_name = ondemand_parcel.ReadString(); + _D("Ondemand Service_name : %s", list_service_name.c_str()); + if (list_header == std::string("OndemandList")) { + raw = GetOndemandList(list_service_name).GetRaw(); + if (raw.size() == 0) + return; + } + + auto dpl = std::make_unique(); + std::vector listdata_vector(raw.begin(), raw.end()); + dpl->SetData(listdata_vector); + + SendPayloadAsync(dpl.get(), peer, [] ( + std::shared_ptr result) { + _I("result received !!! %s", result->GetPayloadID().c_str()); + }); +} + +int CionOndemandServer::OnOndemandLaunchRequested( + std::shared_ptr data, + std::shared_ptr peer) { + //TODO check privilege app_id + std::string app_id = peer->GetAppID(); + int ret = -20; + + cion::IPayload::PayloadType type = data->GetType(); + if (type == cion::IPayload::PayloadType::File) + return ret; + + std::shared_ptr data_payload = + std::dynamic_pointer_cast(data); + + std::vector getdata = data_payload->GetData(); + std::string launch_requested(getdata.begin(), getdata.end()); + + ret = OndemandLaunchApp(launch_requested); + if (ret != 0) { + _E("Faled to __esd_cion_launch_ondemand : %d", ret); + } + + return ret; +} + +int CionOndemandServer::OndemandLaunchApp(std::string appid) { + uid_t uid = getuid(); + tizen_base::Bundle b; + int ret = -20; + bool found = false; + + for (std::shared_ptr cs : ondemand_peer_list_) { + if (cs->GetAppID() == appid) { + found = true; + break; + } + } + + if (found == false) { + _E("%s is not found", appid.c_str()); + return ret; + } + + _D("cion launch ondemand: app_id(%s)", appid.c_str()); + + if (!aul_app_is_running_for_uid(appid.c_str(), uid)) { + aul_svc_set_operation(b.GetHandle(), AUL_SVC_OPERATION_DEFAULT); + aul_svc_set_appid(b.GetHandle(), appid.c_str()); + + ret = aul_svc_run_service_async_for_uid(b.GetHandle(), 0, NULL, NULL, uid); + if (ret < 0) + _E("Failed to launch app : %s", appid.c_str()); + + } else { + _D("already is running or launch failed"); + } + + return ret; +} + +void CionOndemandServer::LoadOndemandServiceList() { + GList *list = nullptr; + int ret = esd_cion_get_enabled_service_list(&list); + if (ret != 0 || list == nullptr) { + _E("Get list error"); + } else { + for (GList *it = g_list_first(list); it; it = g_list_next(it)) { + cion_service_info *cion_info = (cion_service_info_s *)(it->data); + char *app_id = cion_info->appid; + char *service_name = cion_info->service_name; + char *display_name = cion_info->display_name; + char *uuid; + ret = esd_cion_get_uuid_with_generate(app_id, &uuid); + if (ret != 0) { + _E("Get uuid for %s", app_id); + } + + std::string app_version = GetAppVersion(app_id); + + tizen_base::Parcel parcel; + parcel.WriteString(device_id); + parcel.WriteString(device_name); + parcel.WriteString(device_platform); + parcel.WriteString(device_platform_version); + parcel.WriteString(device_type); + parcel.WriteString(std::string(app_id)); + parcel.WriteString(app_version); + parcel.WriteString(std::string(uuid)); + parcel.WriteString(std::string(display_name)); + + std::shared_ptr pi = + std::make_shared(std::string(service_name), + parcel.GetRaw().data(), parcel.GetRaw().size()); + ondemand_peer_list_.emplace_back(pi); + + free(uuid); + } + } + + g_list_free_full(list, FreeList); +} + +void CionOndemandServer::AddOndemandServiceList(std::string service_name, + std::string appid, std::string display_name) { + for (auto peer : ondemand_peer_list_) { + if (peer->GetServiceName() == service_name && + peer->GetAppID() == appid) { + _W("%s is already exist", appid.c_str()); + return; + } + } + + char *uuid; + int ret = esd_cion_get_uuid_with_generate(appid.c_str(), &uuid); + if (ret != 0) { + _E("Get uuid for %s", appid.c_str()); + return; + } + + std::string app_version = GetAppVersion(appid.c_str()); + + tizen_base::Parcel parcel; + parcel.WriteString(device_id); + parcel.WriteString(device_name); + parcel.WriteString(device_platform); + parcel.WriteString(device_platform_version); + parcel.WriteString(device_type); + parcel.WriteString(appid); + parcel.WriteString(app_version); + parcel.WriteString(std::string(uuid)); + parcel.WriteString(display_name); + + std::shared_ptr pi = + std::make_shared(service_name, parcel.GetRaw().data(), + parcel.GetRaw().size()); + ondemand_peer_list_.emplace_back(pi); + _D("[%s:%s] is added to list", appid.c_str(), service_name.c_str()); +} + +void CionOndemandServer::RemoveOndemandServiceList(std::string service_name, + std::string appid) { + for (auto peer = ondemand_peer_list_.begin(); + peer != ondemand_peer_list_.end(); peer++) { + if (peer->get()->GetServiceName() == service_name && + peer->get()->GetAppID() == appid) { + ondemand_peer_list_.erase(peer); + _D("[%s:%s] is removed from list", appid.c_str(), service_name.c_str()); + break; + } + } +} + +tizen_base::Parcel CionOndemandServer::GetOndemandList( + std::string service_name) { + if (ondemand_peer_list_.size() == 0) { + _W("ondemand peer list is empty"); + return {}; + } + + std::string header("ODL:"); + tizen_base::Parcel parcel; + parcel.WriteString(header); + + for (auto peer : ondemand_peer_list_) { + if (peer->GetServiceName() != service_name || + aul_app_is_running(peer->GetAppID().c_str())) + continue; + + parcel.WriteBool(true); + std::vector peer_raw = peer->Serialize(); + parcel.WriteUInt32(peer_raw.size()); + parcel.Write(peer_raw.data(), peer_raw.size()); + } + + parcel.WriteBool(false); + + return parcel; +} \ No newline at end of file diff --git a/src/esd_cion/cion_ondemand_server.h b/src/esd_cion/cion_ondemand_server.h new file mode 100644 index 0000000..b3852d0 --- /dev/null +++ b/src/esd_cion/cion_ondemand_server.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_DAEMON_CION_ONDEMAND_SERVER_H_ +#define EVENTSYSTEM_DAEMON_CION_ONDEMAND_SERVER_H_ + +#include + +#include +#include +#include + +#include "cion_peer_info.h" + +class CionOndemandServer : public cion::channel::ServerChannel { + public: + explicit CionOndemandServer(std::string service_name, + std::string display_name); + explicit CionOndemandServer(std::string service_name, + std::string display_name, cion::SecurityInfo security); + + void AddOndemandServiceList(std::string service_name, std::string appid, + std::string display_name); + void RemoveOndemandServiceList(std::string service_name, std::string appid); + + protected: + void OnConnectionResult(std::shared_ptr info, + const cion::ConnectionResult& result) override; + void OnDisconnected(std::shared_ptr peer) override; + std::vector OnDataReceived(const std::vector& data, + std::shared_ptr peer) override; + void OnPayloadReceived(std::shared_ptr data, + std::shared_ptr peer, + IPayloadReceiver::PayloadTransferStatus status) override; + void OnConnectionRequest(std::shared_ptr peer) override; + void OnOndemandListRequested(std::shared_ptr data, + std::shared_ptr peer) override; + int OnOndemandLaunchRequested(std::shared_ptr data, + std::shared_ptr peer) override; + + int OndemandLaunchApp(std::string appid); + void LoadOndemandServiceList(); + tizen_base::Parcel GetOndemandList(std::string service_name); + + private: + std::list> ondemand_peer_list_; +}; + +#endif /* EVENTSYSTEM_DAEMON_CION_ONDEMAND_SERVER_H_ */ \ No newline at end of file diff --git a/src/esd_cion/cion_peer_info.cc b/src/esd_cion/cion_peer_info.cc new file mode 100644 index 0000000..33705d8 --- /dev/null +++ b/src/esd_cion/cion_peer_info.cc @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "cion_peer_info.h" + +CionPeerInfo::CionPeerInfo(std::string service_name) : cion::PeerInfo(), + service_name_(service_name) { +} + +CionPeerInfo::CionPeerInfo(std::string service_name, + const void* buf, uint32_t size) : cion::PeerInfo(buf, size), + service_name_(service_name){ + +} + +void CionPeerInfo::SetServiceName(std::string service_name) { + service_name_ = service_name; +} + +std::string CionPeerInfo::GetServiceName() const { + return service_name_; +} \ No newline at end of file diff --git a/src/esd_cion/cion_peer_info.h b/src/esd_cion/cion_peer_info.h new file mode 100644 index 0000000..acf14b0 --- /dev/null +++ b/src/esd_cion/cion_peer_info.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_DAEMON_CION_PEER_INFO_H_ +#define EVENTSYSTEM_DAEMON_CION_PEER_INFO_H_ + +#include + +#include + +class CionPeerInfo : public cion::PeerInfo { + public: + CionPeerInfo(std::string service_name); + CionPeerInfo(std::string service_name, const void* buf, uint32_t size); + + std::string GetServiceName() const; + void SetServiceName(std::string service_name); + + private: + std::string service_name_; +}; + +#endif /* EVENTSYSTEM_DAEMON_CION_PEER_INFO_H_ */ \ No newline at end of file diff --git a/src/esd_cion/esd_cion.c b/src/esd_cion/esd_cion.c deleted file mode 100644 index 48447e0..0000000 --- a/src/esd_cion/esd_cion.c +++ /dev/null @@ -1,316 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "eventsystem_daemon.h" - -#define CION_METADATA_KEY "http://tizen.org/metadata/cion" - -static uid_t cur_uid; -static pkgmgr_client *pkgmgr; -static GList *service_list; - -struct cion_service { - char *pkgid; - char *appid; - char *service_name; - char *uuid; - int port; -}; - -static void __free_cion_service(gpointer data) -{ - struct cion_service *service = (struct cion_service *)data; - - free(service->pkgid); - free(service->appid); - free(service->service_name); - free(service->uuid); - free(service); -} - -static int __esd_cion_set_cur_uid(void) -{ - /* TODO(jeremy.jang): get current user from gumd or systemd */ - cur_uid = 5001; - return 0; -} - -static int __esd_cion_foreach_metadata_callback(const char *key, - const char *val, void *user_data) -{ - struct cion_service *service; - GList **service_list = (GList **)user_data; - - if (strncmp(key, CION_METADATA_KEY, strlen(CION_METADATA_KEY)) != 0) - return 0; - - if (val == NULL || strlen(val) == 0) { - _E("Service name is mandatory"); - return 0; - } - - service = calloc(1, sizeof(struct cion_service)); - if (service == NULL) { - _E("Out of memory"); - return -1; - } - - service->service_name = strdup(val); - if (service->service_name == NULL) { - _E("Out of memory"); - return -1; - } - - *service_list = g_list_append(*service_list, (gpointer)service); - - return 0; -} - -static void __esd_cion_remove_cion_service_by_appid(const char *appid) -{ - GList *item; - GList *next; - struct cion_service *service; - - item = service_list; - while (item != NULL) { - next = item->next; - service = (struct cion_service *)item->data; - if (strcmp(service->appid, appid) == 0) { - _D("Remove a cion service [%s:%s:%s:%d]", - service->appid, service->service_name, - service->uuid, service->port); - __free_cion_service(service); - service_list = g_list_delete_link(service_list, item); - } - item = next; - } -} - -static void __esd_cion_remove_cion_service_by_pkgid(const char *pkgid) -{ - GList *item; - GList *next; - struct cion_service *service; - - item = service_list; - while (item != NULL) { - next = item->next; - service = (struct cion_service *)item->data; - if (strcmp(service->pkgid, pkgid) == 0) { - _D("Remove a cion service [%s:%s:%s:%d]", - service->appid, service->service_name, - service->uuid, service->port); - __free_cion_service(service); - service_list = g_list_delete_link(service_list, item); - } - item = next; - } -} - -static int __esd_cion_add_cion_service(struct cion_service *service, - const char *pkgid, const char *appid) -{ - /* service name already set by __esd_cion_foreach_metadata_callback() */ - service->pkgid = strdup(pkgid); - if (service->pkgid == NULL) { - _E("Out of memory"); - return -1; - } - - service->appid = strdup(appid); - if (service->appid == NULL) { - _E("Out of memory"); - return -1; - } - - /* how to get uuid? */ - - service_list = g_list_append(service_list, service); - _D("Add a cion service [%s:%s:%s:%d]", service->appid, - service->service_name, service->uuid, - service->port); - - return 0; -} - -static int __esd_cion_foreach_app_callback(const pkgmgrinfo_appinfo_h appinfo, - void *user_data) -{ - int ret; - char *pkgid; - char *appid; - struct cion_service *service; - GList *item; - GList *list = NULL; - - ret = pkgmgrinfo_appinfo_foreach_metadata(appinfo, - __esd_cion_foreach_metadata_callback, &list); - if (ret != PMINFO_R_OK) { - _E("Failed to get metadata: %d", ret); - return -1; - } - - ret = pkgmgrinfo_appinfo_get_pkgid(appinfo, &pkgid); - if (ret != PMINFO_R_OK) { - _E("Failed to get pkgid: %d", ret); - return -1; - } - - ret = pkgmgrinfo_appinfo_get_appid(appinfo, &appid); - if (ret != PMINFO_R_OK) { - _E("Failed to get appid: %d", ret); - return -1; - } - - /* remove first, the updated app may no longer provide cion service */ - __esd_cion_remove_cion_service_by_appid(appid); - for (item = list; item; item = item->next) { - service = (struct cion_service *)item->data; - if (__esd_cion_add_cion_service(service, pkgid, appid)) { - _E("Failed to add a cion service"); - __free_cion_service(service); - } - /* remove reference, the global 'service_list' takes reference - * of 'service'. - */ - item->data = NULL; - } - - g_list_free(list); - - return 0; -} - -static int __esd_cion_pkgmgr_event_callback(uid_t target_uid, int req_id, - const char *pkg_type, const char *pkgid, const char *key, - const char *val, const void *pmsg, void *data) -{ - int ret; - pkgmgrinfo_pkginfo_h pkginfo; - - if (strncmp(key, "end", strlen("end")) || - strncmp(val, "ok", strlen("ok"))) - return 0; - - ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &pkginfo); - if (ret == PMINFO_R_OK) { - /* install or update */ - ret = pkgmgrinfo_appinfo_get_usr_list(pkginfo, PMINFO_ALL_APP, - __esd_cion_foreach_app_callback, NULL, - target_uid); - if (ret != PMINFO_R_OK) { - _E("Failed to get appinfo of pkgid %s: %d", pkgid, ret); - pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); - return 0; - } - pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); - } else if (ret == PMINFO_R_ENOENT) { - /* uninstall */ - __esd_cion_remove_cion_service_by_pkgid(pkgid); - } else { - _E("Failed to get pkginfo of %s: %d", pkgid, ret); - } - - return 0; -} - -static int __esd_cion_set_pkgmgr_callback(void) -{ - int ret; - - pkgmgr = pkgmgr_client_new(PC_LISTENING); - if (pkgmgr == NULL) { - _E("Failed to create pkgmgr client"); - return -1; - } - - ret = pkgmgr_client_set_status_type(pkgmgr, - PKGMGR_CLIENT_STATUS_INSTALL | - PKGMGR_CLIENT_STATUS_UPGRADE | - PKGMGR_CLIENT_STATUS_UNINSTALL); - if (ret != PKGMGR_R_OK) { - _E("Failed to set pkgmgr event status type: %d", ret); - pkgmgr_client_free(pkgmgr); - pkgmgr = NULL; - return -1; - } - - ret = pkgmgr_client_listen_status(pkgmgr, - __esd_cion_pkgmgr_event_callback, NULL); - if (ret < 0) { - _E("Failed to set event callback: %d", ret); - pkgmgr_client_free(pkgmgr); - pkgmgr = NULL; - return -1; - } - - return 0; -} - -static int __esd_cion_load_services(uid_t uid) -{ - int ret; - pkgmgrinfo_appinfo_metadata_filter_h filter; - - ret = pkgmgrinfo_appinfo_metadata_filter_create(&filter); - if (ret != PMINFO_R_OK) { - _E("Failed to create metadata filter: %d", ret); - return -1; - } - - ret = pkgmgrinfo_appinfo_metadata_filter_add(filter, - CION_METADATA_KEY, ""); - if (ret != PMINFO_R_OK) { - _E("Failed to add keyval to metadata filter: %d", ret); - pkgmgrinfo_appinfo_metadata_filter_destroy(filter); - return -1; - } - - ret = pkgmgrinfo_appinfo_usr_metadata_filter_foreach(filter, - __esd_cion_foreach_app_callback, NULL, uid); - if (ret != PMINFO_R_OK) { - _E("Failed to metadata filter foreach: %d", ret); - pkgmgrinfo_appinfo_metadata_filter_destroy(filter); - return -1; - } - - pkgmgrinfo_appinfo_metadata_filter_destroy(filter); - - return 0; -} - -int __esd_cion_init(void) -{ - if (__esd_cion_set_cur_uid()) { - _E("Failed to set current uid"); - return -1; - } - - /* how to handle when user switched? */ - if (__esd_cion_load_services(cur_uid)) { - _E("Failed to load cion services"); - return -1; - } - - if (__esd_cion_set_pkgmgr_callback()) { - _E("Failed to set pkgmgr event callback"); - return -1; - } - - return 0; -} - -void __esd_cion_finalize(void) -{ - if (pkgmgr) { - pkgmgr_client_remove_listen_status(pkgmgr); - pkgmgr_client_free(pkgmgr); - } - - g_list_free_full(service_list, __free_cion_service); -} diff --git a/src/esd_cion/esd_cion.cc b/src/esd_cion/esd_cion.cc new file mode 100644 index 0000000..8ee6485 --- /dev/null +++ b/src/esd_cion/esd_cion.cc @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "eventsystem_daemon.h" +#include "cion_ondemand_server.h" + +namespace { + std::shared_ptr esd_cion_server; +} // namespace + +int _esd_cion_init() { + + try { + esd_cion_server = + std::make_shared("__CION_INTERNAL_DAEMON__", ""); + } catch (const cion::Exception& e) { + _D("cion_init failed : %s", e.what()); + return -1; + } + + esd_cion_server->Listen(); + + _D("cion_init done"); + + return 0; +} + +void _esd_cion_adds_enabled_app(const char *service_name, const char *app_id, + const char *display_name) { + if (esd_cion_server == nullptr) { + _E("Call init function at first"); + return; + } + + esd_cion_server->AddOndemandServiceList(std::string(service_name), + std::string(app_id), std::string(display_name)); +} + +void _esd_cion_removes_enabled_app(const char *service_name, const char *app_id) { + if (esd_cion_server == nullptr) { + _E("Call init function at first"); + return; + } + + esd_cion_server->RemoveOndemandServiceList(std::string(service_name), + std::string(app_id)); +} \ No newline at end of file diff --git a/src/esd_cion/esd_cion_db.c b/src/esd_cion/esd_cion_db.c index 2cf7fd9..1a99dc0 100644 --- a/src/esd_cion/esd_cion_db.c +++ b/src/esd_cion/esd_cion_db.c @@ -341,7 +341,9 @@ int esd_cion_set_enabled(const char *appid, const char *service_name, int ret = -1; sqlite3 *db; char *query = NULL; + const char *display_name = NULL; sqlite3_stmt *stmt = NULL; + sqlite3_stmt *select_stmt = NULL; db = esd_cion_db_open(); if (!db) { @@ -359,13 +361,34 @@ int esd_cion_set_enabled(const char *appid, const char *service_name, if (ret != SQLITE_OK) goto out; + query = sqlite3_mprintf("SELECT display_name FROM cion_display_name " + "WHERE appid = %Q AND service_name = %Q", appid, service_name); + if (query == NULL) + goto out; + + ret = sqlite3_prepare_v2(db, query, strlen(query), &select_stmt, NULL); + if (ret != SQLITE_OK) + goto out; + ret = sqlite3_step(stmt); - if (ret == SQLITE_OK || ret == SQLITE_DONE) + if (ret != SQLITE_OK && ret != SQLITE_DONE) + goto out; + + ret = sqlite3_step(select_stmt); + if (ret == SQLITE_ROW) { ret = 0; + display_name = (const char*)sqlite3_column_text(select_stmt, 0); + } + + if (enabled) + _esd_cion_adds_enabled_app(service_name, appid, display_name); + else + _esd_cion_removes_enabled_app(service_name, appid); out: sqlite3_free(query); sqlite3_finalize(stmt); + sqlite3_finalize(select_stmt); esd_cion_db_close(&db); return ret; @@ -411,14 +434,12 @@ out: return ret; } -int esd_cion_get_enabled_service_list(const char *service_name, - const char *display_name, GList **list) +int esd_cion_get_enabled_service_list(GList **list) { int ret = -1; sqlite3 *db; char *query = NULL; sqlite3_stmt *stmt = NULL; - char *appid; db = esd_cion_db_open(); if (!db) { @@ -426,13 +447,8 @@ int esd_cion_get_enabled_service_list(const char *service_name, return -1; } - if (display_name) - query = sqlite3_mprintf("SELECT appid FROM cion_display_name " - "WHERE service_name = %Q AND display_name = %Q AND enabled = 1", - service_name, display_name); - else - query = sqlite3_mprintf("SELECT appid FROM cion_display_name " - "WHERE service_name = %Q AND enabled = 1", service_name); + query = sqlite3_mprintf("SELECT service_name, appid, display_name " + "FROM cion_display_name WHERE enabled = 1"); if (query == NULL) goto out; @@ -441,10 +457,17 @@ int esd_cion_get_enabled_service_list(const char *service_name, goto out; while(sqlite3_step(stmt) == SQLITE_ROW) { - appid = strdup((char*)sqlite3_column_text(stmt, 0)); - _E("get appid list : %s", appid); + cion_service_info_s *cion_info = malloc(sizeof(cion_service_info_s)); + cion_info->service_name = strdup((char*)sqlite3_column_text(stmt, 0)); + cion_info->appid = strdup((char*)sqlite3_column_text(stmt, 1)); + + char *display_name = (char*)sqlite3_column_text(stmt, 2); + if (display_name) + cion_info->display_name = strdup(display_name); + _D("get list : [%s:%s:%s]", + cion_info->service_name, cion_info->appid, cion_info->display_name); - *list = g_list_append(*list, appid); + *list = g_list_append(*list, cion_info); } out: diff --git a/src/esd_main.c b/src/esd_main.c index dabb5ce..69d5eb1 100644 --- a/src/esd_main.c +++ b/src/esd_main.c @@ -2619,7 +2619,7 @@ int main(int argc, char *argv[]) return ES_R_ERROR; } - if (__esd_cion_init() != 0) { + if (_esd_cion_init() != 0) { _E("ESD Cion Initialization failed!"); g_main_loop_unref(mainloop); return ES_R_ERROR; @@ -2639,7 +2639,6 @@ int main(int argc, char *argv[]) _E("shutdown"); - __esd_cion_finalize(); __esd_finalize(); g_main_loop_unref(mainloop); -- 2.7.4 From 4d2c55a47ee357a53cdac18b88ac302b5219bbaa Mon Sep 17 00:00:00 2001 From: Inkyun Kil Date: Mon, 23 Aug 2021 09:55:55 +0900 Subject: [PATCH 03/16] Release version 0.2.0 Changes: - Add esd-cion module - Add db for cion uuid - Add display name for cion db - Add Cion Server Change-Id: I504fdc148efca60abfe871be93795da5e06456ae Signed-off-by: Inkyun Kil --- packaging/esd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/esd.spec b/packaging/esd.spec index 4bcc907..4241d43 100644 --- a/packaging/esd.spec +++ b/packaging/esd.spec @@ -1,6 +1,6 @@ Name: esd Summary: Event system daemon -Version: 0.1.22 +Version: 0.2.0 Release: 1 Group: Application Framework/Service License: Apache-2.0 -- 2.7.4 From bf3ccc693938007cc8d4b651b42cc30599d2701d Mon Sep 17 00:00:00 2001 From: SukhyungKang Date: Thu, 26 Aug 2021 15:59:52 +0900 Subject: [PATCH 04/16] Fix static analysis issues - NO_CATCH - UNINIT.LOCAL_VAR.EX - MEMORY_LEAK.EX - BAD_SIZEOF - FORWARD_NULL - USE_AFTER_FREE Change-Id: Icc2afb3ca9ebb431b278dfbd7296d6ead1683a66 Signed-off-by: SukhyungKang Signed-off-by: jusung --- src/esd_cion/cion_ondemand_server.cc | 2 ++ src/esd_cion/esd_cion.cc | 3 +-- src/esd_cion/esd_cion_db.c | 29 ++++++++++++++--------------- src/esd_main.c | 10 +++------- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/src/esd_cion/cion_ondemand_server.cc b/src/esd_cion/cion_ondemand_server.cc index 0d5965e..2493ac3 100644 --- a/src/esd_cion/cion_ondemand_server.cc +++ b/src/esd_cion/cion_ondemand_server.cc @@ -322,6 +322,8 @@ void CionOndemandServer::AddOndemandServiceList(std::string service_name, std::make_shared(service_name, parcel.GetRaw().data(), parcel.GetRaw().size()); ondemand_peer_list_.emplace_back(pi); + free(uuid); + _D("[%s:%s] is added to list", appid.c_str(), service_name.c_str()); } diff --git a/src/esd_cion/esd_cion.cc b/src/esd_cion/esd_cion.cc index 8ee6485..a91b95c 100644 --- a/src/esd_cion/esd_cion.cc +++ b/src/esd_cion/esd_cion.cc @@ -28,13 +28,12 @@ int _esd_cion_init() { try { esd_cion_server = std::make_shared("__CION_INTERNAL_DAEMON__", ""); + esd_cion_server->Listen(); } catch (const cion::Exception& e) { _D("cion_init failed : %s", e.what()); return -1; } - esd_cion_server->Listen(); - _D("cion_init done"); return 0; diff --git a/src/esd_cion/esd_cion_db.c b/src/esd_cion/esd_cion_db.c index 1a99dc0..61b7b5b 100644 --- a/src/esd_cion/esd_cion_db.c +++ b/src/esd_cion/esd_cion_db.c @@ -160,7 +160,7 @@ static const char *__esd_cion_generate_uuid() { static int __esd_cion_get_uuid(sqlite3 *db, const char *appid, char **uuid) { int ret = -1; char *query; - sqlite3_stmt *stmt; + sqlite3_stmt *stmt = NULL; query = sqlite3_mprintf("SELECT uuid FROM cion_uuid " "WHERE appid = %Q", appid); @@ -187,7 +187,7 @@ out: static int __esd_cion_set_uuid(sqlite3 *db, const char *appid, const char *uuid) { int ret = -1; char *query; - sqlite3_stmt *stmt; + sqlite3_stmt *stmt = NULL; query = sqlite3_mprintf("INSERT INTO cion_uuid (appid, uuid) " "VALUES (%Q, %Q) ", appid, uuid); @@ -242,7 +242,7 @@ int esd_cion_set_display_name(const char *appid, const char *service_name, sqlite3 *db; char *query = NULL; sqlite3_stmt *stmt = NULL; - char *_uuid; + char *_uuid = NULL; db = esd_cion_db_open(); if (!db) { @@ -250,16 +250,11 @@ int esd_cion_set_display_name(const char *appid, const char *service_name, return -1; } - if (__esd_cion_get_uuid(db, appid, &_uuid) == 0) { - free(_uuid); - } else { + if (__esd_cion_get_uuid(db, appid, &_uuid) != 0) { _uuid = (char*)__esd_cion_generate_uuid(); ret = __esd_cion_set_uuid(db, appid, _uuid); - if (ret != 0) { - free(_uuid); + if (ret != 0) goto out; - } - _E("set uuid generate"); } query = sqlite3_mprintf("INSERT INTO cion_display_name " @@ -282,6 +277,7 @@ int esd_cion_set_display_name(const char *appid, const char *service_name, ret = 0; out: + free(_uuid); sqlite3_free(query); sqlite3_finalize(stmt); esd_cion_db_close(&db); @@ -341,7 +337,7 @@ int esd_cion_set_enabled(const char *appid, const char *service_name, int ret = -1; sqlite3 *db; char *query = NULL; - const char *display_name = NULL; + const char *display_name = ""; sqlite3_stmt *stmt = NULL; sqlite3_stmt *select_stmt = NULL; @@ -361,6 +357,11 @@ int esd_cion_set_enabled(const char *appid, const char *service_name, if (ret != SQLITE_OK) goto out; + ret = sqlite3_step(stmt); + if (ret != SQLITE_OK && ret != SQLITE_DONE) + goto out; + + sqlite3_free(query); query = sqlite3_mprintf("SELECT display_name FROM cion_display_name " "WHERE appid = %Q AND service_name = %Q", appid, service_name); if (query == NULL) @@ -370,10 +371,6 @@ int esd_cion_set_enabled(const char *appid, const char *service_name, if (ret != SQLITE_OK) goto out; - ret = sqlite3_step(stmt); - if (ret != SQLITE_OK && ret != SQLITE_DONE) - goto out; - ret = sqlite3_step(select_stmt); if (ret == SQLITE_ROW) { ret = 0; @@ -464,6 +461,8 @@ int esd_cion_get_enabled_service_list(GList **list) char *display_name = (char*)sqlite3_column_text(stmt, 2); if (display_name) cion_info->display_name = strdup(display_name); + else + cion_info->display_name = strdup(""); _D("get list : [%s:%s:%s]", cion_info->service_name, cion_info->appid, cion_info->display_name); diff --git a/src/esd_main.c b/src/esd_main.c index 69d5eb1..5a931ad 100644 --- a/src/esd_main.c +++ b/src/esd_main.c @@ -1310,7 +1310,7 @@ static int __esd_get_appid_by_pid(int pid, char *app_id, int buf_size) if (fd < 0) return ES_R_ERROR; - ret = read(fd, app_id, sizeof(app_id) - 1); + ret = read(fd, app_id, buf_size - 1); close(fd); if (ret <= 0) @@ -2066,10 +2066,8 @@ static void __esd_on_bus_acquired(GDBusConnection *connection, NULL, NULL); - if (boot_id == 0) { + if (boot_id == 0) _E("g_dbus_connection_signal_subscribe() is failed."); - g_object_unref(connection); - } user_boot_id = g_dbus_connection_signal_subscribe(connection, NULL, @@ -2082,10 +2080,8 @@ static void __esd_on_bus_acquired(GDBusConnection *connection, NULL, NULL); - if (user_boot_id == 0) { + if (user_boot_id == 0) _E("g_dbus_connection_signal_subscribe() is failed."); - g_object_unref(connection); - } } static void __esd_on_name_acquired(GDBusConnection *connection, -- 2.7.4 From 934432c9e778c89e560fd60553c6a3ebf6be619e Mon Sep 17 00:00:00 2001 From: SukhyungKang Date: Thu, 26 Aug 2021 17:27:28 +0900 Subject: [PATCH 05/16] Release version 0.2.1 Changes: - Fix static analysis issues Change-Id: Iccbcae5af0986bbf35cd5fac08efdeabcfc3ec5e Signed-off-by: SukhyungKang --- packaging/esd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/esd.spec b/packaging/esd.spec index 4241d43..65e4ac5 100644 --- a/packaging/esd.spec +++ b/packaging/esd.spec @@ -1,6 +1,6 @@ Name: esd Summary: Event system daemon -Version: 0.2.0 +Version: 0.2.1 Release: 1 Group: Application Framework/Service License: Apache-2.0 -- 2.7.4 From 407377e2d3c59f62a3ea6be8721238b73fc8f2de Mon Sep 17 00:00:00 2001 From: Inkyun Kil Date: Fri, 10 Sep 2021 11:56:30 +0900 Subject: [PATCH 06/16] Remove error code when failing cion init Change-Id: Id10dd5e1805f4cd00b0c07ab4825b525b4253eba Signed-off-by: Inkyun Kil --- src/esd_main.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/esd_main.c b/src/esd_main.c index 5a931ad..dee892c 100644 --- a/src/esd_main.c +++ b/src/esd_main.c @@ -2615,11 +2615,8 @@ int main(int argc, char *argv[]) return ES_R_ERROR; } - if (_esd_cion_init() != 0) { + if (_esd_cion_init() != 0) _E("ESD Cion Initialization failed!"); - g_main_loop_unref(mainloop); - return ES_R_ERROR; - } if (__esd_before_loop() < 0) { _E("ESD failed!"); -- 2.7.4 From e3d4303b1bb4a94cfad63f6eb17d87298253f9ab Mon Sep 17 00:00:00 2001 From: Inkyun Kil Date: Fri, 10 Sep 2021 15:25:19 +0900 Subject: [PATCH 07/16] Release version 0.2.2 changes: - Remove error code when failing cion init Change-Id: I010c11b0e3f01d330d5e7c338a38c49fe78569b6 Signed-off-by: Inkyun Kil --- packaging/esd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/esd.spec b/packaging/esd.spec index 65e4ac5..ca63ca6 100644 --- a/packaging/esd.spec +++ b/packaging/esd.spec @@ -1,6 +1,6 @@ Name: esd Summary: Event system daemon -Version: 0.2.1 +Version: 0.2.2 Release: 1 Group: Application Framework/Service License: Apache-2.0 -- 2.7.4 From b18552e143befba9d758dd570cff0eae96f02922 Mon Sep 17 00:00:00 2001 From: Inkyun Kil Date: Wed, 13 Oct 2021 18:55:04 +0900 Subject: [PATCH 08/16] Change cion listen status - If ondemand list is empty, there is no need to listen. Change-Id: I0d9869b835d90714151061a9b5d55e2195120afb Signed-off-by: Inkyun Kil --- src/esd_cion/esd_cion.cc | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/esd_cion/esd_cion.cc b/src/esd_cion/esd_cion.cc index a91b95c..e124d59 100644 --- a/src/esd_cion/esd_cion.cc +++ b/src/esd_cion/esd_cion.cc @@ -21,14 +21,35 @@ namespace { std::shared_ptr esd_cion_server; + bool is_listening = false; } // namespace -int _esd_cion_init() { +static void __change_listen_status_cion_server() { + try { + GList *list = nullptr; + int ret = esd_cion_get_enabled_service_list(&list); + if (ret != 0) { + _D("Get list error"); + } else if (list == nullptr && is_listening) { + esd_cion_server->Stop(); + is_listening = false; + _D("esd_cion_server stop listen"); + } else if (list != nullptr && !is_listening) { + esd_cion_server->Listen(); + is_listening = true; + _D("esd_cion_server start listen"); + } + } catch (const cion::Exception& e) { + _E("cion_init failed : %s", e.what()); + } + + return; +} +int _esd_cion_init() { try { esd_cion_server = std::make_shared("__CION_INTERNAL_DAEMON__", ""); - esd_cion_server->Listen(); } catch (const cion::Exception& e) { _D("cion_init failed : %s", e.what()); return -1; @@ -36,6 +57,8 @@ int _esd_cion_init() { _D("cion_init done"); + __change_listen_status_cion_server(); + return 0; } @@ -48,6 +71,9 @@ void _esd_cion_adds_enabled_app(const char *service_name, const char *app_id, esd_cion_server->AddOndemandServiceList(std::string(service_name), std::string(app_id), std::string(display_name)); + + if (!is_listening) + __change_listen_status_cion_server(); } void _esd_cion_removes_enabled_app(const char *service_name, const char *app_id) { @@ -58,4 +84,7 @@ void _esd_cion_removes_enabled_app(const char *service_name, const char *app_id) esd_cion_server->RemoveOndemandServiceList(std::string(service_name), std::string(app_id)); + + if (is_listening) + __change_listen_status_cion_server(); } \ No newline at end of file -- 2.7.4 From c6398d3f2d76303c89417dd2ebbfd28931895bf8 Mon Sep 17 00:00:00 2001 From: Inkyun Kil Date: Thu, 4 Nov 2021 09:18:08 +0900 Subject: [PATCH 09/16] Release version 0.2.3 changes: - Change cion listen status Change-Id: Ie2a9444b17fd176b294ad5d983c62e62122df11f Signed-off-by: Inkyun Kil --- packaging/esd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/esd.spec b/packaging/esd.spec index ca63ca6..317a3f2 100644 --- a/packaging/esd.spec +++ b/packaging/esd.spec @@ -1,6 +1,6 @@ Name: esd Summary: Event system daemon -Version: 0.2.2 +Version: 0.2.3 Release: 1 Group: Application Framework/Service License: Apache-2.0 -- 2.7.4 From 1c82ddc6db3d7136f1b446eacc9542f0e16cc70f Mon Sep 17 00:00:00 2001 From: jusung Date: Thu, 11 Nov 2021 09:12:27 +0900 Subject: [PATCH 10/16] Rewire extern "C" blocks This is needed in order not to #include "glib.h" in the extern "C" blocks, which breaks in the newest GLib version. Change-Id: Ie94aedff5bbbdb5f85b0abbb167d5e7d5498ea0c Signed-off-by: jusung --- include/eventsystem_daemon.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/eventsystem_daemon.h b/include/eventsystem_daemon.h index 706a89b..f6f853d 100644 --- a/include/eventsystem_daemon.h +++ b/include/eventsystem_daemon.h @@ -21,13 +21,13 @@ * header file for eventsystem_daemon */ +#include +#include + #ifdef __cplusplus extern "C" { #endif -#include -#include - #undef LOG_TAG #define LOG_TAG "ESD" -- 2.7.4 From 919f482b4e45d594700cfe951bda0c7bd11e09dc Mon Sep 17 00:00:00 2001 From: jusung Date: Thu, 11 Nov 2021 09:15:34 +0900 Subject: [PATCH 11/16] Release version 0.2.4 Changes: - Rewire extern "C" blocks Change-Id: I3984f8f2a1d41454035596d2fa6eafde95589d07 Signed-off-by: jusung --- packaging/esd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/esd.spec b/packaging/esd.spec index 317a3f2..35a6100 100644 --- a/packaging/esd.spec +++ b/packaging/esd.spec @@ -1,6 +1,6 @@ Name: esd Summary: Event system daemon -Version: 0.2.3 +Version: 0.2.4 Release: 1 Group: Application Framework/Service License: Apache-2.0 -- 2.7.4 From 31feec915d92a3b142144eb1dd05e69ed04dcf01 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 26 Sep 2022 02:35:54 +0000 Subject: [PATCH 12/16] Use modified tizen_base::Parcel To improve the performance of the parcel creation, the implementation of the Parcel is changed. It uses malloc() instead of std::vector. Requires: - https://review.tizen.org/gerrit/#/c/platform/core/base/bundle/+/281779/ Change-Id: Iba427db6a0e5624fdb6cc5a0b0290cc4960d3fa0 Signed-off-by: Hwankyu Jhun --- src/esd_cion/cion_ondemand_server.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/esd_cion/cion_ondemand_server.cc b/src/esd_cion/cion_ondemand_server.cc index 2493ac3..13f9923 100644 --- a/src/esd_cion/cion_ondemand_server.cc +++ b/src/esd_cion/cion_ondemand_server.cc @@ -171,7 +171,7 @@ void CionOndemandServer::OnOndemandListRequested( std::string list_service_name = ondemand_parcel.ReadString(); _D("Ondemand Service_name : %s", list_service_name.c_str()); if (list_header == std::string("OndemandList")) { - raw = GetOndemandList(list_service_name).GetRaw(); + raw = GetOndemandList(list_service_name).ToRaw(); if (raw.size() == 0) return; } @@ -278,7 +278,7 @@ void CionOndemandServer::LoadOndemandServiceList() { std::shared_ptr pi = std::make_shared(std::string(service_name), - parcel.GetRaw().data(), parcel.GetRaw().size()); + parcel.GetData(), parcel.GetDataSize()); ondemand_peer_list_.emplace_back(pi); free(uuid); @@ -319,8 +319,8 @@ void CionOndemandServer::AddOndemandServiceList(std::string service_name, parcel.WriteString(display_name); std::shared_ptr pi = - std::make_shared(service_name, parcel.GetRaw().data(), - parcel.GetRaw().size()); + std::make_shared(service_name, parcel.GetData(), + parcel.GetDataSize()); ondemand_peer_list_.emplace_back(pi); free(uuid); @@ -365,4 +365,4 @@ tizen_base::Parcel CionOndemandServer::GetOndemandList( parcel.WriteBool(false); return parcel; -} \ No newline at end of file +} -- 2.7.4 From 142004a960943efa2dd32159543d187ba3f1c860 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 27 Sep 2022 06:03:42 +0000 Subject: [PATCH 13/16] Fix static anlaysis issues The following issues are fixed: - NULL_RETURNS - AUTO_CAUSES_COPY Change-Id: Id7244305e0762f6b532dff6ea792a68740e49872 Signed-off-by: Hwankyu Jhun --- src/esd_cion/cion_ondemand_server.cc | 4 +- src/esd_cion/cion_ondemand_server.h | 2 +- src/esd_cion/esd_cion_db.c | 86 +++++++++++++++++++++++++++++++----- 3 files changed, 78 insertions(+), 14 deletions(-) diff --git a/src/esd_cion/cion_ondemand_server.cc b/src/esd_cion/cion_ondemand_server.cc index 13f9923..a7c267b 100644 --- a/src/esd_cion/cion_ondemand_server.cc +++ b/src/esd_cion/cion_ondemand_server.cc @@ -290,7 +290,7 @@ void CionOndemandServer::LoadOndemandServiceList() { void CionOndemandServer::AddOndemandServiceList(std::string service_name, std::string appid, std::string display_name) { - for (auto peer : ondemand_peer_list_) { + for (auto const& peer : ondemand_peer_list_) { if (peer->GetServiceName() == service_name && peer->GetAppID() == appid) { _W("%s is already exist", appid.c_str()); @@ -330,7 +330,7 @@ void CionOndemandServer::AddOndemandServiceList(std::string service_name, void CionOndemandServer::RemoveOndemandServiceList(std::string service_name, std::string appid) { for (auto peer = ondemand_peer_list_.begin(); - peer != ondemand_peer_list_.end(); peer++) { + peer != ondemand_peer_list_.end(); peer++) { if (peer->get()->GetServiceName() == service_name && peer->get()->GetAppID() == appid) { ondemand_peer_list_.erase(peer); diff --git a/src/esd_cion/cion_ondemand_server.h b/src/esd_cion/cion_ondemand_server.h index b3852d0..3f7ed16 100644 --- a/src/esd_cion/cion_ondemand_server.h +++ b/src/esd_cion/cion_ondemand_server.h @@ -59,4 +59,4 @@ class CionOndemandServer : public cion::channel::ServerChannel { std::list> ondemand_peer_list_; }; -#endif /* EVENTSYSTEM_DAEMON_CION_ONDEMAND_SERVER_H_ */ \ No newline at end of file +#endif /* EVENTSYSTEM_DAEMON_CION_ONDEMAND_SERVER_H_ */ diff --git a/src/esd_cion/esd_cion_db.c b/src/esd_cion/esd_cion_db.c index 61b7b5b..f6689f4 100644 --- a/src/esd_cion/esd_cion_db.c +++ b/src/esd_cion/esd_cion_db.c @@ -431,12 +431,79 @@ out: return ret; } +static void __cion_service_info_destroy(cion_service_info_s *info) +{ + if (info == NULL) + return; + + free(info->service_name); + free(info->appid); + free(info->display_name); + free(info); +} + +static cion_service_info_s *__cion_service_info_create(sqlite3_stmt *stmt) +{ + cion_service_info_s *info; + const char* value; + int index = 0; + + info = calloc(1, sizeof(cion_service_info_s)); + if (info == NULL) { + _E("malloc() is failed"); + return NULL; + } + + value = (const char *)sqlite3_column_text(stmt, index++); + if (value == NULL) { + _E("sqlite3_column_text() is failed. index: %d", index - 1); + __cion_service_info_destroy(info); + return NULL; + } + + info->service_name = strdup(value); + if (info->service_name == NULL) { + _E("strdup() is failed"); + __cion_service_info_destroy(info); + return NULL; + } + + value = (const char *)sqlite3_column_text(stmt, index++); + if (value == NULL) { + _E("sqlite3_column_text() is failed. index: %d", index - 1); + __cion_service_info_destroy(info); + return NULL; + } + + info->appid = strdup(value); + if (info->appid == NULL) { + _E("strdup() is failed"); + __cion_service_info_destroy(info); + return NULL; + } + + value = (const char *)sqlite3_column_text(stmt, index++); + if (value != NULL) + info->display_name = strdup(value); + else + info->display_name = strdup(""); + + if (info->display_name == NULL) { + _E("strdup() is failed"); + __cion_service_info_destroy(info); + return NULL; + } + + return info; +} + int esd_cion_get_enabled_service_list(GList **list) { int ret = -1; sqlite3 *db; char *query = NULL; sqlite3_stmt *stmt = NULL; + cion_service_info_s *cion_info; db = esd_cion_db_open(); if (!db) { @@ -453,19 +520,16 @@ int esd_cion_get_enabled_service_list(GList **list) if (ret != SQLITE_OK) goto out; - while(sqlite3_step(stmt) == SQLITE_ROW) { - cion_service_info_s *cion_info = malloc(sizeof(cion_service_info_s)); - cion_info->service_name = strdup((char*)sqlite3_column_text(stmt, 0)); - cion_info->appid = strdup((char*)sqlite3_column_text(stmt, 1)); + while (sqlite3_step(stmt) == SQLITE_ROW) { + cion_info = __cion_service_info_create(stmt); + if (cion_info == NULL) { + ret = -1; + goto out; + } - char *display_name = (char*)sqlite3_column_text(stmt, 2); - if (display_name) - cion_info->display_name = strdup(display_name); - else - cion_info->display_name = strdup(""); _D("get list : [%s:%s:%s]", - cion_info->service_name, cion_info->appid, cion_info->display_name); - + cion_info->service_name, cion_info->appid, + cion_info->display_name); *list = g_list_append(*list, cion_info); } -- 2.7.4 From 7b2f4e851464d61db17c464e5614b9953defbd9f Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 27 Sep 2022 06:56:40 +0000 Subject: [PATCH 14/16] Release version 0.2.5 Changes: - Use modified tizen_base::Parcel - Fix static anlaysis issues Change-Id: Idab9d19241a0888eff6329862380e17219fc3d51 Signed-off-by: Hwankyu Jhun --- packaging/esd.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/esd.spec b/packaging/esd.spec index 35a6100..e419837 100644 --- a/packaging/esd.spec +++ b/packaging/esd.spec @@ -1,6 +1,6 @@ Name: esd Summary: Event system daemon -Version: 0.2.4 +Version: 0.2.5 Release: 1 Group: Application Framework/Service License: Apache-2.0 -- 2.7.4 From da607e631e5059d1840b34fcfc4804bab2d772f1 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 28 Sep 2022 03:59:22 +0000 Subject: [PATCH 15/16] Fix static analysis issue The following issue is fixed: - AUTO_CAUSES_COPY Change-Id: I76704d5c779e67819d9378329b8c3cdc4320fb5e Signed-off-by: Hwankyu Jhun --- src/esd_cion/cion_ondemand_server.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/esd_cion/cion_ondemand_server.cc b/src/esd_cion/cion_ondemand_server.cc index a7c267b..0301b0f 100644 --- a/src/esd_cion/cion_ondemand_server.cc +++ b/src/esd_cion/cion_ondemand_server.cc @@ -351,7 +351,7 @@ tizen_base::Parcel CionOndemandServer::GetOndemandList( tizen_base::Parcel parcel; parcel.WriteString(header); - for (auto peer : ondemand_peer_list_) { + for (auto& peer : ondemand_peer_list_) { if (peer->GetServiceName() != service_name || aul_app_is_running(peer->GetAppID().c_str())) continue; -- 2.7.4 From e1f2f3e9c5a6ed3565ffa9c364732f42b1ba615f Mon Sep 17 00:00:00 2001 From: "jh9216.park" Date: Tue, 15 Nov 2022 01:33:14 -0500 Subject: [PATCH 16/16] Refactor esd - Apply plugin style - Use tizen_base::Database - Rewrite legacy code to C++ Change-Id: If90ad1a11aed462afaddc330501e85a06e1f6471 Signed-off-by: jh9216.park --- AUTHORS | 2 +- CMakeLists.txt | 111 +- cmake/Modules/ApplyPkgConfig.cmake | 35 + include/eventsystem_daemon.h | 83 - esd.manifest.in => packaging/esd.manifest | 0 packaging/esd.spec | 44 +- src/CMakeLists.txt | 3 + src/esd/CMakeLists.txt | 20 + src/esd/main.cc | 28 + src/esd/module_runner.cc | 109 + src/esd/module_runner.hh | 54 + .../esd/tizen.system.event.app2esd.service.in | 0 src/esd_cion/esd_cion.cc | 90 - src/esd_cion/esd_cion_db.c | 542 ---- src/esd_main.c | 2640 -------------------- src/esd_system_event.c | 576 ----- src/lib/CMakeLists.txt | 34 + src/lib/imodule.hh | 33 + src/lib/log.hh | 30 + src/lib/method_broker.hh | 79 + src/lib/pkgconfig/libesd.pc.in | 13 + src/lib/tool_box.cc | 25 + src/lib/tool_box.hh | 40 + src/modules/CMakeLists.txt | 2 + src/modules/cion/CMakeLists.txt | 27 + src/modules/cion/cion.cc | 25 + src/modules/cion/cion_module.cc | 428 ++++ src/modules/cion/cion_module.hh | 73 + .../cion}/cion_ondemand_server.cc | 101 +- .../cion}/cion_ondemand_server.h | 4 +- src/{esd_cion => modules/cion}/cion_peer_info.cc | 0 src/{esd_cion => modules/cion}/cion_peer_info.h | 0 src/modules/cion/cion_service_info.hh | 49 + src/modules/cion/database.hpp | 449 ++++ src/modules/dbus_event/CMakeLists.txt | 30 + src/modules/dbus_event/dbus_event.cc | 25 + src/modules/dbus_event/dbus_event_module.cc | 2464 ++++++++++++++++++ src/modules/dbus_event/dbus_event_module.hh | 93 + src/modules/dbus_event/esd_system_event.cc | 561 +++++ .../modules/dbus_event/eventsystem.conf | 0 src/modules/dbus_event/introspection_cb.hh | 111 + 41 files changed, 4972 insertions(+), 4061 deletions(-) create mode 100644 cmake/Modules/ApplyPkgConfig.cmake delete mode 100644 include/eventsystem_daemon.h rename esd.manifest.in => packaging/esd.manifest (100%) create mode 100644 src/CMakeLists.txt create mode 100644 src/esd/CMakeLists.txt create mode 100644 src/esd/main.cc create mode 100644 src/esd/module_runner.cc create mode 100644 src/esd/module_runner.hh rename tizen.system.event.app2esd.service.in => src/esd/tizen.system.event.app2esd.service.in (100%) delete mode 100644 src/esd_cion/esd_cion.cc delete mode 100644 src/esd_cion/esd_cion_db.c delete mode 100644 src/esd_main.c delete mode 100644 src/esd_system_event.c create mode 100644 src/lib/CMakeLists.txt create mode 100644 src/lib/imodule.hh create mode 100644 src/lib/log.hh create mode 100644 src/lib/method_broker.hh create mode 100644 src/lib/pkgconfig/libesd.pc.in create mode 100644 src/lib/tool_box.cc create mode 100644 src/lib/tool_box.hh create mode 100644 src/modules/CMakeLists.txt create mode 100644 src/modules/cion/CMakeLists.txt create mode 100644 src/modules/cion/cion.cc create mode 100644 src/modules/cion/cion_module.cc create mode 100644 src/modules/cion/cion_module.hh rename src/{esd_cion => modules/cion}/cion_ondemand_server.cc (81%) rename src/{esd_cion => modules/cion}/cion_ondemand_server.h (95%) rename src/{esd_cion => modules/cion}/cion_peer_info.cc (100%) rename src/{esd_cion => modules/cion}/cion_peer_info.h (100%) create mode 100644 src/modules/cion/cion_service_info.hh create mode 100644 src/modules/cion/database.hpp create mode 100644 src/modules/dbus_event/CMakeLists.txt create mode 100644 src/modules/dbus_event/dbus_event.cc create mode 100644 src/modules/dbus_event/dbus_event_module.cc create mode 100644 src/modules/dbus_event/dbus_event_module.hh create mode 100644 src/modules/dbus_event/esd_system_event.cc rename eventsystem.conf => src/modules/dbus_event/eventsystem.conf (100%) create mode 100644 src/modules/dbus_event/introspection_cb.hh diff --git a/AUTHORS b/AUTHORS index cf4d288..6fcd6fa 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1,2 @@ -Jongmyeong Ko +Junghoon Park Jusung Son diff --git a/CMakeLists.txt b/CMakeLists.txt index d207d7c..60b5383 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,72 +1,55 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +PROJECT(esd) -PROJECT(esd C CXX) -AUX_SOURCE_DIRECTORY(src/ SRCS) -AUX_SOURCE_DIRECTORY(src/esd_cion/ CION_SRCS) +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-zdefs") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") -SET(VERSION 0.0.1) -SET(VERSION_MAJOR 0) +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_C_FLAGS} -std=c++17") +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_CXX_FLAGS_RELEASE "-O2") -SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(EXEC_PREFIX "\${prefix}") -SET(LIBDIR "\${prefix}/lib") -SET(INCLUDEDIR "\${prefix}/include") - -set(CMAKE_SKIP_BUILD_RPATH true) - -### Local include directories -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/src) - -### Required packages -INCLUDE(FindPkgConfig) - -pkg_check_modules(pkgs REQUIRED - dlog - bundle - parcel - pkgmgr-info - glib-2.0 - gio-2.0 - appsvc - aul - vconf - libtzplatform-config - cert-svc-vcore - cynara-client - cynara-creds-gdbus - cynara-session - security-manager - sqlite3 - uuid - cion - capi-system-info -) - -FOREACH(flag ${pkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -ENDFOREACH(flag) +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") -#FIND_LIBRARY(LIB_DL dl) +## Target esd +SET(TARGET_ESD "esd") +SET(TARGET_LIB_ESD "libesd") -## Additional flag -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -Wall -Werror") -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -std=c++14 -Werror") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +## Target modules +SET(TARGET_ESD_MOD_CION "esd-mod-cion") +SET(TARGET_ESD_MOD_DBUS_EVENT "esd-mod-dbus-event") -## Linker flags -SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") +#ENABLE_TESTING() +#SET(TARGET_ESD_UNIT_TESTS "esd-unit-tests") -##build eventsystem daemon -add_executable(esd ${SRCS} ${CION_SRCS}) -TARGET_LINK_LIBRARIES(esd eventsystem pkgmgr-client ${pkgs_LDFLAGS}) -SET_TARGET_PROPERTIES(esd PROPERTIES COMPILE_FLAGS ${CFLAGS} ${CXXFLAGS} "-fPIE") -SET_TARGET_PROPERTIES(esd PROPERTIES LINK_FLAGS "-pie -Wl,-z,relro") +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/") -# pkgconfig file -configure_file(esd.manifest.in esd.manifest @ONLY) -configure_file(tizen.system.event.app2esd.service.in tizen.system.event.app2esd.service @ONLY) - -INSTALL(TARGETS esd DESTINATION bin) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/eventsystem.conf DESTINATION /etc/dbus-1/system.d) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/tizen.system.event.app2esd.service DESTINATION ${SHARE_INSTALL_PREFIX}/dbus-1/system-services/) +INCLUDE(FindPkgConfig) +INCLUDE(ApplyPkgConfig) + +PKG_CHECK_MODULES(AUL_DEPS REQUIRED aul) +PKG_CHECK_MODULES(BUNDLE_DEPS REQUIRED bundle) +PKG_CHECK_MODULES(CAPI_SYSTEM_INFO_DEPS REQUIRED capi-system-info) +PKG_CHECK_MODULES(CERT_SVC_VCORE_DEPS REQUIRED cert-svc-vcore) +PKG_CHECK_MODULES(CYNARA_CLIENT_DEPS REQUIRED cynara-client) +PKG_CHECK_MODULES(CYNARA_CREDS_DBUS_DEPS REQUIRED cynara-creds-gdbus) +PKG_CHECK_MODULES(CYNARA_SESSION_DEPS REQUIRED cynara-session) +PKG_CHECK_MODULES(DLOG_DEPS REQUIRED dlog) +PKG_CHECK_MODULES(GIO_DEPS REQUIRED gio-2.0) +PKG_CHECK_MODULES(GLIB_DEPS REQUIRED glib-2.0) +PKG_CHECK_MODULES(LIBTZPLATFORM_CONFIG_DEPS REQUIRED libtzplatform-config) +PKG_CHECK_MODULES(PARCEL_DEPS REQUIRED parcel) +PKG_CHECK_MODULES(PKGMGR_INFO_DEPS REQUIRED pkgmgr-info) +PKG_CHECK_MODULES(SECURITY_MANAGER_DEPS REQUIRED security-manager) +PKG_CHECK_MODULES(SQLITE3_DEPS REQUIRED sqlite3) +PKG_CHECK_MODULES(CION_DEPS REQUIRED cion) +PKG_CHECK_MODULES(UUID_DEPS REQUIRED uuid) +PKG_CHECK_MODULES(VCONF_DEPS REQUIRED vconf) +PKG_CHECK_MODULES(PKGMGR_DEPS REQUIRED pkgmgr) +PKG_CHECK_MODULES(EVENTSYSTEM_DEPS REQUIRED eventsystem) + +ADD_SUBDIRECTORY(src) diff --git a/cmake/Modules/ApplyPkgConfig.cmake b/cmake/Modules/ApplyPkgConfig.cmake new file mode 100644 index 0000000..9b84be3 --- /dev/null +++ b/cmake/Modules/ApplyPkgConfig.cmake @@ -0,0 +1,35 @@ +# Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# +# This function applies external (out of source tree) dependencies +# to given target. Arguments are: +# TARGET - valid cmake target +# PRIVACY - dependency can be inherited by dependent targets or not: +# PUBLIC - this should be used by default, cause compile/link flags passing +# PRIVATE - do not passes any settings to dependent targets, +# may be usefull for static libraries from the inside of the project +# Argument ARGV2 and following are supposed to be names of checked pkg config +# packages. This function will use variables created by check_pkg_modules(). +# - ${DEP_NAME}_LIBRARIES +# - ${DEP_NAME}_INCLUDE_DIRS +# - ${DEP_NAME}_CFLAGS +# +FUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY) + MATH(EXPR DEST_INDEX "${ARGC}-1") + FOREACH(I RANGE 2 ${DEST_INDEX}) + IF(NOT ${ARGV${I}}_FOUND) + MESSAGE(FATAL_ERROR "Not found dependency - ${ARGV${I}}_FOUND") + ENDIF(NOT ${ARGV${I}}_FOUND) + TARGET_LINK_LIBRARIES(${TARGET} ${PRIVACY} "${${ARGV${I}}_LIBRARIES}") + TARGET_INCLUDE_DIRECTORIES(${TARGET} ${PRIVACY} SYSTEM "${${ARGV${I}}_INCLUDE_DIRS}") + STRING(REPLACE ";" " " CFLAGS_STR "${${ARGV${I}}_CFLAGS}") + SET(CFLAGS_LIST ${CFLAGS_STR}) + SEPARATE_ARGUMENTS(CFLAGS_LIST) + FOREACH(OPTION ${CFLAGS_LIST}) + TARGET_COMPILE_OPTIONS(${TARGET} ${PRIVACY} ${OPTION}) + ENDFOREACH(OPTION) + SET_TARGET_PROPERTIES(${TARGET} PROPERTIES SKIP_BUILD_RPATH true) + ENDFOREACH(I RANGE 2 ${DEST_INDEX}) +ENDFUNCTION(APPLY_PKG_CONFIG TARGET PRIVACY) diff --git a/include/eventsystem_daemon.h b/include/eventsystem_daemon.h deleted file mode 100644 index f6f853d..0000000 --- a/include/eventsystem_daemon.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __EVENTSYSTEM_DAEMON_H__ -#define __EVENTSYSTEM_DAEMON_H__ - -/** - * header file for eventsystem_daemon - */ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#undef LOG_TAG -#define LOG_TAG "ESD" - -#define _E(fmt, arg...) LOGE(fmt, ##arg) -#define _D(fmt, arg...) LOGD(fmt, ##arg) -#define _W(fmt, arg...) LOGW(fmt, ##arg) -#define _I(fmt, arg...) LOGI(fmt, ##arg) - -#define FREE_AND_NULL(ptr) do { \ - if (ptr) { \ - free((void *)ptr); \ - ptr = NULL; \ - } \ -} while (0) - -#define ESD_BOOT_COMPLETED "/tmp/esd_ready" - -#define SYSTEMD_DBUS_DEST "org.freedesktop.systemd1" -#define SYSTEMD_DBUS_IFACE_MANAGER SYSTEMD_DBUS_DEST ".Manager" -#define SYSTEMD_DBUS_PATH "/org/freedesktop/systemd1" -#define SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED "StartupFinished" -#define SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED "UserSessionStartupFinished" - -typedef struct cion_service_info { - char *service_name; - char *appid; - char *display_name; -} cion_service_info_s; - -int __esd_register_vconf_callbacks(void); - -int _esd_cion_init(void); -void _esd_cion_adds_enabled_app(const char *service_name, const char *app_id, - const char *display_name); -void _esd_cion_removes_enabled_app(const char *service_name, const char *app_id); - -int esd_cion_db_init(void); -int esd_cion_get_uuid_with_generate(const char* appid, char** uuid); -int esd_cion_set_display_name(const char *appid, const char *service_name, - char *display_name); -int esd_cion_get_display_name(const char *appid, const char *service_name, - char **display_name); -int esd_cion_set_enabled(const char *appid, const char *service_name, - bool enabled); -int esd_cion_get_enabled(const char *appid, const char *service_name, - int *enabled); -int esd_cion_get_enabled_service_list(GList **list); - -#ifdef __cplusplus -} -#endif - -#endif /* __EVENTSYSTEM_DAEMONE_H__ */ diff --git a/esd.manifest.in b/packaging/esd.manifest similarity index 100% rename from esd.manifest.in rename to packaging/esd.manifest diff --git a/packaging/esd.spec b/packaging/esd.spec index e419837..cfbe03b 100644 --- a/packaging/esd.spec +++ b/packaging/esd.spec @@ -1,11 +1,12 @@ Name: esd Summary: Event system daemon -Version: 0.2.5 +Version: 1.0.0 Release: 1 Group: Application Framework/Service License: Apache-2.0 Source0: %{name}-%{version}.tar.gz Source1: esd.service +Source1001: %{name}.manifest BuildRequires: cmake BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(bundle) @@ -44,16 +45,38 @@ Requires: %{name} = %{version}-%{release} %description devel Event system Daemon (devel) +%package -n esd-mod-cion +Summary: ESD module for cion +Group: Application Framework/Service + +%description -n esd-mod-cion +This module is for cion + +%package -n esd-mod-dbus-event +Summary: ESD module for dbus-event +Group: Application Framework/Service + +%description -n esd-mod-dbus-event +This module is for event system using dbus + +%define _moddir %{_datadir}/esd + %prep %setup -q +cp %{SOURCE1001} . %build export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +%cmake \ + -DFULLVER=%{version} \ + -DMAJORVER=${MAJORVER} \ + -DESD_MODULES_DIR=%{_moddir} \ + . -%cmake . make %{?jobs:-j%jobs} %install @@ -69,14 +92,27 @@ ln -sf ../esd.service %{buildroot}%{_unitdir}/multi-user.target.wants/esd.servic %postun -p /sbin/ldconfig %files -%manifest esd.manifest +%manifest %{name}.manifest %config %{_sysconfdir}/dbus-1/system.d/eventsystem.conf %defattr(-,root,root,-) %{_bindir}/esd +%{_libdir}/libesd.so.* %{_unitdir}/esd.service %{_unitdir}/multi-user.target.wants/esd.service %attr(0644,root,root) %{_datadir}/dbus-1/system-services/tizen.system.event.app2esd.service %license LICENSE %files devel -%defattr(-,root,root,-) +%{_includedir}/esd/*.hh +%{_libdir}/libesd.so +%{_libdir}/pkgconfig/*pc + +%files -n esd-mod-cion +%manifest %{name}.manifest +%license LICENSE +%{_moddir}/mod/libesd-mod-cion.so + +%files -n esd-mod-dbus-event +%manifest %{name}.manifest +%license LICENSE +%{_moddir}/mod/libesd-mod-dbus-event.so diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..262c5f2 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,3 @@ +ADD_SUBDIRECTORY(esd) +ADD_SUBDIRECTORY(lib) +ADD_SUBDIRECTORY(modules) diff --git a/src/esd/CMakeLists.txt b/src/esd/CMakeLists.txt new file mode 100644 index 0000000..0bac57d --- /dev/null +++ b/src/esd/CMakeLists.txt @@ -0,0 +1,20 @@ +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} ESD_SRCS) + +ADD_EXECUTABLE(${TARGET_ESD} ${ESD_SRCS}) + +SET_TARGET_PROPERTIES(${TARGET_ESD} PROPERTIES COMPILE_FLAGS "-fPIE") +SET_TARGET_PROPERTIES(${TARGET_ESD} PROPERTIES LINK_FLAGS + "-pie -Wl,-z,relro") + +TARGET_LINK_LIBRARIES(${TARGET_ESD} PRIVATE ${TARGET_LIB_ESD} "-ldl") +TARGET_INCLUDE_DIRECTORIES(${TARGET_ESD} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../lib) + +APPLY_PKG_CONFIG(${TARGET_ESD} PUBLIC + DLOG_DEPS + GLIB_DEPS +) + +INSTALL(TARGETS ${TARGET_ESD} DESTINATION bin) +CONFIGURE_FILE(tizen.system.event.app2esd.service.in tizen.system.event.app2esd.service @ONLY) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/tizen.system.event.app2esd.service DESTINATION ${SHARE_INSTALL_PREFIX}/dbus-1/system-services/) diff --git a/src/esd/main.cc b/src/esd/main.cc new file mode 100644 index 0000000..a49d1b5 --- /dev/null +++ b/src/esd/main.cc @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "module_runner.hh" + +constexpr const char MODULE_PATH[] = "/usr/share/esd/mod/"; + +int main(int argc, char* argv[]) { + esd::ModuleRunner runner; + + if (runner.Run(MODULE_PATH)) + return 0; + + return -1; +} diff --git a/src/esd/module_runner.cc b/src/esd/module_runner.cc new file mode 100644 index 0000000..07be263 --- /dev/null +++ b/src/esd/module_runner.cc @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "module_runner.hh" + +#include +#include +#include +#include +#include +#include + +#include + +namespace esd { + +ModuleRunner::ModuleRunner() = default; + +bool ModuleRunner::Run(const std::string& module_path) { + GMainLoop* loop = g_main_loop_new(nullptr, FALSE); + if (loop == nullptr) { + _E("out of memory"); + return false; + } + + _I("ESD : Init modules"); + if (!InitModules(module_path)) { + g_main_loop_unref(loop); + return false; + } + + g_main_loop_run(loop); + _E("ESD : Shutdown"); + FiniModules(); + g_main_loop_unref(loop); + + return true; +} + +bool ModuleRunner::InitModules(const std::string& module_path) { + DIR* dp = opendir(module_path.c_str()); + if (dp == nullptr) + return false; + + dirent* dentry; + while ((dentry = readdir(dp)) != nullptr) { + if (dentry->d_name[0] == '.') + continue; + + char* extension = strrchr(dentry->d_name, '.'); + if (extension == nullptr || strcmp(extension, ".so") != 0) + continue; + + std::string path = module_path + "/" + + std::string(dentry->d_name); + + if (!InitModule(path)) { + closedir(dp); + return false; + } + } + + closedir(dp); + + return true; +} + +bool ModuleRunner::InitModule(const std::string& module_path) { + std::unique_ptr handle( + dlopen(module_path.c_str(), RTLD_LAZY | RTLD_GLOBAL)); + if (!handle) { + _E("dlopen() is failed. path(%s), error(%s)", module_path.c_str(), + dlerror()); + return false; + } + + using esd_mod_func = esd::api::IModule* (*)(); + auto* get_mod = reinterpret_cast( + dlsym(handle.get(), "ESD_GET_MODULE")); + if (get_mod == nullptr) { + _E("dlsym() is failed"); + return false; + } + + auto* mod = get_mod(); + modules_.push_back(std::unique_ptr(mod)); + libs_.push_back(std::move(handle)); + return mod->Startup(&tools_); +} + +void ModuleRunner::FiniModules() { + for (auto& mod : modules_) + mod->Shutdown(); +} + +} // namespace esd \ No newline at end of file diff --git a/src/esd/module_runner.hh b/src/esd/module_runner.hh new file mode 100644 index 0000000..7f9253f --- /dev/null +++ b/src/esd/module_runner.hh @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_ESD_HH_ +#define EVENTSYSTEM_ESD_HH_ + +#include +#include +#include +#include + +#include +#include + +namespace esd { + +class ModuleRunner { + public: + ModuleRunner(); + bool Run(const std::string& module_path); + + private: + bool InitModules(const std::string& module_path); + bool InitModule(const std::string& module_path); + void FiniModules(); + + private: + struct DlCloser { + void operator()(void* handle) const { + dlclose(handle); + } + }; + + api::ToolBox tools_; + std::list> libs_; + std::list> modules_; +}; + +} // namespace esd + +#endif // EVENTSYSTEM_ESD_HH_ \ No newline at end of file diff --git a/tizen.system.event.app2esd.service.in b/src/esd/tizen.system.event.app2esd.service.in similarity index 100% rename from tizen.system.event.app2esd.service.in rename to src/esd/tizen.system.event.app2esd.service.in diff --git a/src/esd_cion/esd_cion.cc b/src/esd_cion/esd_cion.cc deleted file mode 100644 index e124d59..0000000 --- a/src/esd_cion/esd_cion.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2021 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "eventsystem_daemon.h" -#include "cion_ondemand_server.h" - -namespace { - std::shared_ptr esd_cion_server; - bool is_listening = false; -} // namespace - -static void __change_listen_status_cion_server() { - try { - GList *list = nullptr; - int ret = esd_cion_get_enabled_service_list(&list); - if (ret != 0) { - _D("Get list error"); - } else if (list == nullptr && is_listening) { - esd_cion_server->Stop(); - is_listening = false; - _D("esd_cion_server stop listen"); - } else if (list != nullptr && !is_listening) { - esd_cion_server->Listen(); - is_listening = true; - _D("esd_cion_server start listen"); - } - } catch (const cion::Exception& e) { - _E("cion_init failed : %s", e.what()); - } - - return; -} - -int _esd_cion_init() { - try { - esd_cion_server = - std::make_shared("__CION_INTERNAL_DAEMON__", ""); - } catch (const cion::Exception& e) { - _D("cion_init failed : %s", e.what()); - return -1; - } - - _D("cion_init done"); - - __change_listen_status_cion_server(); - - return 0; -} - -void _esd_cion_adds_enabled_app(const char *service_name, const char *app_id, - const char *display_name) { - if (esd_cion_server == nullptr) { - _E("Call init function at first"); - return; - } - - esd_cion_server->AddOndemandServiceList(std::string(service_name), - std::string(app_id), std::string(display_name)); - - if (!is_listening) - __change_listen_status_cion_server(); -} - -void _esd_cion_removes_enabled_app(const char *service_name, const char *app_id) { - if (esd_cion_server == nullptr) { - _E("Call init function at first"); - return; - } - - esd_cion_server->RemoveOndemandServiceList(std::string(service_name), - std::string(app_id)); - - if (is_listening) - __change_listen_status_cion_server(); -} \ No newline at end of file diff --git a/src/esd_cion/esd_cion_db.c b/src/esd_cion/esd_cion_db.c deleted file mode 100644 index f6689f4..0000000 --- a/src/esd_cion/esd_cion_db.c +++ /dev/null @@ -1,542 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "eventsystem_daemon.h" - -#define DBPATH tzplatform_mkpath(TZ_SYS_DB, ".cion.db") - -#define CREATE_CION_TABLE " \ -PRAGMA user_version = 50; \ -PRAGMA journal_mode = PERSIST; \ -PRAGMA foreign_keys = ON; \ -BEGIN EXCLUSIVE TRANSACTION; \ -CREATE TABLE IF NOT EXISTS cion_uuid ( \ - appid TEXT NOT NULL, \ - uuid TEXT NOT NULL, \ - PRIMARY KEY(appid) \ -); \ -CREATE TABLE IF NOT EXISTS cion_display_name ( \ - service_name TEXT NOT NULL, \ - appid TEXT NOT NULL, \ - display_name TEXT NULL, \ - enabled INTEGER DEFAULT 0, \ - PRIMARY KEY(service_name, appid) , \ - FOREIGN KEY(appid) REFERENCES cion_uuid (appid) ON DELETE CASCADE \ -); \ -COMMIT TRANSACTION; " - -static int __check_table_exist(sqlite3 *db) { - int ret; - const char *val; - sqlite3_stmt *stmt = NULL; - const char query[] = - "SELECT name FROM sqlite_master WHERE type='table'" - " ORDER BY name ASC"; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - _E("prepare error: %s", sqlite3_errmsg(db)); - ret = -1; - goto out; - } - - ret = sqlite3_step(stmt); - if (ret != SQLITE_ROW) { - _E("fail to get row"); - ret = -1; - goto out; - } - - val = (const char*)sqlite3_column_text(stmt, 0); - if (val == NULL) { - _E("name is NULL"); - ret = -1; - goto out; - } - - if (strcmp("cion", val) != 0) { - ret = -1; - goto out; - } - - ret = 0; - -out: - sqlite3_finalize(stmt); - - return ret; -} - -static int __create_table(sqlite3 *db) { - int ret; - char *errmsg = NULL; - - ret = sqlite3_exec(db, CREATE_CION_TABLE, - NULL, NULL, &errmsg); - if (ret != SQLITE_OK) { - _E("create table fail : %s", errmsg); - sqlite3_free(errmsg); - return -1; - } - - return 0; -} - -int esd_cion_db_init(void) { - sqlite3 *db = NULL; - - if (sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) { - sqlite3_close_v2(db); - unlink(DBPATH); - - if (sqlite3_open_v2(DBPATH, &db, - SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, - NULL) != SQLITE_OK) { - _E("Fail to create db"); - unlink(DBPATH); - return -1; - } - } - - if (__check_table_exist(db) < 0) { - if (__create_table(db) < 0) { - sqlite3_close_v2(db); - _E("Fail to create table"); - return -1; - } - } - - sqlite3_close_v2(db); - - return 0; -} - -sqlite3 *esd_cion_db_open() { - sqlite3 *db; - - if (access(DBPATH, R_OK | W_OK) != 0) - return NULL; - - if (sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) - return NULL; - - return db; -} - -int esd_cion_db_close(sqlite3 **db) { - if (db == NULL || *db == NULL) - return 0; - - if (sqlite3_close(*db) != SQLITE_OK) { - _E("Failed to close db"); - return 0; - } - - *db = NULL; - - return 0; -} - -static const char *__esd_cion_generate_uuid() { - uuid_t uu; - char _uuid[37]; - char *uuid; - - uuid_generate_random(uu); - uuid_unparse(uu, _uuid); - - uuid = strdup(_uuid); - - return uuid; -} - -static int __esd_cion_get_uuid(sqlite3 *db, const char *appid, char **uuid) { - int ret = -1; - char *query; - sqlite3_stmt *stmt = NULL; - - query = sqlite3_mprintf("SELECT uuid FROM cion_uuid " - "WHERE appid = %Q", appid); - if (query == NULL) - goto out; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) - goto out; - - ret = sqlite3_step(stmt); - if (ret == SQLITE_ROW) { - ret = 0; - *uuid = strdup((char*)sqlite3_column_text(stmt, 0)); - } - -out: - sqlite3_free(query); - sqlite3_finalize(stmt); - - return ret; -} - -static int __esd_cion_set_uuid(sqlite3 *db, const char *appid, const char *uuid) { - int ret = -1; - char *query; - sqlite3_stmt *stmt = NULL; - - query = sqlite3_mprintf("INSERT INTO cion_uuid (appid, uuid) " - "VALUES (%Q, %Q) ", appid, uuid); - if (query == NULL) - goto out; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) - goto out; - - ret = sqlite3_step(stmt); - if (ret == SQLITE_OK || ret == SQLITE_DONE) - ret = 0; - -out: - sqlite3_free(query); - sqlite3_finalize(stmt); - - return ret; -} - -int esd_cion_get_uuid_with_generate(const char *appid, char **uuid) { - int ret = 0; - sqlite3 *db; - const char *_uuid; - - db = esd_cion_db_open(); - if (!db) { - _E("db open fail"); - return -1; - } - - if (__esd_cion_get_uuid(db, appid, uuid) != 0) { - _uuid = __esd_cion_generate_uuid(); - ret = __esd_cion_set_uuid(db, appid, _uuid); - if (ret == 0) - *uuid = (char*)_uuid; - else - free((char*)_uuid); - - _E("get uuid generate"); - } - - esd_cion_db_close(&db); - - return ret; -} - -int esd_cion_set_display_name(const char *appid, const char *service_name, - char *display_name) { - int ret = -1; - sqlite3 *db; - char *query = NULL; - sqlite3_stmt *stmt = NULL; - char *_uuid = NULL; - - db = esd_cion_db_open(); - if (!db) { - _E("db open fail"); - return -1; - } - - if (__esd_cion_get_uuid(db, appid, &_uuid) != 0) { - _uuid = (char*)__esd_cion_generate_uuid(); - ret = __esd_cion_set_uuid(db, appid, _uuid); - if (ret != 0) - goto out; - } - - query = sqlite3_mprintf("INSERT INTO cion_display_name " - "(service_name, appid, display_name) " - "VALUES (%Q, %Q, %Q) ON CONFLICT(service_name, appid)" - "DO UPDATE SET display_name = %Q " - "WHERE service_name = %Q AND appid = %Q ", service_name, appid, display_name, - display_name, service_name, appid); - if (query == NULL) - goto out; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) - goto out; - - ret = sqlite3_step(stmt); - _E("set name step: %d", ret); - - if (ret == SQLITE_OK || ret == SQLITE_DONE) - ret = 0; - -out: - free(_uuid); - sqlite3_free(query); - sqlite3_finalize(stmt); - esd_cion_db_close(&db); - - return ret; -} - -int esd_cion_get_display_name(const char *appid, const char *service_name, - char **display_name) { - int ret = -1; - sqlite3 *db; - char *query = NULL; - sqlite3_stmt *stmt = NULL; - char *_name = NULL; - - db = esd_cion_db_open(); - if (!db) { - _E("db open fail"); - return -1; - } - - query = sqlite3_mprintf("SELECT display_name FROM cion_display_name " - "WHERE appid = %Q AND service_name = %Q", appid, service_name); - if (query == NULL) - goto out; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) - goto out; - - ret = sqlite3_step(stmt); - if (ret == SQLITE_ROW) { - ret = 0; - - _name = (char*)sqlite3_column_text(stmt, 0); - - if (_name != NULL) - *display_name = strdup(_name); - else - _E("get display name null"); - - } else if (ret == SQLITE_DONE){ - _E("get display name not exist"); - ret = 0; - } - -out: - sqlite3_free(query); - sqlite3_finalize(stmt); - esd_cion_db_close(&db); - - return ret; -} - -int esd_cion_set_enabled(const char *appid, const char *service_name, - bool enabled) { - int ret = -1; - sqlite3 *db; - char *query = NULL; - const char *display_name = ""; - sqlite3_stmt *stmt = NULL; - sqlite3_stmt *select_stmt = NULL; - - db = esd_cion_db_open(); - if (!db) { - _E("db open fail"); - return -1; - } - - query = sqlite3_mprintf("UPDATE cion_display_name SET enabled = %i " - "WHERE appid = %Q AND service_name = %Q", enabled? 1 : 0 , - appid, service_name); - if (query == NULL) - goto out; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) - goto out; - - ret = sqlite3_step(stmt); - if (ret != SQLITE_OK && ret != SQLITE_DONE) - goto out; - - sqlite3_free(query); - query = sqlite3_mprintf("SELECT display_name FROM cion_display_name " - "WHERE appid = %Q AND service_name = %Q", appid, service_name); - if (query == NULL) - goto out; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &select_stmt, NULL); - if (ret != SQLITE_OK) - goto out; - - ret = sqlite3_step(select_stmt); - if (ret == SQLITE_ROW) { - ret = 0; - display_name = (const char*)sqlite3_column_text(select_stmt, 0); - } - - if (enabled) - _esd_cion_adds_enabled_app(service_name, appid, display_name); - else - _esd_cion_removes_enabled_app(service_name, appid); - -out: - sqlite3_free(query); - sqlite3_finalize(stmt); - sqlite3_finalize(select_stmt); - esd_cion_db_close(&db); - - return ret; -} - -int esd_cion_get_enabled(const char *appid, const char *service_name, - int *enabled) { - int ret = -1; - sqlite3 *db; - char *query = NULL; - sqlite3_stmt *stmt = NULL; - - db = esd_cion_db_open(); - if (!db) { - _E("db open fail"); - return -1; - } - - query = sqlite3_mprintf("SELECT enabled FROM cion_display_name " - "WHERE appid = %Q AND service_name = %Q", appid, service_name); - if (query == NULL) - goto out; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) - goto out; - - ret = sqlite3_step(stmt); - if (ret == SQLITE_ROW) { - ret = 0; - - *enabled = sqlite3_column_int(stmt, 0); - } else if (ret == SQLITE_DONE){ - _E("get enabled not exist"); - ret = 0; - } - -out: - sqlite3_free(query); - sqlite3_finalize(stmt); - esd_cion_db_close(&db); - - return ret; -} - -static void __cion_service_info_destroy(cion_service_info_s *info) -{ - if (info == NULL) - return; - - free(info->service_name); - free(info->appid); - free(info->display_name); - free(info); -} - -static cion_service_info_s *__cion_service_info_create(sqlite3_stmt *stmt) -{ - cion_service_info_s *info; - const char* value; - int index = 0; - - info = calloc(1, sizeof(cion_service_info_s)); - if (info == NULL) { - _E("malloc() is failed"); - return NULL; - } - - value = (const char *)sqlite3_column_text(stmt, index++); - if (value == NULL) { - _E("sqlite3_column_text() is failed. index: %d", index - 1); - __cion_service_info_destroy(info); - return NULL; - } - - info->service_name = strdup(value); - if (info->service_name == NULL) { - _E("strdup() is failed"); - __cion_service_info_destroy(info); - return NULL; - } - - value = (const char *)sqlite3_column_text(stmt, index++); - if (value == NULL) { - _E("sqlite3_column_text() is failed. index: %d", index - 1); - __cion_service_info_destroy(info); - return NULL; - } - - info->appid = strdup(value); - if (info->appid == NULL) { - _E("strdup() is failed"); - __cion_service_info_destroy(info); - return NULL; - } - - value = (const char *)sqlite3_column_text(stmt, index++); - if (value != NULL) - info->display_name = strdup(value); - else - info->display_name = strdup(""); - - if (info->display_name == NULL) { - _E("strdup() is failed"); - __cion_service_info_destroy(info); - return NULL; - } - - return info; -} - -int esd_cion_get_enabled_service_list(GList **list) -{ - int ret = -1; - sqlite3 *db; - char *query = NULL; - sqlite3_stmt *stmt = NULL; - cion_service_info_s *cion_info; - - db = esd_cion_db_open(); - if (!db) { - _E("db open fail"); - return -1; - } - - query = sqlite3_mprintf("SELECT service_name, appid, display_name " - "FROM cion_display_name WHERE enabled = 1"); - if (query == NULL) - goto out; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) - goto out; - - while (sqlite3_step(stmt) == SQLITE_ROW) { - cion_info = __cion_service_info_create(stmt); - if (cion_info == NULL) { - ret = -1; - goto out; - } - - _D("get list : [%s:%s:%s]", - cion_info->service_name, cion_info->appid, - cion_info->display_name); - *list = g_list_append(*list, cion_info); - } - -out: - sqlite3_free(query); - sqlite3_finalize(stmt); - esd_cion_db_close(&db); - - return ret; -} diff --git a/src/esd_main.c b/src/esd_main.c deleted file mode 100644 index dee892c..0000000 --- a/src/esd_main.c +++ /dev/null @@ -1,2640 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "eventsystem_daemon.h" - -#define DEFAULT_USER tzplatform_getuid(TZ_SYS_DEFAULT_USER) -#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) -#define ROOT_USER 0 - -#define SYS_EVENT_NAME_PREFIX "tizen.system.event" -#define SYS_EVENT_OBJ_PATH "/tizen/system/event" -#define REQUEST_LAST_DATA "request_last_data" - -static GHashTable *event_launch_table; /* table of events for launch_on_event*/ - -static const char *event_launch_support_list[] = { - SYS_EVENT_BATTERY_CHARGER_STATUS, - SYS_EVENT_USB_STATUS, - SYS_EVENT_EARJACK_STATUS, - SYS_EVENT_INCOMMING_MSG, - SYS_EVENT_OUTGOING_MSG, - SYS_EVENT_WIFI_STATE -}; - -struct privilege_info { - const char *event_name; - const char *privilege_name; -}; - -static const struct privilege_info privilege_check_list[] = { - {SYS_EVENT_DISPLAY_STATE, "http://tizen.org/privilege/display"}, - {SYS_EVENT_WIFI_STATE, "http://tizen.org/privilege/network.get"}, - {SYS_EVENT_INCOMMING_MSG, "http://tizen.org/privilege/message.read"}, - {SYS_EVENT_OUTGOING_MSG, "http://tizen.org/privilege/message.read"} -}; - -static int privilege_check_size = sizeof(privilege_check_list)/sizeof(struct privilege_info); - -#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE -static const char *earlier_event_list[] = { - SYS_EVENT_ESD_STATUS, - SYS_EVENT_LOW_MEMORY, - SYS_EVENT_BOOT_COMPLETED, - SYS_EVENT_SYSTEM_SHUTDOWN, - SYS_EVENT_BATTERY_CHARGER_STATUS -}; - -static GHashTable *earlier_event_table; /* table of events for earlier_data */ - -typedef struct __earlier_table_item { - char *event_name; - guint reg_id; - bundle *earlier_data; /* event-data from earlier occurrence */ -} earlier_item; - -#endif - -static GHashTable *user_last_event_table; /* table of user events for last data */ - -struct __last_event_item { - char *key; - char *app_id; - char *event_name; - char *own_name; - uid_t uid; -}; - -static GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */ - -typedef struct __trusted_busname_item { - char *app_id; - char *bus_name; - int pid; - uid_t uid; -} trusted_item; - -typedef struct __eventlaunch_item_param { - char *app_id; -} eventlaunch_item_param_s; - -enum trusted_result { - TRUSTED_UNKNOWN, - TRUSTED_ALLOWED, - TRUSTED_DENIED, -}; - -typedef struct esd_list_item { - char *pkg_id; - char *app_id; - int trusted_info; - uid_t uid; -} esd_list_item_s; - -typedef struct __event_launch_table_item { - char *event_name; - char *package_name; /* just for passing pointer to app-list removal func */ - GList *app_list_evtlaunch; /* app-list for on-event-launch */ - guint reg_id; - uid_t uid; -} event_launch_item; - -enum __pkg_event_type { - UNKNOWN = 0, - INSTALL, - UNINSTALL, - UPDATE, -}; - -typedef struct __pkgmgr_event { - int type; - char *pkgid; -} esd_pkgmgr_event; - -typedef struct __esd_event_param { - char *event_name; - bundle *event_data; - uid_t sender_uid; - char *sender_appid; - bool is_user_event; - bool trusted; - void *user_data; -} esd_event_param; - -typedef struct esd_info { - pkgmgr_client *client; -} esd_info_s; -static esd_info_s s_info; - -typedef struct __esd_appctrl_cb_data { - char *appid; - char *pkgid; - uid_t uid; -} esd_appctrl_cb_data; - -static void __esd_event_handler(char *event_name, bundle *data, void *user_data); -static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data); - -static cynara *r_cynara; - -static int __esd_init_cynara(void) -{ - int ret; - - ret = cynara_initialize(&r_cynara, NULL); - if (ret != CYNARA_API_SUCCESS) { - _E("cynara initialize failed."); - return ret; - } - - return 0; -} - -static void __esd_finish_cynara(void) -{ - if (r_cynara) - cynara_finish(r_cynara); - r_cynara = NULL; -} - -static void free_saved_event(struct __last_event_item *item) -{ - if (!item) - return; - - free(item->event_name); - free(item->own_name); - free(item->app_id); - free(item); -} - -#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE -static int __esd_check_earlier_support(const char *event_name) -{ - int i = 0; - int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list); - - for (i = 0; i < size; i++) { - if (strcmp(earlier_event_list[i], event_name) == 0) - return true; - } - - return false; -} -#endif - -static bool __esd_check_platform_cert(const char *pkgid, uid_t uid) -{ - _D("Checking if %s has a platform certification", pkgid); - - int r; - const char *cert_value; - pkgmgrinfo_certinfo_h certinfo; - CertSvcInstance instance; - CertSvcCertificate certificate; - CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC; - - r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo); - if (r != PMINFO_R_OK) { - _E("Failed to create certinfo"); - return false; - } - - r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid); - if (r != PMINFO_R_OK) { - _E("Failed to load certinfo"); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - return false; - } - - r = pkgmgrinfo_pkginfo_get_cert_value(certinfo, - PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value); - if (r != PMINFO_R_OK || cert_value == NULL) { - _E("Failed to get cert value"); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - return false; - } - - r = certsvc_instance_new(&instance); - if (r != CERTSVC_SUCCESS) { - _E("certsvc_instance_new() is failed."); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - return false; - } - - r = certsvc_certificate_new_from_memory(instance, - (const unsigned char *)cert_value, - strlen(cert_value), - CERTSVC_FORM_DER_BASE64, - &certificate); - if (r != CERTSVC_SUCCESS) { - _E("certsvc_certificate_new_from_memory() is failed."); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - certsvc_instance_free(instance); - return false; - } - - r = certsvc_certificate_get_visibility(certificate, &visibility); - if (r != CERTSVC_SUCCESS) - _E("certsvc_certificate_get_visibility() is failed."); - - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - certsvc_certificate_free(certificate); - certsvc_instance_free(instance); - - _D("visibility is %d", visibility); - if (visibility & CERTSVC_VISIBILITY_PLATFORM) { - _D("%s has a platform certification", pkgid); - return true; - } - - return false; -} - -static int __esd_check_event_launch_support(const char *event_name) -{ - int i = 0; - int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list); - - for (i = 0; i < size; i++) { - if (strcmp(event_launch_support_list[i], event_name) == 0) - return true; - } - - return false; -} - -static int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type) -{ - GDBusMessage *msg = NULL; - GDBusMessage *reply = NULL; - GError *err = NULL; - GVariant *body; - int ret = -1; - unsigned int value; - - msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", - "org.freedesktop.DBus", type); - if (!msg) { - _E("Can't allocate new method call"); - goto out; - } - - g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name)); - reply = g_dbus_connection_send_message_with_reply_sync(conn, msg, - G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err); - - if (!reply) { - if (err != NULL) { - _E("Failed to get info [%s]", err->message); - g_error_free(err); - } - goto out; - } - - body = g_dbus_message_get_body(reply); - g_variant_get(body, "(u)", &value); - ret = (int)value; - -out: - if (msg) - g_object_unref(msg); - if (reply) - g_object_unref(reply); - - return ret; -} - -static int __get_sender_pid(GDBusConnection *conn, const char *sender_name) -{ - int pid = 0; - - pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID"); - if (pid < 0) { - _E("failed to get pid"); - pid = 0; - } - - _D("sender_name(%s), pid(%d)", sender_name, pid); - - return pid; -} - -static int __get_sender_uid(GDBusConnection *conn, const char *sender_name) -{ - int uid = -1; - - uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser"); - if (uid < 0) - _E("failed to get uid"); - - _D("sender_name(%s), uid(%d)", sender_name, uid); - - return uid; -} - -static int __esd_check_certificate_match(uid_t uid, const char *app_id, uid_t from_uid, const char *from_appid) -{ - pkgmgrinfo_cert_compare_result_type_e res; - int ret = 0; - - _D("uid(%d), app_id(%s), from_uid(%d), from_appid(%s)", uid, app_id, from_uid, from_appid); - - ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, from_appid, from_uid, &res); - if (ret < 0) { - _E("failed to check certificate"); - return ES_R_ERROR; - } - - if (res != PMINFO_CERT_COMPARE_MATCH) { - _D("certificat not match (%s)", app_id); - return ES_R_EINVAL; - } - - return ES_R_OK; -} - -static bool __esd_check_application_validation(uid_t uid, const char *appid) -{ - int ret = 0; - pkgmgrinfo_appinfo_h handle; - - ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle); - if (ret != PMINFO_R_OK) - return false; - - pkgmgrinfo_appinfo_destroy_appinfo(handle); - - if (!aul_app_is_running_for_uid(appid, uid)) - return false; - - return true; -} - -static void __esd_trusted_busname_print_items(void) -{ - GHashTableIter iter; - gpointer key; - gpointer value; - - g_hash_table_iter_init(&iter, trusted_busname_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) { - trusted_item *item = (trusted_item *)value; - if (item) - _D("uid(%d), appid(%s), pid(%d), busname(%s)", item->uid, item->app_id, item->pid, item->bus_name); - } -} - -static int __esd_trusted_busname_add_item(uid_t uid, const char *appid, const char *busname, int pid) -{ - char *app_id = NULL; - char *bus_name = NULL; - trusted_item *item = NULL; - trusted_item *new_item; - - app_id = strdup(appid); - if (app_id == NULL) { - _E("out of memory"); - return ES_R_ENOMEM; - } - - bus_name = strdup(busname); - if (bus_name == NULL) { - _E("out of memory"); - FREE_AND_NULL(app_id); - return ES_R_ENOMEM; - } - - item = (trusted_item *)g_hash_table_lookup(trusted_busname_table, app_id); - - if (item && item->bus_name && strcmp(item->bus_name, bus_name) == 0 && - (item->uid == uid)) { - _D("already exist (%s, %s)", app_id, bus_name); - FREE_AND_NULL(app_id); - FREE_AND_NULL(bus_name); - } else { - new_item = calloc(1, sizeof(trusted_item)); - if (new_item == NULL) { - _E("memory alloc failed"); - FREE_AND_NULL(app_id); - FREE_AND_NULL(bus_name); - return ES_R_ENOMEM; - } - new_item->uid = uid; - new_item->app_id = app_id; - new_item->bus_name = bus_name; - new_item->pid = pid; - g_hash_table_insert(trusted_busname_table, new_item->app_id, new_item); - _D("added busname(%s)", new_item->bus_name); - } - - return ES_R_OK; -} - -static int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name) -{ - GVariant *result; - GError *error = NULL; - GVariantIter *iter; - gchar *str; - char tmp_appid[128] = {0, }; - int pid = 0; - int uid = 0; - int ret = 0; - - result = g_dbus_connection_call_sync(conn, - "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", - list_name, NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE, - -1, NULL, &error); - - if (result == NULL) { - _E("get (%s) error(%s)", list_name, error->message); - g_error_free(error); - return ES_R_ERROR; - } - - g_variant_get(result, "(as)", &iter); - while (g_variant_iter_loop(iter, "s", &str)) { - if (!strstr((const char *)str, "event.busname.session")) - continue; - - _D("list(%s), name(%s)", list_name, str); - pid = __get_sender_pid(conn, (const char *)str); - if (pid <= 0) { - _E("failed to get pid(%d)", pid); - continue; - } - - uid = __get_sender_uid(conn, (const char *)str); - if (uid < 0) { - _E("failed to get uid(%d)", uid); - continue; - } - _D("uid(%d)", uid); - - memset(tmp_appid, 0, sizeof(tmp_appid)); - ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), (uid_t)uid); - if (ret != AUL_R_OK) { - _E("failed to get appid by pid(%d)", pid); - continue; - } - - _D("appid(%s)", tmp_appid); - if (__esd_check_application_validation((uid_t)uid, tmp_appid)) { - _D("add to table"); - ret = __esd_trusted_busname_add_item((uid_t)uid, tmp_appid, (const char *)str, pid); - if (ret < 0) - _E("failed to add item"); - } - } - g_variant_iter_free(iter); - g_variant_unref(result); - - return ES_R_OK; -} - -static int __esd_check_privilege_name(const char *event_name, char **privilege_name) -{ - int i = 0; - - *privilege_name = NULL; - - for (i = 0; i < privilege_check_size; i++) { - if (strcmp(event_name, privilege_check_list[i].event_name) == 0) { - *privilege_name = (char *)privilege_check_list[i].privilege_name; - _D("[%d] privilege_name(%s)", i, *privilege_name); - break; - } - } - - return ES_R_OK; -} - -static bool __esd_check_valid_privilege_by_cynara(const char *appid, const char *client, - const char *session, const char *user, const char *privilege_name) -{ - int ret = 0; - bool has_privilege = false; - - _D("check privilege, (%s, %s, %s, %s, %s)", appid, client, session, user, privilege_name); - - ret = cynara_check(r_cynara, client, session, user, privilege_name); - if (ret == CYNARA_API_ACCESS_ALLOWED) { - _D("valid privilege"); - has_privilege = true; - } else if (ret == CYNARA_API_ACCESS_DENIED) { - _E("invalid privilege"); - } else { - _E("failed to check privilege, error(%d)", ret); - } - - return has_privilege; -} - -static int __esd_check_app_privileged_event(uid_t uid, const char *appid, const char *pkgid, const char *event_name) -{ - char *privilege_name = NULL; - int ret = 0; - int result = 0; - - _D("event_name(%s), uid(%d), appid(%s), pkgid(%s)", event_name, uid, appid, pkgid); - - __esd_check_privilege_name(event_name, &privilege_name); - - if (privilege_name) { - ret = security_manager_app_has_privilege(appid, privilege_name, uid, &result); - if (ret != SECURITY_MANAGER_SUCCESS) - _E("failed to check privilege(%d)", ret); - _D("result(%d)", result); - } else { - result = 1; - } - - return result; -} - -static void __esd_print_appid_with_eventid(gpointer data, gpointer user_data) -{ - esd_list_item_s *item = (esd_list_item_s *)data; - char *event_name = (char *)user_data; - - _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name, item->uid, item->app_id, item->pkg_id); -} - -static void __esd_print_interested_event(gpointer data, gpointer user_data) -{ - event_launch_item *el_item = (event_launch_item *)data; - char *event_name = (char *)el_item->event_name; - _D("event_name = (%s)", event_name); - g_list_foreach(el_item->app_list_evtlaunch, __esd_print_appid_with_eventid, event_name); -} - -static void __esd_launch_table_print_items(void) -{ - GHashTableIter iter; - gpointer key; - gpointer value; - - g_hash_table_iter_init(&iter, event_launch_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) - __esd_print_interested_event(value, NULL); -} - -static int __esd_find_compare_by_list_item(gconstpointer data, gconstpointer user_data) -{ - esd_list_item_s *item_1 = (esd_list_item_s *)user_data; - esd_list_item_s *item_2 = (esd_list_item_s *)data; - - return (item_1->uid != item_2->uid) | - strcmp(item_1->app_id, item_2->app_id) | - strcmp(item_1->pkg_id, item_2->pkg_id); -} - -static int __esd_add_list_item(uid_t uid, event_launch_item *el_item, - const char *app_id, const char *pkg_id) -{ - esd_list_item_s *item_of_list = NULL; - - item_of_list = calloc(1, sizeof(esd_list_item_s)); - if (item_of_list == NULL) { - _E("out_of_memory"); - return ES_R_ENOMEM; - } - item_of_list->uid = uid; - item_of_list->app_id = (char *)app_id; - item_of_list->pkg_id = (char *)pkg_id; - item_of_list->trusted_info = TRUSTED_UNKNOWN; - el_item->app_list_evtlaunch = - g_list_append(el_item->app_list_evtlaunch, item_of_list); - - return ES_R_OK; -} - -static int __esd_add_launch_item(uid_t uid, const char *event_name, - const char *appid, const char *pkgid) -{ - GList *app_list = NULL; - guint subscription_id = 0; - char *app_id = NULL; - char *pkg_id = NULL; - esd_list_item_s *item_of_list = NULL; - event_launch_item *eli; - event_launch_item *el_item = - (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name); - - if (el_item) { - item_of_list = calloc(1, sizeof(esd_list_item_s)); - if (item_of_list == NULL) { - _E("memory alloc failed"); - return ES_R_ENOMEM; - } - item_of_list->uid = uid; - item_of_list->app_id = (char *)appid; - item_of_list->pkg_id = (char *)pkgid; - - app_list = g_list_find_custom(el_item->app_list_evtlaunch, - item_of_list, (GCompareFunc)__esd_find_compare_by_list_item); - free(item_of_list); - if (app_list == NULL) { - _D("add new item (list item only)"); - app_id = strdup((char *)appid); - if (!app_id) { - _E("out_of_memory"); - return ES_R_ENOMEM; - } - pkg_id = strdup((char *)pkgid); - if (!pkg_id) { - _E("out_of_memory"); - FREE_AND_NULL(app_id); - return ES_R_ENOMEM; - } - if (__esd_add_list_item(uid, el_item, app_id, pkg_id) < 0) { - _E("failed to add list item"); - FREE_AND_NULL(app_id); - FREE_AND_NULL(pkg_id); - return ES_R_ERROR; - } - } - } else { - _D("add new item (all)"); - eli = calloc(1, sizeof(event_launch_item)); - if (!eli) { - _E("memory alloc failed"); - return ES_R_ENOMEM; - } - - eli->event_name = strdup(event_name); - if (!eli->event_name) { - _E("out_of_memory"); - FREE_AND_NULL(eli); - return ES_R_ENOMEM; - } - - app_id = strdup((char *)appid); - if (!app_id) { - _E("out_of_memory"); - FREE_AND_NULL(eli->event_name); - FREE_AND_NULL(eli); - return ES_R_ENOMEM; - } - - pkg_id = strdup((char *)pkgid); - if (!pkg_id) { - _E("out_of_memory"); - FREE_AND_NULL(app_id); - FREE_AND_NULL(eli->event_name); - FREE_AND_NULL(eli); - return ES_R_ENOMEM; - } - - if (__esd_add_list_item(uid, eli, app_id, pkg_id) < 0) { - _E("failed to add list item"); - FREE_AND_NULL(app_id); - FREE_AND_NULL(pkg_id); - FREE_AND_NULL(eli->event_name); - FREE_AND_NULL(eli); - return ES_R_ERROR; - } - - g_hash_table_insert(event_launch_table, eli->event_name, eli); - - eventsystem_register_event(eli->event_name, &subscription_id, - (eventsystem_handler)__esd_event_handler, NULL); - if (subscription_id == 0) { - _E("signal subscription error, event_name(%s), app_id(%s)", - eli->event_name, app_id); - return ES_R_ERROR; - } else { - eli->reg_id = subscription_id; - } - } - - return ES_R_OK; -} - -static void __esd_remove_all_private_usr_app_list(gpointer data, gpointer user_data) -{ - esd_list_item_s *item = (esd_list_item_s *)data; - event_launch_item *eli = (event_launch_item *)user_data; - - if (item->uid != GLOBAL_USER && !strcmp(eli->package_name, item->pkg_id)) { - _D("uid(%d), app_id(%s), pkg_id(%s)", item->uid, item->app_id, eli->package_name); - eli->app_list_evtlaunch = g_list_remove_all(eli->app_list_evtlaunch, data); - } -} - -static int __esd_launch_table_remove_private_usr_items(void) -{ - GHashTableIter iter; - gpointer key; - gpointer value; - event_launch_item *eli = NULL; - GList *first_list = NULL; - - g_hash_table_iter_init(&iter, event_launch_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) { - eli = (event_launch_item *)value; - g_list_foreach(eli->app_list_evtlaunch, __esd_remove_all_private_usr_app_list, eli); - - first_list = g_list_first(eli->app_list_evtlaunch); - if (first_list == NULL) { - if (eli->reg_id) - eventsystem_unregister_event(eli->reg_id); - - g_hash_table_iter_remove(&iter); - } - } - - return ES_R_OK; -} - -static void __esd_remove_app_list(gpointer data, gpointer user_data) -{ - bool skip = false; - esd_list_item_s *item = (esd_list_item_s *)data; - event_launch_item *eli = (event_launch_item *)user_data; - - if (eli->uid != GLOBAL_USER && eli->uid != item->uid) - skip = true; - - if (!skip && !strcmp(eli->package_name, item->pkg_id)) { - _D("pkg_id(%s), app_id(%s)", eli->package_name, item->app_id); - eli->app_list_evtlaunch = - g_list_remove_all(eli->app_list_evtlaunch, data); - } -} - -static int __esd_remove_launch_item(uid_t uid, gpointer data, const char *pkg_id) -{ - event_launch_item *eli = (event_launch_item *)data; - GList *first_list = NULL; - - eli->uid = uid; - eli->package_name = (char *)pkg_id; - g_list_foreach(eli->app_list_evtlaunch, __esd_remove_app_list, eli); - - first_list = g_list_first(eli->app_list_evtlaunch); - if (first_list == NULL) { - if (eli->reg_id) - eventsystem_unregister_event(eli->reg_id); - - return ES_R_REMOVE; - } - - return ES_R_OK; -} - -static int __esd_launch_table_remove_items(uid_t uid, const char *pkg_id) -{ - GHashTableIter iter; - gpointer key; - gpointer value; - - g_hash_table_iter_init(&iter, event_launch_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) { - if (__esd_remove_launch_item(uid, value, pkg_id) == ES_R_REMOVE) { - _D("remove item itself"); - g_hash_table_iter_remove(&iter); - } - } - - return ES_R_OK; -} - -static void __esd_event_launch_with_appid(gpointer data, gpointer user_data) -{ - esd_list_item_s *item = (esd_list_item_s *)data; - uid_t uid = item->uid; - char *app_id = item->app_id; - esd_event_param *eep = (esd_event_param *)user_data; - static unsigned int req_id; - int pid; - char event_uri[1024]; - bundle *b; - int ret; - - _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d), trusted(%d)", - app_id, eep->event_name, uid, eep->is_user_event, eep->trusted); - - if (eep->is_user_event && eep->trusted) { - if (item->trusted_info == TRUSTED_UNKNOWN) { - ret = __esd_check_certificate_match(uid, app_id, eep->sender_uid, eep->sender_appid); - if (ret == ES_R_EINVAL) { - item->trusted_info = TRUSTED_DENIED; - return; - } else if (ret == ES_R_ERROR) { - return; - } else { - item->trusted_info = TRUSTED_ALLOWED; - } - } else if (item->trusted_info == TRUSTED_DENIED) { - return; - } - } - - if (!aul_app_is_running_for_uid(app_id, uid)) { - b = bundle_dup(eep->event_data); - if (eep->is_user_event) - snprintf(event_uri, sizeof(event_uri), "%s%s", USER_EVENT_NAME_PREFIX, eep->event_name); - else - snprintf(event_uri, sizeof(event_uri), "%s%s", SYSTEM_EVENT_NAME_PREFIX, eep->event_name); - - appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT); - appsvc_set_uri(b, event_uri); - appsvc_set_appid(b, app_id); - - pid = aul_svc_run_service_async_for_uid(b, req_id++, NULL, eep->user_data, uid); - _D("uid(%d), pid(%d)", uid, pid); - - bundle_free(b); - } else { - _D("already is running or launch failed"); - } -} - -static void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_data) -{ - event_launch_item *el_item = (event_launch_item *)data; - esd_event_param *eep = (esd_event_param *)user_data; - - if (strcmp(eep->event_name, (char *)el_item->event_name) == 0) { - g_list_foreach(el_item->app_list_evtlaunch, - __esd_event_launch_with_appid, user_data); - } -} - -static void __esd_launch_event_handler(char *event_name, bundle *data, - const bool is_user_event, gboolean trusted, - const uid_t sender_uid, char *sender_appid, void *user_data) -{ - const char *val; - const char *msg_type; - const char *msg_id; - esd_event_param *eep; - event_launch_item *el_item; - - _D("event_name(%s)", event_name); - - el_item = (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name); - if (el_item == NULL) - return; - - if (el_item->app_list_evtlaunch != NULL) { - if (is_user_event == false) { - if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS); - _D("charger val(%s)", val); - if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0)) - return; - } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_USB_STATUS); - _D("usb val(%s)", val); - if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0)) - return; - } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS); - _D("earjack val(%s)", val); - if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0)) - return; - } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) { - msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE); - _D("msg_type(%s)", msg_type); - if (msg_type == NULL) - return; - - msg_id = bundle_get_val(data, EVT_KEY_MSG_ID); - _D("msg_id(%s)", msg_id); - if (msg_id == NULL) - return; - } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) { - val = bundle_get_val(data, EVT_KEY_WIFI_STATE); - if (val == NULL) - return; - _D("wifi_state(%s)", val); - if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0) - return; - } - } - - eep = calloc(1, sizeof(esd_event_param)); - if (!eep) { - _E("memory alloc failed"); - return; - } - eep->event_name = event_name; - eep->event_data = data; - eep->sender_uid = sender_uid; - eep->sender_appid = sender_appid; - eep->is_user_event = is_user_event; - eep->trusted = (bool)trusted; - eep->user_data = (void *)user_data; - __esd_check_event_launch_with_eventid(el_item, eep); - free(eep); - } -} - -#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE -static void __esd_print_earlier_event(gpointer data, gpointer user_data) -{ - earlier_item *item = (earlier_item *)data; - char *event_name = (char *)item->event_name; - const char *val; - - _D("event_name = (%s)", event_name); - - if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) { - if (item->earlier_data) { - val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED); - _D("boot_completed(%s)", val); - } - } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) { - if (item->earlier_data) { - val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN); - _D("shutdown(%s)", val); - } - } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) { - if (item->earlier_data) { - val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY); - _D("low_memory(%s)", val); - } - } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) { - if (item->earlier_data) { - val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS); - _D("charger_status(%s)", val); - } - } -} - -static void __esd_earlier_table_print_items(void) -{ - GHashTableIter iter; - gpointer key; - gpointer value; - - g_hash_table_iter_init(&iter, earlier_event_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) - __esd_print_earlier_event(value, NULL); -} - -static void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data) -{ - earlier_item *item; - _D("event_name(%s)", event_name); - - item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name); - if (item) { - /* update earlier value */ - if (item->earlier_data != NULL) - bundle_free(item->earlier_data); - - item->earlier_data = bundle_dup(data); - } -} -#endif - -static void __esd_event_handler(char *event_name, bundle *data, void *user_data) -{ - _D("event_name(%s)", event_name); - -#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE - if (__esd_check_earlier_support(event_name)) - __esd_earlier_event_handler(event_name, data, user_data); -#endif - - if (__esd_check_event_launch_support(event_name)) - __esd_launch_event_handler(event_name, data, - false, TRUE, ROOT_USER, NULL, user_data); -} - -static void __esd_trusted_busname_remove_item(char *bus_name) -{ - GHashTableIter iter; - gpointer key; - gpointer value; - trusted_item *item; - - g_hash_table_iter_init(&iter, trusted_busname_table); - - while (g_hash_table_iter_next(&iter, &key, &value)) { - item = (trusted_item *)value; - if (item) { - if (strcmp(bus_name, item->bus_name) == 0) { - _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name); - FREE_AND_NULL(item->app_id); - FREE_AND_NULL(item->bus_name); - FREE_AND_NULL(item); - g_hash_table_iter_remove(&iter); - - __esd_trusted_busname_print_items(); - } - } - } -} - -static void __esd_filter_name_owner_changed(GDBusConnection *connection, - const gchar *sender_name, const gchar *object_path, - const gchar *interface_name, const gchar *signal_name, - GVariant *parameters, gpointer user_data) -{ - char *name = NULL; - char *old_owner = NULL; - char *new_owner = NULL; - int old_len = 0; - int new_len = 0; - - g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner); - - if (strstr(name, "event.busname.session")) { - old_len = strlen(old_owner); - new_len = strlen(new_owner); - - _D("changed name(%s), old_onwer(%s)(%d) -> new_onwer(%s)(%d)", - name, old_owner, old_len, new_owner, new_len); - - if (old_len > 0 && new_len == 0) - __esd_trusted_busname_remove_item(name); - else if (old_len == 0 && new_len > 0) - _D("new name owned"); - else - _E("not-expected name change"); - } -} - -static int __esd_dbus_name_monitor(GDBusConnection *connection) -{ - guint name_owner_changed_id = 0; - - name_owner_changed_id = g_dbus_connection_signal_subscribe(connection, - "org.freedesktop.DBus", "org.freedesktop.DBus", - "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE, - __esd_filter_name_owner_changed, NULL, NULL); - - _I("name_owner_changed_id(%d)", name_owner_changed_id); - - return ES_R_OK; -} - -static int __esd_get_user_items(uid_t uid) -{ - int ret = 0; - pkgmgrinfo_appinfo_filter_h handle = NULL; - - _I("get user items for uid(%d)", uid); - /* reset user's item */ - __esd_launch_table_remove_private_usr_items(); - - ret = pkgmgrinfo_appinfo_filter_create(&handle); - if (ret < 0) { - _E("failed to create appinfo filter"); - return ES_R_ERROR; - } - ret = pkgmgrinfo_appinfo_filter_add_string(handle, - PMINFO_APPINFO_PROP_APP_COMPONENT, "svcapp"); - if (ret < 0) { - _E("failed to add appinfo filter string"); - pkgmgrinfo_appinfo_filter_destroy(handle); - return ES_R_ERROR; - } - ret = pkgmgrinfo_appinfo_filter_add_string(handle, - PMINFO_APPINFO_PROP_APP_OPERATION, APPSVC_OPERATION_LAUNCH_ON_EVENT); - if (ret < 0) { - _E("failed to add appinfo filter string"); - pkgmgrinfo_appinfo_filter_destroy(handle); - return ES_R_ERROR; - } - ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle, - __esd_add_appinfo_handler, &uid, uid); - if (ret < 0) { - _E("appinfo filter foreach error"); - pkgmgrinfo_appinfo_filter_destroy(handle); - return ES_R_ERROR; - } - pkgmgrinfo_appinfo_filter_destroy(handle); - - __esd_launch_table_print_items(); - - return ES_R_OK; -} - -static void __esd_signal_handler(GDBusConnection *connection, - const gchar *sender_name, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data) -{ - int handle; - bundle *b; - guint64 uid = 0; - - if (!g_strcmp0(signal_name, - SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED)) { - _I("System session finished"); - - b = bundle_create(); - bundle_add_str(b, EVT_KEY_BOOT_COMPLETED, - EVT_VAL_BOOT_COMPLETED_TRUE); - eventsystem_send_system_event(SYS_EVENT_BOOT_COMPLETED, b); - bundle_free(b); - - handle = creat(ESD_BOOT_COMPLETED, 0640); - if (handle != -1) - close(handle); - } else if (!g_strcmp0(signal_name, - SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED)) { - g_variant_get(parameters, "(t)", &uid); - _I("User session finished uid : %d", (int)uid); - if ((uid_t)uid != DEFAULT_USER) - __esd_get_user_items((uid_t)uid); - } -} - -static GDBusNodeInfo *introspection_data; -static const gchar introspection_xml[] = -"" -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE -" " -" " -" " -" " -" " -" " -#endif -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -""; - -static int __esd_get_appid_by_pid_for_uid(int pid, uid_t uid, char *app_id, int buf_size) -{ - int retval = ES_R_OK; - int ret = 0; - - if (pid <= 0) { - _E("invalid pid(%d)", pid); - retval = ES_R_ERROR; - } else if (uid <= 0) { - _E("invalid uid(%d)", uid); - retval = ES_R_ERROR; - } else { - ret = aul_app_get_appid_bypid_for_uid(pid, app_id, buf_size, (uid_t)uid); - if (ret != AUL_R_OK) { - _E("failed to get appid by pid"); - retval = ES_R_ERROR; - } - _D("pid(%d)-uid(%d)-appid(%s)", pid, uid, app_id); - } - - return retval; -} - -static int __esd_get_appid_by_pid(int pid, char *app_id, int buf_size) -{ - int ret; - int fd; - char buf[128] = { 0, }; - - ret = aul_app_get_appid_bypid(pid, app_id, buf_size); - if (ret != AUL_R_OK) { - snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); - - fd = open(buf, O_RDONLY); - if (fd < 0) - return ES_R_ERROR; - - ret = read(fd, app_id, buf_size - 1); - close(fd); - - if (ret <= 0) - return ES_R_ERROR; - - app_id[ret] = '\0'; - ret = ES_R_OK; - } - - return ret; -} - -static int check_user_event_sender_valid(const char *event_name, const char *app_id) -{ - char *valid_name = NULL; - char *temp_name = NULL; - char *tmp = NULL; - int retval = ES_R_OK; - int len = 0; - int valid_name_len = 0; - - temp_name = strdup(event_name); - if (temp_name == NULL) { - _E("out of memory"); - return ES_R_ENOMEM; - } - - tmp = strrchr(temp_name, '.'); - if (tmp == NULL || strlen(tmp) == 0) { - _E("invalid event name"); - FREE_AND_NULL(temp_name); - return ES_R_EINVAL; - } - len = strlen(tmp); - if (len <= 1 || len > 128) { - _E("invalid length(%d) of user-defined name", len); - FREE_AND_NULL(temp_name); - return ES_R_EINVAL; - } - *tmp = '\0'; - - _D("app_id(%s), len(%zu)", app_id, strlen(app_id)); - - valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1; - valid_name = calloc(1, valid_name_len); - if (valid_name == NULL) { - _E("memory alloc failed"); - FREE_AND_NULL(temp_name); - return ES_R_ENOMEM; - } - snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id); - _D("valid_name(%s)", valid_name); - - if (strcmp(temp_name, valid_name) != 0) { - _E("appid misamatch"); - retval = ES_R_EINVAL; - } - - FREE_AND_NULL(temp_name); - FREE_AND_NULL(valid_name); - - return retval; -} - -static void check_sender_valid_method_call(GDBusConnection *connection, const gchar *sender, - GVariant *parameters, GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = 0; - char *event_name = NULL; - char app_id[128] = {0, }; - int event_sender_pid = 0; - uid_t sender_uid = 0; - - g_variant_get(parameters, "(i&s)", &event_sender_pid, &event_name); - _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name); - - sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { - result = ES_R_ERROR; - } else { - if (check_user_event_sender_valid(event_name, app_id) < 0) { - _E("invalid sender"); - result = ES_R_EINVAL; - } else { - result = 1; - } - } - - param = g_variant_new("(is)", result, app_id); - _D("event_name(%s), result(%d)", event_name, result); - g_dbus_method_invocation_return_value(invocation, param); -} - -static void check_send_event_valid_method_call(GDBusConnection *connection, const gchar *sender, - GVariant *parameters, GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = 0; - char *event_name = NULL; - char app_id[128] = {0, }; - int sender_pid = 0; - uid_t sender_uid = 0; - - g_variant_get(parameters, "(&s)", &event_name); - _D("event_name(%s)", event_name); - - sender_pid = __get_sender_pid(connection, sender); - sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { - result = ES_R_ERROR; - } else { - if (check_user_event_sender_valid(event_name, app_id) < 0) { - _E("invalid sender"); - result = ES_R_EINVAL; - } else { - result = 1; - } - } - - param = g_variant_new("(i)", result); - _D("event_name(%s), result(%d)", event_name, result); - g_dbus_method_invocation_return_value(invocation, param); -} - -static void get_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender, - GVariant *parameters, GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = 0; - GVariantBuilder *builder = NULL; - GHashTableIter iter; - gpointer key, value; - char *event_name = NULL; - char app_id[128] = {0, }; - int sender_pid = 0; - uid_t sender_uid = 0; - int ret = 0; - uid_t uid = 0; - char *_appid = NULL; - char *_busname = NULL; - trusted_item *item; - - g_variant_get(parameters, "(&s)", &event_name); - _D("event_name(%s)", event_name); - - sender_pid = __get_sender_pid(connection, sender); - sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { - result = ES_R_ERROR; - } else { - builder = g_variant_builder_new(G_VARIANT_TYPE("as")); - - g_hash_table_iter_init(&iter, trusted_busname_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - item = (trusted_item *)value; - uid = item->uid; - _appid = item->app_id; - _busname = item->bus_name; - - if (uid != GLOBAL_USER && uid != sender_uid) - continue; - - ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id); - if (ret == ES_R_OK) - g_variant_builder_add(builder, "s", _busname); - } - - result = 1; - } - - param = g_variant_new("(ias)", result, builder); - _D("result(%d)", result); - g_dbus_method_invocation_return_value(invocation, param); - if (builder) - g_variant_builder_unref(builder); -} - -static void setup_trusted_peer_method_call(GDBusConnection *connection, const gchar *sender, - GVariant *parameters, GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = 0; - char *event_name = NULL; - char *destination_name = NULL; - char app_id[128] = {0, }; - int sender_pid = 0; - uid_t sender_uid = 0; - int ret = 0; - - g_variant_get(parameters, "(&s&s)", &event_name, &destination_name); - _D("event_name(%s), destination_name(%s)", event_name, destination_name); - - if (destination_name && destination_name[0] != '\0') { - sender_pid = __get_sender_pid(connection, sender); - sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { - result = ES_R_ERROR; - } else { - ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name, - sender_pid); - if (ret < 0) { - _E("failed to add trusted busname item"); - result = ES_R_ERROR; - } else { - result = 1; - } - } - } else { - _E("invalid destination name"); - result = ES_R_ERROR; - } - - param = g_variant_new("(i)", result); - _D("event_name(%s), result(%d)", event_name, result); - g_dbus_method_invocation_return_value(invocation, param); -} - -static void check_privilege_valid_method_call(GDBusConnection *connection, const gchar *sender, - GVariant *parameters, GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = 0; - char *event_name = NULL; - char *privilege_name = NULL; - char app_id[128] = {0, }; - int sender_pid = 0; - uid_t sender_uid = 0; - char *client = NULL; - char *session = NULL; - char *user = NULL; - int ret = 0; - - g_variant_get(parameters, "(&s)", &event_name); - __esd_check_privilege_name(event_name, &privilege_name); - _D("event_name(%s), privilege_name(%s)", event_name, privilege_name); - - if (privilege_name) { - sender_pid = __get_sender_pid(connection, sender); - sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { - result = ES_R_ERROR; - } else { - ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client); - if (ret != CYNARA_API_SUCCESS) { - _E("failed to get client"); - result = ES_R_EINVAL; - goto out; - } - - ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user); - if (ret != CYNARA_API_SUCCESS) { - _E("failed to get user"); - result = ES_R_EINVAL; - goto out; - } - - session = cynara_session_from_pid(sender_pid); - if (session == NULL) { - _E("failed to get session"); - result = ES_R_EINVAL; - goto out; - } - - _D("app_id(%s), client(%s), session(%s), user(%s)", app_id, client, session, user); - if (__esd_check_valid_privilege_by_cynara(app_id, client, session, user, privilege_name)) - result = 1; - else - result = ES_R_EINVAL; - } - } else { - result = 1; - } - -out: - g_free(client); - g_free(user); - g_free(session); - param = g_variant_new("(i)", result); - _D("event_name(%s), result(%d)", event_name, result); - g_dbus_method_invocation_return_value(invocation, param); -} - -#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE -static void get_earlier_data_method_call(GVariant *parameters, GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = ES_R_ERROR; - char *event_name = NULL; - bundle *b = NULL; - bundle_raw *raw = NULL; - int len = 0; - earlier_item *item; - - g_variant_get(parameters, "(&s)", &event_name); - _D("event_name(%s)", event_name); - - item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name); - if (item != NULL) { - if (item->earlier_data) { - b = bundle_dup(item->earlier_data); - bundle_add_str(b, "is_earlier_data", "true"); - result = ES_R_OK; - } - } - - if (result == ES_R_ERROR) - b = bundle_create(); - - bundle_encode(b, &raw, &len); - bundle_free(b); - - param = g_variant_new("(iis)", result, len, raw); - - _D("result(%d), len(%d)", result, len); - g_dbus_method_invocation_return_value(invocation, param); - - bundle_free_encoded_rawdata(&raw); -} -#endif - -static void keep_last_data_method_call(GDBusConnection *connection, - const gchar *sender, GVariant *parameters, - GDBusMethodInvocation *invocation) -{ - GVariant *param; - int result = ES_R_OK; - char *event_name; - char *own_name; - char *key; - char app_id[128]; - int sender_pid; - uid_t sender_uid; - struct __last_event_item *item; - - g_variant_get(parameters, "(&s&s)", &event_name, &own_name); - - if (!event_name || !own_name) { - result = ES_R_ERROR; - _E("invalid event_name and own_name"); - goto out; - } - - sender_pid = __get_sender_pid(connection, sender); - sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, - sizeof(app_id)) < 0) { - _E("failed to get appid by pid"); - result = ES_R_ERROR; - goto out; - } - - key = (char *)malloc(sizeof(event_name) + 10); - if (!key) { - result = ES_R_ENOMEM; - _E("out of memory"); - goto out; - } - - snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid); - item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table, - key); - if (!item) { - item = calloc(1, sizeof(*item)); - if (!item) { - result = ES_R_ERROR; - goto out; - } - item->key = key; - item->event_name = strdup(event_name); - item->own_name = strdup(own_name); - item->uid = sender_uid; - item->app_id = strdup(app_id); - g_hash_table_insert(user_last_event_table, - item->key, item); - } else { - free(item->own_name); - item->own_name = strdup(own_name); - } - -out: - param = g_variant_new("(i)", result); - - g_dbus_method_invocation_return_value(invocation, param); -} - -static void check_last_data_method_call(GDBusConnection *connection, - const gchar *sender, GVariant *parameters, - GDBusMethodInvocation *invocation) -{ - GVariant *param; - int result = ES_R_OK; - char *event_name; - char *own_name; - char *key; - char app_id[128]; - int sender_pid; - uid_t sender_uid; - struct __last_event_item *item; - - g_variant_get(parameters, "(&s&s)", &event_name, &own_name); - - if (!event_name || !own_name) { - result = ES_R_ERROR; - _E("invalid event_name and own_name"); - goto out; - } - - sender_pid = __get_sender_pid(connection, sender); - sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, - sizeof(app_id)) < 0) { - result = ES_R_ERROR; - _E("failed to get appid by pid"); - goto out; - } - - key = (char *)malloc(sizeof(event_name) + 10); - if (!key) { - result = ES_R_ENOMEM; - _E("out of memory"); - goto out; - } - - snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid); - item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table, - key); - free(key); - if (item) { - GVariant *gv; - bundle *b; - bundle_raw *raw; - int len; - int ret; - GError *error = NULL; - - b = bundle_create(); - if (!b) { - result = ES_R_ERROR; - goto out; - } - bundle_add_str(b, EVT_KEY_KEPT_EVENT_NAME, event_name); - bundle_add_str(b, EVT_KEY_KEPT_OWN_NAME, own_name); - if (__esd_check_certificate_match(item->uid, item->app_id, - sender_uid, app_id) == ES_R_OK) - bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "true"); - else - bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "false"); - - bundle_encode(b, &raw, &len); - gv = g_variant_new("(us)", len, raw); - ret = g_dbus_connection_emit_signal(connection, - item->own_name, - SYS_EVENT_OBJ_PATH, - SYS_EVENT_NAME_PREFIX, - REQUEST_LAST_DATA, - gv, - &error); - if (ret == FALSE) { - _E("Unable to emit signal: %s", error->message); - g_error_free(error); - } - bundle_free_encoded_rawdata(&raw); - bundle_free(b); - } - -out: - param = g_variant_new("(i)", result); - - g_dbus_method_invocation_return_value(invocation, param); -} - -static void launch_on_event_from_userevent(GDBusConnection *connection, - const gchar *sender, GVariant *parameters, - GDBusMethodInvocation *invocation) -{ - GVariant *param; - int result = ES_R_OK; - int len; - gboolean trusted; - int sender_pid; - uid_t sender_uid; - char *event_name; - char app_id[128]; - char *buf; - bundle *b; - - g_variant_get(parameters, "(&s&sib)", &event_name, &buf, &len, &trusted); - - if (!event_name) { - result = ES_R_ERROR; - _E("invalid event_name"); - goto out; - } - - sender_pid = __get_sender_pid(connection, sender); - sender_uid = (uid_t)__get_sender_uid(connection, sender); - if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, - sizeof(app_id)) < 0) { - _E("failed to get appid by pid"); - result = ES_R_ERROR; - goto out; - } - - b = bundle_decode((bundle_raw *)buf, len); - if (b == NULL) { - _E("Out of memory"); - result = ES_R_ENOMEM; - goto out; - } - - __esd_launch_event_handler(event_name, b, true, trusted, - sender_uid, app_id, NULL); - - bundle_free(b); - -out: - param = g_variant_new("(i)", result); - - g_dbus_method_invocation_return_value(invocation, param); -} - -static void get_uuid_method_call(GDBusConnection *connection, - const gchar *sender, GVariant *parameters, - GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = ES_R_OK; - char *uuid; - char app_id[128] = { 0, }; - int sender_pid; - - sender_pid = __get_sender_pid(connection, sender); - if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) { - _E("failed to get appid by pid"); - result = ES_R_ERROR; - goto out; - } - - if (esd_cion_get_uuid_with_generate(app_id, &uuid) == 0) { - param = g_variant_new("(is)", result, uuid); - free(uuid); - } else { - result = ES_R_ERROR; - } - -out: - if (param == NULL) - param = g_variant_new("(is)", result, ""); - - g_dbus_method_invocation_return_value(invocation, param); -} - -static void set_display_name_method_call(GDBusConnection *connection, - const gchar *sender, GVariant *parameters, - GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = ES_R_OK; - char app_id[128] = { 0, }; - int sender_pid; - char *display_name = NULL; - char *service_name = NULL; - - sender_pid = __get_sender_pid(connection, sender); - if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) { - _E("failed to get appid by pid"); - result = ES_R_ERROR; - goto out; - } - - g_variant_get(parameters, "(&s&s)", &service_name, &display_name); - - if (esd_cion_set_display_name(app_id, service_name, display_name) != 0) - result = ES_R_ERROR; - -out: - param = g_variant_new("(i)", result); - g_dbus_method_invocation_return_value(invocation, param); -} - -static void get_display_name_method_call(GDBusConnection *connection, - const gchar *sender, GVariant *parameters, - GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = ES_R_OK; - char app_id[128] = { 0, }; - int sender_pid; - char *service_name = NULL; - char *display_name = NULL; - - sender_pid = __get_sender_pid(connection, sender); - if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) { - _E("failed to get appid by pid"); - result = ES_R_ERROR; - goto out; - } - - g_variant_get(parameters, "(&s)", &service_name); - - if (esd_cion_get_display_name(app_id, service_name, &display_name) == 0) { - if (display_name != NULL) { - param = g_variant_new("(is)", result, display_name); - free(display_name); - } else { - goto out; - } - } else { - result = ES_R_ERROR; - } - -out: - if (param == NULL) - param = g_variant_new("(is)", result, ""); - - g_dbus_method_invocation_return_value(invocation, param); -} - -static void set_enabled_method_call(GDBusConnection *connection, - const gchar *sender, GVariant *parameters, - GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = ES_R_OK; - char app_id[128] = { 0, }; - int sender_pid; - gboolean enabled; - char *service_name = NULL; - - sender_pid = __get_sender_pid(connection, sender); - if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) { - _E("failed to get appid by pid"); - result = ES_R_ERROR; - goto out; - } - - g_variant_get(parameters, "(&sb)", &service_name, &enabled); - - if (esd_cion_set_enabled(app_id, service_name, (bool)enabled) != 0) - result = ES_R_ERROR; - -out: - param = g_variant_new("(i)", result); - g_dbus_method_invocation_return_value(invocation, param); -} - -static void get_enabled_method_call(GDBusConnection *connection, - const gchar *sender, GVariant *parameters, - GDBusMethodInvocation *invocation) -{ - GVariant *param = NULL; - int result = ES_R_OK; - char app_id[128] = { 0, }; - int sender_pid; - char *service_name = NULL; - int enabled; - - sender_pid = __get_sender_pid(connection, sender); - if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) { - _E("failed to get appid by pid"); - result = ES_R_ERROR; - goto out; - } - - g_variant_get(parameters, "(&s)", &service_name); - - if (esd_cion_get_enabled(app_id, service_name, &enabled) == 0) - param = g_variant_new("(ib)", result, (bool)enabled); - else - result = ES_R_ERROR; - -out: - if (param == NULL) - param = g_variant_new("(ib)", result, false); - - g_dbus_method_invocation_return_value(invocation, param); -} - -static void handle_method_call(GDBusConnection *connection, - const gchar *sender, const gchar *object_path, - const gchar *interface_name, const gchar *method_name, - GVariant *parameters, GDBusMethodInvocation *invocation, - gpointer user_data) -{ - if (g_strcmp0(method_name, "CheckSenderValidation") == 0) { - check_sender_valid_method_call(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "GetTrustedPeerList") == 0) { - get_trusted_peer_method_call(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "SetupTrustedPeer") == 0) { - setup_trusted_peer_method_call(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "CheckPrivilegeValidation") == 0) { - check_privilege_valid_method_call(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "CheckUserSendValidation") == 0) { - check_send_event_valid_method_call(connection, sender, parameters, invocation); -#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE - } else if (g_strcmp0(method_name, "GetEarlierData") == 0) { - get_earlier_data_method_call(parameters, invocation); -#endif - } else if (g_strcmp0(method_name, "KeepLastData") == 0) { - keep_last_data_method_call(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "CheckLastData") == 0) { - check_last_data_method_call(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "LaunchOnEventFromUserEvent") == 0) { - launch_on_event_from_userevent(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "CionGetUuid") == 0) { - get_uuid_method_call(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "CionSetDisplayName") == 0) { - set_display_name_method_call(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "CionGetDisplayName") == 0) { - get_display_name_method_call(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "CionSetEnabled") == 0) { - set_enabled_method_call(connection, sender, parameters, invocation); - } else if (g_strcmp0(method_name, "CionGetEnabled") == 0) { - get_enabled_method_call(connection, sender, parameters, invocation); - } -} - -static const GDBusInterfaceVTable interface_vtable = { - handle_method_call, - NULL, - NULL -}; - -static void __esd_on_bus_acquired(GDBusConnection *connection, - const gchar *name, gpointer user_data) -{ - _I("bus acquired(%s)", name); - - guint reg_id = 0; - guint boot_id = 0; - guint user_boot_id = 0; - GError *error = NULL; - - reg_id = g_dbus_connection_register_object(connection, - ESD_OBJECT_PATH, - introspection_data->interfaces[0], - &interface_vtable, - NULL, NULL, &error); - if (reg_id == 0) { - _E("g_dbus_connection_register_object error(%s)", error->message); - g_error_free(error); - } - - boot_id = g_dbus_connection_signal_subscribe(connection, - NULL, - SYSTEMD_DBUS_IFACE_MANAGER, - SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED, - SYSTEMD_DBUS_PATH, - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - __esd_signal_handler, - NULL, - NULL); - - if (boot_id == 0) - _E("g_dbus_connection_signal_subscribe() is failed."); - - user_boot_id = g_dbus_connection_signal_subscribe(connection, - NULL, - SYSTEMD_DBUS_IFACE_MANAGER, - SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED, - SYSTEMD_DBUS_PATH, - NULL, - G_DBUS_SIGNAL_FLAGS_NONE, - __esd_signal_handler, - NULL, - NULL); - - if (user_boot_id == 0) - _E("g_dbus_connection_signal_subscribe() is failed."); -} - -static void __esd_on_name_acquired(GDBusConnection *connection, - const gchar *name, gpointer user_data) -{ - bundle *b; - - __esd_check_trusted_events(connection, "ListNames"); - __esd_check_trusted_events(connection, "ListActivatableNames"); - - b = bundle_create(); - bundle_add_str(b, EVT_KEY_ESD_STATUS, EVT_VAL_ESD_STARTED); - eventsystem_send_system_event(SYS_EVENT_ESD_STATUS, b); - bundle_free(b); - - __esd_register_vconf_callbacks(); - - __esd_trusted_busname_print_items(); - - __esd_get_user_items(DEFAULT_USER); - - __esd_dbus_name_monitor(connection); -} - -static void __esd_on_name_lost(GDBusConnection *connection, - const gchar *name, gpointer user_data) -{ -} - -static int __esd_before_loop(void) -{ - int ret = 0; - GError *error = NULL; - guint owner_id = 0; - -#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE - guint subscription_id = 0; - int i; - int size; - char *event_name; - int fd; - int val; - int status; - int charger_status; - int charge_now; - earlier_item *item; - - earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal); - user_last_event_table = g_hash_table_new_full(g_str_hash, - g_str_equal, NULL, (GDestroyNotify)free_saved_event); - - _I("register events for earlier_data"); - size = sizeof(earlier_event_list)/sizeof(*earlier_event_list); - for (i = 0; i < size; i++) { - event_name = (char *)earlier_event_list[i]; - _I("event_name(%s)", event_name); - - item = calloc(1, sizeof(earlier_item)); - if (item == NULL) { - _E("memery alloc failed"); - return ES_R_ENOMEM; - } - item->event_name = strdup(event_name); - if (item->event_name == NULL) { - _E("out of memory"); - free(item); - return ES_R_ENOMEM; - } - - /* set initial data */ - if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) { - fd = open(ESD_BOOT_COMPLETED, O_RDONLY); - if (fd < 0) { - _D("open file error(%d)", fd); - } else { - item->earlier_data = bundle_create(); - bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED, - EVT_VAL_BOOT_COMPLETED_TRUE); - close(fd); - } - } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) { - ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val); - if (ret != VCONF_OK) { - _E("failed to get power_off status (%d)", ret); - } else { - if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || - val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) { - /* power-off requested */ - item->earlier_data = bundle_create(); - bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN, - EVT_VAL_SYSTEM_SHUTDOWN_TRUE); - } - } - } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) { - ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status); - if (ret != VCONF_OK) { - _E("failed to get low_memory status (%d)", ret); - } else { - item->earlier_data = bundle_create(); - if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) - bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY, - EVT_VAL_MEMORY_SOFT_WARNING); - else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING) - bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY, - EVT_VAL_MEMORY_HARD_WARNING); - else - bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY, - EVT_VAL_MEMORY_NORMAL); - } - } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) { - ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status); - if (ret != VCONF_OK) { - _E("failed to get charger_status (%d)", ret); - } else { - ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now); - if (ret != VCONF_OK) - _E("failed to get charge_now (%d)", ret); - } - - if (ret == VCONF_OK) { - item->earlier_data = bundle_create(); - if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) { - if (charge_now == 0) { - bundle_add_str(item->earlier_data, - EVT_KEY_BATTERY_CHARGER_STATUS, - EVT_VAL_BATTERY_CHARGER_DISCHARGING); - } else { - bundle_add_str(item->earlier_data, - EVT_KEY_BATTERY_CHARGER_STATUS, - EVT_VAL_BATTERY_CHARGER_CHARGING); - } - } else { - bundle_add_str(item->earlier_data, - EVT_KEY_BATTERY_CHARGER_STATUS, - EVT_VAL_BATTERY_CHARGER_DISCONNECTED); - } - } - } - - eventsystem_register_event(event_name, &subscription_id, - (eventsystem_handler)__esd_event_handler, NULL); - if (subscription_id == 0) { - _E("signal subscription error, event_name(%s)", event_name); - if (item->earlier_data) - bundle_free(item->earlier_data); - free(item->event_name); - free(item); - - return ES_R_ERROR; - } else { - item->reg_id = subscription_id; - } - - g_hash_table_insert(earlier_event_table, event_name, item); - } - - __esd_earlier_table_print_items(); -#endif - - event_launch_table = g_hash_table_new(g_str_hash, g_str_equal); - trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal); - - /* gdbus setup for method call */ - introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error); - if (!introspection_data) { - _E("g_dbus_node_info_new_for_xml error(%s)", error->message); - g_error_free(error); - return ES_R_ERROR; - } - - owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, - ESD_BUS_NAME, - G_BUS_NAME_OWNER_FLAGS_NONE, - __esd_on_bus_acquired, - __esd_on_name_acquired, - __esd_on_name_lost, - NULL, NULL); - if (!owner_id) { - _E("g_bus_own_name error"); - g_dbus_node_info_unref(introspection_data); - return ES_R_ERROR; - } - - _I("esd before_loop done"); - - return ES_R_OK; -} - -static void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event) -{ - pkg_event->type = UNKNOWN; - if (pkg_event->pkgid) { - free(pkg_event->pkgid); - pkg_event->pkgid = NULL; - } -} - -static int __esd_appcontrol_cb(const char *operation, - const char *uri, const char *mime, void *data) -{ - esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data; - char *appid = NULL; - char *pkgid = NULL; - char *event_name = NULL; - uid_t uid = 0; - - if (cb_data == NULL) { - _E("invalid data"); - return 0; - } - appid = cb_data->appid; - pkgid = cb_data->pkgid; - uid = cb_data->uid; - - _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)", - uid, appid, pkgid, operation, uri, mime); - - if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) { - if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX, strlen(SYSTEM_EVENT_NAME_PREFIX))) { - event_name = strdup(&uri[8]); - if (event_name) { - _D("appid(%s), event_name(%s)", appid, event_name); - if (!__esd_check_event_launch_support(event_name)) - _E("failed to add item (not support event)"); - else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name)) - _E("failed to add item (no privilege)"); - else if (__esd_add_launch_item(uid, event_name, appid, pkgid)) - _E("failed to add item"); - - } else { - _E("out of memory"); - } - } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX, strlen(USER_EVENT_NAME_PREFIX))) { - event_name = strdup(uri); - if (event_name) { - _D("appid(%s), event_name(%s)", appid, event_name); - if (__esd_check_platform_cert(pkgid, uid)) { - if (__esd_add_launch_item(uid, event_name, appid, pkgid)) - _E("failed to add item"); - } - } else { - _E("out of memory"); - } - } - FREE_AND_NULL(event_name); - } - - return 0; -} - -static int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data) -{ - char *appid = NULL; - char *pkgid = NULL; - int ret = 0; - uid_t *p_uid = NULL; - - if (data == NULL) { - _E("invalid data"); - return ES_R_ERROR; - } - - p_uid = (uid_t *)data; - - ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid); - if (ret < 0) { - _E("failed to get appid"); - return ES_R_ERROR; - } - - ret = pkgmgrinfo_appinfo_get_appid(handle, &appid); - if (ret < 0) { - _E("failed to get appid"); - return ES_R_ERROR; - } - - esd_appctrl_cb_data *cb_data = calloc(1, sizeof(esd_appctrl_cb_data)); - - if (cb_data == NULL) { - _E("memory alloc failed"); - return ES_R_ENOMEM; - } - cb_data->appid = strdup(appid); - if (cb_data->appid == NULL) { - _E("out_of_memory"); - FREE_AND_NULL(cb_data); - return ES_R_ENOMEM; - } - cb_data->pkgid = strdup(pkgid); - if (cb_data->pkgid == NULL) { - _E("out_of_memory"); - FREE_AND_NULL(cb_data->appid); - FREE_AND_NULL(cb_data); - return ES_R_ENOMEM; - } - cb_data->uid = *p_uid; - - ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle, - (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data); - - FREE_AND_NULL(cb_data->pkgid); - FREE_AND_NULL(cb_data->appid); - FREE_AND_NULL(cb_data); - - if (ret < 0) { - _E("failed to get appcontrol info"); - return ES_R_ERROR; - } - - return ES_R_OK; -} - -static int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id, - const char *pkg_type, const char *pkgid, const char *key, - const char *val, const void *pmsg, void *data) -{ - esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data; - pkgmgrinfo_pkginfo_h handle = NULL; - int ret = 0; - - _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)", - target_uid, req_id, pkg_type, pkgid, key, val); - - if (strncmp(key, "start", strlen(key)) == 0) { - if (strcmp(val, "install") == 0) { - _D("install start"); - pkg_event->type = INSTALL; - } else if (strcmp(val, "uninstall") == 0) { - _D("unistall start"); - pkg_event->type = UNINSTALL; - } else if (strcmp(val, "update") == 0) { - _D("update start"); - pkg_event->type = UPDATE; - } else { - _D("val(%s) start", val); - __esd_pkgmgr_event_free(pkg_event); - } - } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) { - if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) { - _D("install end (ok)"); - ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle); - if (ret < 0) { - _E("failed to get pkginfo"); - __esd_pkgmgr_event_free(pkg_event); - return 0; - } - ret = pkgmgrinfo_appinfo_get_usr_list(handle, - PMINFO_SVC_APP, __esd_add_appinfo_handler, &target_uid, target_uid); - if (ret < 0) { - _E("failed to get appinfo"); - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - __esd_pkgmgr_event_free(pkg_event); - return 0; - } - ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - if (ret < 0) { - _E("failed to destroy pkginfo"); - __esd_pkgmgr_event_free(pkg_event); - return 0; - } - } else if (pkg_event->type == UNINSTALL) { - _D("uninstall end (ok)"); - __esd_launch_table_remove_items(target_uid, pkgid); - __esd_launch_table_print_items(); - } - __esd_pkgmgr_event_free(pkg_event); - } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) { - _E("pkg_event(%d) falied", pkg_event->type); - __esd_pkgmgr_event_free(pkg_event); - } else { - if (strcmp(key, "install_percent") != 0) - __esd_pkgmgr_event_free(pkg_event); - } - - return 0; -} - -static int __esd_init() -{ - int req_id = 0; - int ret = 0; - pkgmgr_client *client; - esd_pkgmgr_event *pkg_event; - -#if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36) - g_type_init(); -#endif - __esd_init_cynara(); - - client = pkgmgr_client_new(PC_LISTENING); - if (client == NULL) { - _E("set pkgmgr client failed"); - __esd_finish_cynara(); - return ES_R_ERROR; - } - - pkg_event = calloc(1, sizeof(esd_pkgmgr_event)); - if (pkg_event == NULL) { - _E("memory alloc failed"); - ret = pkgmgr_client_free(client); - if (ret != PKGMGR_R_OK) - _E("pkgmgr_client_free failed(%d)", ret); - __esd_finish_cynara(); - return ES_R_ENOMEM; - } - - req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event); - if (req_id < 0) { - _E("pkgmgr client listen failed"); - ret = pkgmgr_client_free(client); - if (ret != PKGMGR_R_OK) - _E("pkgmgr_client_free failed(%d)", ret); - free(pkg_event); - __esd_finish_cynara(); - return ES_R_ERROR; - } - - s_info.client = client; - - _I("esd init done"); - - return 0; -} - -static void __esd_remove_esd_list_item(gpointer data, gpointer user_data) -{ - esd_list_item_s *item = (esd_list_item_s *)data; - - free(item->app_id); - free(item->pkg_id); -} - -static void __esd_finalize(void) -{ - gpointer key; - gpointer value; - GHashTableIter iter; - trusted_item *item; - event_launch_item *el_item; - int ret = 0; -#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE - earlier_item *er_item; -#endif - - _D("esd finalize"); - - if (trusted_busname_table) { - g_hash_table_iter_init(&iter, trusted_busname_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - item = (trusted_item *)value; - if (item) { - free(item->app_id); - free(item->bus_name); - free(item); - } else { - _E("item is null"); - } - g_hash_table_iter_remove(&iter); - } - g_hash_table_unref(trusted_busname_table); - } - -#ifdef APPFW_EVENT_SYSTEM_EARLIER_FEATURE - if (earlier_event_table) { - g_hash_table_iter_init(&iter, earlier_event_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - er_item = (earlier_item *)value; - if (er_item) { - eventsystem_unregister_event(er_item->reg_id); - free(er_item->event_name); - bundle_free(er_item->earlier_data); - free(er_item); - } else { - _E("ealier item is NULL"); - } - g_hash_table_iter_remove(&iter); - } - g_hash_table_unref(earlier_event_table); - } - - g_hash_table_destroy(user_last_event_table); -#endif - - if (event_launch_table) { - g_hash_table_iter_init(&iter, event_launch_table); - while (g_hash_table_iter_next(&iter, &key, &value)) { - el_item = (event_launch_item *)value; - if (el_item) { - eventsystem_unregister_event(el_item->reg_id); - free(el_item->event_name); - g_list_foreach(el_item->app_list_evtlaunch, - __esd_remove_esd_list_item, NULL); - g_list_free(el_item->app_list_evtlaunch); - free(el_item); - } else { - _E("item is NULL"); - } - g_hash_table_iter_remove(&iter); - } - g_hash_table_unref(event_launch_table); - } - - if (introspection_data) - g_dbus_node_info_unref(introspection_data); - - if (s_info.client) { - ret = pkgmgr_client_free(s_info.client); - if (ret != PKGMGR_R_OK) - _E("pkgmgr_client_free failed(%d)", ret); - } - - __esd_finish_cynara(); - - _D("esd finalize end"); -} - -int main(int argc, char *argv[]) -{ - GMainLoop *mainloop; - _I("event system daemon : main()"); - - mainloop = g_main_loop_new(NULL, FALSE); - if (mainloop == NULL) { - _E("out of memory"); - return ES_R_ERROR; - } - - if (__esd_init() != 0) { - _E("ESD Initialization failed!"); - g_main_loop_unref(mainloop); - return ES_R_ERROR; - } - - if (_esd_cion_init() != 0) - _E("ESD Cion Initialization failed!"); - - if (__esd_before_loop() < 0) { - _E("ESD failed!"); - __esd_finalize(); - g_main_loop_unref(mainloop); - return ES_R_ERROR; - } - - if (esd_cion_db_init() < 0) - _E("db init failed!"); - - g_main_loop_run(mainloop); - - _E("shutdown"); - - __esd_finalize(); - - g_main_loop_unref(mainloop); - - return 0; -} diff --git a/src/esd_system_event.c b/src/esd_system_event.c deleted file mode 100644 index 12fd9ee..0000000 --- a/src/esd_system_event.c +++ /dev/null @@ -1,576 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "eventsystem_daemon.h" - -/* table item : sent system-event by esd */ -static GHashTable *esd_sent_table; - -typedef struct __esd_sent_table_item { - char *event_name; - bundle *event_data; -} esd_sent_item; - -struct esd_vconf_handler { - const char *key; - void (*esd_vconfcb_fn) (keynode_t *node, void *user_data); -}; - -static int __esd_event_data_compare(bundle *b1, bundle *b2, const char *key) -{ - int ret = 0; - int tmp1 = 0; - int tmp2 = 0; - char *str1 = NULL; - char *str2 = NULL; - - if (bundle_get_count(b1) == bundle_get_count(b2)) { - tmp1 = bundle_get_str(b1, key, &str1); - tmp2 = bundle_get_str(b2, key, &str2); - if (tmp1 == BUNDLE_ERROR_NONE && tmp2 == BUNDLE_ERROR_NONE) { - if (strcmp(str1, str2) != 0) { - _D("new event_data : value check"); - ret = 1; - } - } - } else { - _D("new event_data : bundle_count check"); - ret = 1; - } - - if (ret == 0) - _D("same event_data"); - - return ret; -} - -static int __esd_send_system_event(const char *event_name, bundle *b, const char *key) -{ - int ret = ES_R_OK; - esd_sent_item *item = - (esd_sent_item *)g_hash_table_lookup(esd_sent_table, event_name); - - if (item && __esd_event_data_compare(item->event_data, b, key) == 0) { - _D("skip send: same with previous data"); - } else { - ret = eventsystem_send_system_event(event_name, b); - if (ret != ES_R_OK) { - _E("failed to send event"); - goto out; - } - - if (item) { - bundle_free(item->event_data); - item->event_data = bundle_dup(b); - } else { - item = calloc(1, sizeof(esd_sent_item)); - if (item == NULL) { - _E("memory alloc failed"); - ret = ES_R_ERROR; - goto out; - } - item->event_name = strdup(event_name); - if (item->event_name == NULL) { - _E("out of memory"); - FREE_AND_NULL(item); - ret = ES_R_ERROR; - goto out; - } - item->event_data = bundle_dup(b); - } - - g_hash_table_insert(esd_sent_table, item->event_name, item); - } - -out: - return ret; -} - -static void __esd_vconfcb_location_use_mylocation(keynode_t *node, void *user_data) -{ - int ret = 0; - int enabled = 0; - bundle *b = NULL; - const char *key = NULL; - const char *val = NULL; - - _D("vconfcb called"); - - ret = vconf_get_int(VCONFKEY_LOCATION_USE_MY_LOCATION, &enabled); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - key = EVT_KEY_LOCATION_ENABLE_STATE; - - if (enabled) - val = EVT_VAL_LOCATION_ENABLED; - else - val = EVT_VAL_LOCATION_DISABLED; - - b = bundle_create(); - bundle_add_str(b, key, val); - - if (__esd_send_system_event(SYS_EVENT_LOCATION_ENABLE_STATE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); -} - -static void __esd_vconfcb_location_enabled(keynode_t *node, void *user_data) -{ - int ret = 0; - int enabled = 0; - bundle *b = NULL; - const char *key = NULL; - const char *val = NULL; - - _D("vconfcb called"); - - ret = vconf_get_int(VCONFKEY_LOCATION_ENABLED, &enabled); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - key = EVT_KEY_GPS_ENABLE_STATE; - - if (enabled) - val = EVT_VAL_GPS_ENABLED; - else - val = EVT_VAL_GPS_DISABLED; - - b = bundle_create(); - bundle_add_str(b, key, val); - - if (__esd_send_system_event(SYS_EVENT_GPS_ENABLE_STATE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); -} - -static void __esd_vconfcb_location_network_enabled(keynode_t *node, void *user_data) -{ - int ret = 0; - int enabled = 0; - bundle *b = NULL; - const char *key = NULL; - const char *val = NULL; - - _D("vconfcb called"); - - ret = vconf_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &enabled); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - key = EVT_KEY_NPS_ENABLE_STATE; - - if (enabled) - val = EVT_VAL_NPS_ENABLED; - else - val = EVT_VAL_NPS_DISABLED; - - b = bundle_create(); - bundle_add_str(b, key, val); - - if (__esd_send_system_event(SYS_EVENT_NPS_ENABLE_STATE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); -} - -static void __esd_vconfcb_language_set(keynode_t *node, void *user_data) -{ - char *str = 0; - bundle *b = NULL; - const char *key = NULL; - - _D("vconfcb called"); - - str = vconf_get_str(VCONFKEY_LANGSET); - if (str == NULL) { - _E("failed to get vconf str"); - return; - } - - key = EVT_KEY_LANGUAGE_SET; - - b = bundle_create(); - bundle_add_str(b, key, str); - - if (__esd_send_system_event(SYS_EVENT_LANGUAGE_SET, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); - if (str) - free(str); -} - -static void __esd_vconfcb_hour_format(keynode_t *node, void *user_data) -{ - int ret = 0; - int hours = 0; - bundle *b = NULL; - const char *key = NULL; - const char *val = NULL; - - _D("vconfcb called"); - - ret = vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, &hours); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - key = EVT_KEY_HOUR_FORMAT; - - if (hours == VCONFKEY_TIME_FORMAT_24) - val = EVT_VAL_HOURFORMAT_24; - else - val = EVT_VAL_HOURFORMAT_12; - - b = bundle_create(); - bundle_add_str(b, key, val); - - if (__esd_send_system_event(SYS_EVENT_HOUR_FORMAT, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); -} - -static void __esd_vconfcb_region_format(keynode_t *node, void *user_data) -{ - char *str = 0; - bundle *b = NULL; - const char *key = NULL; - - _D("vconfcb called"); - - str = vconf_get_str(VCONFKEY_REGIONFORMAT); - if (str == NULL) { - _E("failed to get vconf str"); - return; - } - - key = EVT_KEY_REGION_FORMAT; - - b = bundle_create(); - bundle_add_str(b, key, str); - - if (__esd_send_system_event(SYS_EVENT_REGION_FORMAT, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); - if (str) - free(str); -} - -static void __esd_vconfcb_vibration_status(keynode_t *node, void *user_data) -{ - int ret = 0; - int vibration_on = 0; - int sound_on = 0; - bundle *b = NULL; - char *key = NULL; - char *val = NULL; - - _D("vconfcb called"); - - ret = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibration_on); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - ret = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound_on); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - if (vibration_on) { - key = EVT_KEY_VIBRATION_STATE; - val = EVT_VAL_VIBRATION_ON; - b = bundle_create(); - bundle_add_str(b, key, val); - if (__esd_send_system_event(SYS_EVENT_VIBRATION_STATE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); - - key = EVT_KEY_SILENT_MODE; - val = EVT_VAL_SILENTMODE_OFF; - b = bundle_create(); - bundle_add_str(b, key, val); - if (__esd_send_system_event(SYS_EVENT_SILENT_MODE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); - } else { - key = EVT_KEY_VIBRATION_STATE; - val = EVT_VAL_VIBRATION_OFF; - b = bundle_create(); - bundle_add_str(b, key, val); - if (__esd_send_system_event(SYS_EVENT_VIBRATION_STATE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); - - if (!sound_on) { - key = EVT_KEY_SILENT_MODE; - val = EVT_VAL_SILENTMODE_ON; - b = bundle_create(); - bundle_add_str(b, key, val); - if (__esd_send_system_event(SYS_EVENT_SILENT_MODE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); - } - } -} - -static void __esd_vconfcb_sound_status(keynode_t *node, void *user_data) -{ - int ret = 0; - int vibration_on = 0; - int sound_on = 0; - bundle *b = NULL; - char *key = NULL; - char *val = NULL; - - _D("vconfcb called"); - - ret = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibration_on); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - ret = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound_on); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - if (sound_on) { - key = EVT_KEY_VIBRATION_STATE; - val = EVT_VAL_VIBRATION_OFF; - b = bundle_create(); - bundle_add_str(b, key, val); - if (__esd_send_system_event(SYS_EVENT_VIBRATION_STATE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); - - key = EVT_KEY_SILENT_MODE; - val = EVT_VAL_SILENTMODE_OFF; - b = bundle_create(); - bundle_add_str(b, key, val); - if (__esd_send_system_event(SYS_EVENT_SILENT_MODE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); - } else { - if (!vibration_on) { - key = EVT_KEY_SILENT_MODE; - val = EVT_VAL_SILENTMODE_ON; - b = bundle_create(); - bundle_add_str(b, key, val); - if (__esd_send_system_event(SYS_EVENT_SILENT_MODE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); - } - } -} - -static void __esd_vconfcb_auto_rotate(keynode_t *node, void *user_data) -{ - int ret = 0; - int enabled = 0; - bundle *b = NULL; - const char *key = NULL; - const char *val = NULL; - - _D("vconfcb called"); - - ret = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &enabled); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - key = EVT_KEY_SCREEN_AUTOROTATE_STATE; - - if (enabled) - val = EVT_VAL_SCREEN_AUTOROTATE_ON; - else - val = EVT_VAL_SCREEN_AUTOROTATE_OFF; - - b = bundle_create(); - bundle_add_str(b, key, val); - - if (__esd_send_system_event(SYS_EVENT_SCREEN_AUTOROTATE_STATE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); -} - -static void __esd_vconfcb_mobiledata_state(keynode_t *node, void *user_data) -{ - int ret = 0; - int enabled = 0; - bundle *b = NULL; - const char *key = NULL; - const char *val = NULL; - - _D("vconfcb called"); - - ret = vconf_get_bool(VCONFKEY_3G_ENABLE, &enabled); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - key = EVT_KEY_MOBILE_DATA_STATE; - - if (enabled) - val = EVT_VAL_MOBILE_DATA_ON; - else - val = EVT_VAL_MOBILE_DATA_OFF; - - b = bundle_create(); - bundle_add_str(b, key, val); - - if (__esd_send_system_event(SYS_EVENT_MOBILE_DATA_STATE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); -} - -static void __esd_vconfcb_roaming_state(keynode_t *node, void *user_data) -{ - int ret = 0; - int enabled = 0; - bundle *b = NULL; - const char *key = NULL; - const char *val = NULL; - - _D("vconfcb called"); - - ret = vconf_get_bool(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL, &enabled); - if (ret != VCONF_OK) { - _E("failed to get vconf (%d)", ret); - return; - } - - key = EVT_KEY_DATA_ROAMING_STATE; - - if (enabled) - val = EVT_VAL_DATA_ROAMING_ON; - else - val = EVT_VAL_DATA_ROAMING_OFF; - - b = bundle_create(); - bundle_add_str(b, key, val); - - if (__esd_send_system_event(SYS_EVENT_DATA_ROAMING_STATE, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); -} - -static void __esd_vconfcb_font_set(keynode_t *node, void *user_data) -{ - char *str = 0; - bundle *b = NULL; - const char *key = NULL; - - _D("vconfcb called"); - - str = vconf_get_str(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME); - if (str == NULL) { - _E("failed to get vconf str"); - return; - } - - key = EVT_KEY_FONT_SET; - - b = bundle_create(); - bundle_add_str(b, key, str); - - if (__esd_send_system_event(SYS_EVENT_FONT_SET, b, key) != ES_R_OK) - _E("failed to send event"); - - if (b) - bundle_free(b); - if (str) - free(str); -} - -static struct esd_vconf_handler vconf_callbacks[] = { - {VCONFKEY_LOCATION_USE_MY_LOCATION, __esd_vconfcb_location_use_mylocation}, - {VCONFKEY_LOCATION_ENABLED, __esd_vconfcb_location_enabled}, - {VCONFKEY_LOCATION_NETWORK_ENABLED, __esd_vconfcb_location_network_enabled}, - {VCONFKEY_LANGSET, __esd_vconfcb_language_set}, - {VCONFKEY_REGIONFORMAT_TIME1224, __esd_vconfcb_hour_format}, - {VCONFKEY_REGIONFORMAT, __esd_vconfcb_region_format}, - {VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, __esd_vconfcb_vibration_status}, - {VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, __esd_vconfcb_sound_status}, - {VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __esd_vconfcb_auto_rotate}, - {VCONFKEY_3G_ENABLE, __esd_vconfcb_mobiledata_state}, - {VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL, __esd_vconfcb_roaming_state}, - {VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, __esd_vconfcb_font_set}, -}; - -static int vconfcbs_size = sizeof(vconf_callbacks)/sizeof(struct esd_vconf_handler); - -int __esd_register_vconf_callbacks(void) -{ - int i = 0; - int ret = 0; - int result = ES_R_OK; - -#if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36) - g_type_init(); -#endif - - esd_sent_table = g_hash_table_new(g_str_hash, g_str_equal); - - _D("vconf callbacks size(%d)", vconfcbs_size); - for (i = 0; i < vconfcbs_size; i++) { - ret = vconf_notify_key_changed(vconf_callbacks[i].key, - vconf_callbacks[i].esd_vconfcb_fn, NULL); - if (ret != VCONF_OK) { - _E("failed to register vconf callback (%s)", vconf_callbacks[i].key); - result = ES_R_ERROR; - break; - } - } - - return result; -} diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt new file mode 100644 index 0000000..74a95ad --- /dev/null +++ b/src/lib/CMakeLists.txt @@ -0,0 +1,34 @@ +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} + LIB_SRCS) + +ADD_LIBRARY(${TARGET_LIB_ESD} SHARED + ${LIB_SRCS} +) +SET_TARGET_PROPERTIES(${TARGET_LIB_ESD} PROPERTIES SOVERSION ${MAJORVER}) +SET_TARGET_PROPERTIES(${TARGET_LIB_ESD} PROPERTIES VERSION ${FULLVER}) +SET_TARGET_PROPERTIES(${TARGET_LIB_ESD} PROPERTIES OUTPUT_NAME esd) + +SET_TARGET_PROPERTIES(${TARGET_LIB_ESD} PROPERTIES COMPILE_FLAGS + ${CFLAGS} "-fpic") +SET_TARGET_PROPERTIES(${TARGET_LIB_ESD} PROPERTIES LINK_FLAGS "-ldl -lpthread") + +TARGET_INCLUDE_DIRECTORIES(${TARGET_LIB_ESD} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/) + +APPLY_PKG_CONFIG(${TARGET_LIB_ESD} PUBLIC + AUL_DEPS + DLOG_DEPS + GIO_DEPS + GLIB_DEPS +) + +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/${TARGET_LIB_ESD}.pc.in + ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/libesd.pc @ONLY) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pkgconfig/libesd.pc DESTINATION + ${LIB_INSTALL_DIR}/pkgconfig) +INSTALL(TARGETS ${TARGET_LIB_ESD} DESTINATION ${LIB_INSTALL_DIR} COMPONENT + RuntimeLibraries) +INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION include/esd + FILES_MATCHING + PATTERN "*.hh") diff --git a/src/lib/imodule.hh b/src/lib/imodule.hh new file mode 100644 index 0000000..a0e64d5 --- /dev/null +++ b/src/lib/imodule.hh @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_LIB_IMODULE_HH_ +#define EVENTSYSTEM_LIB_IMODULE_HH_ + +#include + +namespace esd::api { + +class IModule { + public: + virtual ~IModule() = default; + virtual bool Startup(ToolBox* tools) = 0; + virtual void Shutdown() = 0; +}; + +} // namesapce esd::api + +#endif // EVENTSYSTEM_LIB_IMODULE_HH_ \ No newline at end of file diff --git a/src/lib/log.hh b/src/lib/log.hh new file mode 100644 index 0000000..4f2660e --- /dev/null +++ b/src/lib/log.hh @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_LIB_LOG_HH_ +#define EVENTSYSTEM_LIB_LOG_HH_ + +#include + +#undef LOG_TAG +#define LOG_TAG "ESD" + +#define _E(fmt, arg...) LOGE(fmt, ##arg) +#define _D(fmt, arg...) LOGD(fmt, ##arg) +#define _W(fmt, arg...) LOGW(fmt, ##arg) +#define _I(fmt, arg...) LOGI(fmt, ##arg) + +#endif // EVENTSYSTEM_LIB_LOG_HH_ \ No newline at end of file diff --git a/src/lib/method_broker.hh b/src/lib/method_broker.hh new file mode 100644 index 0000000..00d1d35 --- /dev/null +++ b/src/lib/method_broker.hh @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_LIB_METHOD_BROKER_HH_ +#define EVENTSYSTEM_LIB_METHOD_BROKER_HH_ + +#include +#include +#include +#include + +namespace esd::api { + +class ParamsBase { + public: + virtual ~ParamsBase() = default; +}; + +template +class Params : public ParamsBase { + public: + using FuncType = std::function; + + Params() {}; + Params(FuncType f) : func_(f) {} + + void operator()(ArgTypes... args) { + if (func_) + func_(args...); + } + + private: + FuncType func_; +}; + +class MethodBroker { + public: + template + void Register(std::string name, const T& cmd) { + fmap_.insert(std::pair>(name, std::make_shared(cmd))); + } + + template + bool Invoke(std::string name, ArgTypes... args) { + using ParamsType = Params; + + auto it = fmap_.find(name); + if (it != fmap_.end()) { + auto* p = dynamic_cast(it->second.get()); + if (p) { + (*p)(args...); + return true; + } + } + + return false; + } + + private: + std::map> fmap_; +}; + +} // namespace esd::api + +#endif // EVENTSYSTEM_LIB_METHOD_BROKER_HH_ \ No newline at end of file diff --git a/src/lib/pkgconfig/libesd.pc.in b/src/lib/pkgconfig/libesd.pc.in new file mode 100644 index 0000000..c78c669 --- /dev/null +++ b/src/lib/pkgconfig/libesd.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=/usr +exec_prefix=@EXEC_PREFIX@ +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDE_INSTALL_DIR@ + +Name: libesd +Description: esd library for making plugins +Version: @VERSION@ +Requires: bundle +Libs: -L${libdir} -lesd +Cflags: -I${includedir} -I${includedir}/esd diff --git a/src/lib/tool_box.cc b/src/lib/tool_box.cc new file mode 100644 index 0000000..5318493 --- /dev/null +++ b/src/lib/tool_box.cc @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tool_box.hh" + +namespace esd::api { + +ToolBox::ToolBox() { + +} + +} // namespace esd::api \ No newline at end of file diff --git a/src/lib/tool_box.hh b/src/lib/tool_box.hh new file mode 100644 index 0000000..7b56243 --- /dev/null +++ b/src/lib/tool_box.hh @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_LIB_TOOL_BOX_HH_ +#define EVENTSYSTEM_LIB_TOOL_BOX_HH_ + +#include + +#undef EXPORT_API +#define EXPORT_API __attribute__((visibility("default"))) + +namespace esd::api { + +class EXPORT_API ToolBox { + public: + ToolBox(); + MethodBroker& GetMethodBroker() { + return broker_; + } + + private: + MethodBroker broker_; +}; + +} // namespace esd::api + +#endif // EVENTSYSTEM_LIB_TOOL_BOX_HH_ \ No newline at end of file diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt new file mode 100644 index 0000000..3c1e9e5 --- /dev/null +++ b/src/modules/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY(cion) +ADD_SUBDIRECTORY(dbus_event) diff --git a/src/modules/cion/CMakeLists.txt b/src/modules/cion/CMakeLists.txt new file mode 100644 index 0000000..3a591da --- /dev/null +++ b/src/modules/cion/CMakeLists.txt @@ -0,0 +1,27 @@ +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} ESD_MOD_CION_SRCS) + +ADD_LIBRARY(${TARGET_ESD_MOD_CION} ${ESD_MOD_CION_SRCS}) + +TARGET_INCLUDE_DIRECTORIES(${TARGET_ESD_MOD_CION} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../lib) + +TARGET_LINK_LIBRARIES(${TARGET_ESD_MOD_CION} PRIVATE ${TARGET_LIB_ESD}) + +APPLY_PKG_CONFIG(${TARGET_ESD_MOD_CION} PUBLIC + AUL_DEPS + BUNDLE_DEPS + PARCEL_DEPS + PKGMGR_INFO_DEPS + DLOG_DEPS + GIO_DEPS + GLIB_DEPS + CION_DEPS + VCONF_DEPS + CAPI_SYSTEM_INFO_DEPS + LIBTZPLATFORM_CONFIG_DEPS + UUID_DEPS + SQLITE3_DEPS +) + +INSTALL(TARGETS ${TARGET_ESD_MOD_CION} DESTINATION ${ESD_MODULES_DIR}/mod + COMPONENT RuntimeLibraries) diff --git a/src/modules/cion/cion.cc b/src/modules/cion/cion.cc new file mode 100644 index 0000000..377b53a --- /dev/null +++ b/src/modules/cion/cion.cc @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "cion_module.hh" + +#undef EXPORT_API +#define EXPORT_API __attribute__((visibility("default"))) + +extern "C" EXPORT_API esd::api::IModule* ESD_GET_MODULE() { + return new esd::module::CionModule(); +} \ No newline at end of file diff --git a/src/modules/cion/cion_module.cc b/src/modules/cion/cion_module.cc new file mode 100644 index 0000000..42b4cf9 --- /dev/null +++ b/src/modules/cion/cion_module.cc @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "cion_module.hh" + +#include +#include +#include +#include + +#include "log.hh" + +#define DBPATH tzplatform_mkpath(TZ_SYS_DB, ".cion.db") + +namespace esd::module { + +using tizen_base::_; +using tizen_base::dbtype_cast; + +namespace { + +constexpr const char CREATE_CION_TABLE[] = R"__cion( +PRAGMA user_version = 50; +PRAGMA journal_mode = PERSIST; +PRAGMA foreign_keys = ON; +BEGIN EXCLUSIVE TRANSACTION; +CREATE TABLE IF NOT EXISTS cion_uuid ( + appid TEXT NOT NULL, + uuid TEXT NOT NULL, + PRIMARY KEY(appid) +); +CREATE TABLE IF NOT EXISTS cion_display_name ( + service_name TEXT NOT NULL, + appid TEXT NOT NULL, + display_name TEXT NULL, + enabled INTEGER DEFAULT 0, + PRIMARY KEY(service_name, appid) , + FOREIGN KEY(appid) REFERENCES cion_uuid (appid) ON DELETE CASCADE +); +COMMIT TRANSACTION; +)__cion"; + +bool CreateTable(const tizen_base::Database& db) { + auto q = tizen_base::Database::Sql(CREATE_CION_TABLE); + auto r = db.Exec(q); + if (!static_cast(r)) + return false; + + return true; +} + +bool IsTableExist(const tizen_base::Database& db) { + auto q = tizen_base::Database::Sql( + "SELECT name FROM sqlite_master WHERE type='table'" + " ORDER BY name ASC"); + auto r = db.Exec(q); + if (!static_cast(r)) + return false; + + for (const auto& i : r) { + auto [table_name] = i.Get<_>(); + if (dbtype_cast(table_name) == "cion") + return true; + } + + return false; +} + +} // namespace + +bool CionModule::Startup(api::ToolBox* tools) { + tools->GetMethodBroker().Register("Cion.GetUuidWithGenerate", + api::Params&>( + [this](const std::string& appid, std::optional& uuid) { + GetUuidWithGenerate(appid, uuid); + })); + tools->GetMethodBroker().Register("Cion.SetDisplayName", + api::Params( + [this](const std::string& appid, const std::string& service_name, + const std::string& display_name, int& ret) { + SetDisplayName(appid, service_name, display_name, ret); + })); + tools->GetMethodBroker().Register("Cion.GetDisplayName", + api::Params( + [this](const std::string& appid, const std::string& service_name, + std::string& display_name, int& ret) { + GetDisplayName(appid, service_name, display_name, ret); + })); + tools->GetMethodBroker().Register("Cion.SetEnabled", + api::Params( + [this](const std::string& appid, const std::string& service_name, + bool enabled, int& ret) { + SetEnabled(appid, service_name, enabled, ret); + })); + tools->GetMethodBroker().Register("Cion.GetEnabled", + api::Params( + [this](const std::string& appid, const std::string& service_name, + bool& enabled, int& ret) { + GetEnabled(appid, service_name, enabled, ret); + })); + + return Init(); +} + +void CionModule::Shutdown() { + +} + +bool CionModule::Init() { + try { + esd_cion_server_ = + std::make_shared("__CION_INTERNAL_DAEMON__", "", this); + } catch (const cion::Exception& e) { + _D("cion_init failed : %s", e.what()); + return false; + } + + _D("cion_init done"); + ChangeListenStatusCionServer(); + + return DbInit(); +} + +void CionModule::ChangeListenStatusCionServer() { + try { + auto ret = GetEnabledServiceList(); + if (!ret) { + _D("Get list error"); + } else if (ret->empty() && is_listening_) { + esd_cion_server_->Stop(); + is_listening_ = false; + _D("esd_cion_server stop listen"); + } else if (!ret->empty() && !is_listening_) { + esd_cion_server_->Listen(); + is_listening_ = true; + _D("esd_cion_server start listen"); + } + } catch (const cion::Exception& e) { + _E("cion_init failed : %s", e.what()); + } + + return; +} + +void CionModule::AddEnabledApp(const std::string& service_name, + const std::string& app_id, const std::string& display_name) { + if (esd_cion_server_ == nullptr) { + _E("Call init function at first"); + return; + } + + esd_cion_server_->AddOndemandServiceList(service_name, app_id, display_name); + if (!is_listening_) + ChangeListenStatusCionServer(); +} + +void CionModule::RemoveEnabledApp(const std::string& service_name, + const std::string& app_id) { + if (esd_cion_server_ == nullptr) { + _E("Call init function at first"); + return; + } + + esd_cion_server_->RemoveOndemandServiceList(service_name, app_id); + + if (is_listening_) + ChangeListenStatusCionServer(); +} + +bool CionModule::DbInit() { + try { + tizen_base::Database db(DBPATH, SQLITE_OPEN_READWRITE); + if (IsTableExist(db)) { + if (!CreateTable(db)) { + _E("Fail to create table"); + return false; + } + } + } catch(const std::runtime_error&) { + unlink(DBPATH); + try { + tizen_base::Database db(DBPATH, SQLITE_OPEN_CREATE | + SQLITE_OPEN_READWRITE); + if (IsTableExist(db)) { + if (!CreateTable(db)) { + _E("Fail to create table"); + return false; + } + } + } catch(const std::runtime_error&) { + unlink(DBPATH); + return false; + } + } + + return true; +} + +std::string CionModule::GenUuid() { + uuid_t uu; + char _uuid[37]; + + uuid_generate_random(uu); + uuid_unparse(uu, _uuid); + + return _uuid; +} + +bool CionModule::GetUuidFromDb(const tizen_base::Database& db, + const std::string& appid, std::string& uuid) { + auto q = tizen_base::Database::Sql( + "SELECT uuid FROM cion_uuid WHERE appid = ?") + .Bind(appid); + auto r = db.Exec(q); + if (!static_cast(r)) + return false; + + for (const auto& i : r) { + auto [uuid_rec] = i.Get<_>(); + uuid = dbtype_cast(uuid_rec); + return true; + } + + return false; +} + +bool CionModule::SetUuidToDb(const tizen_base::Database& db, + const std::string& appid, const std::string& uuid) { + auto q = tizen_base::Database::Sql( + "INSERT INTO cion_uuid (appid, uuid) VALUES (?, ?)") + .Bind(appid) + .Bind(uuid); + auto r = db.Exec(q); + if (!static_cast(r)) + return false; + return true; +} + +void CionModule::GetUuidWithGenerate(const std::string& appid, + std::optional& uuid) { + try { + tizen_base::Database db(DBPATH, SQLITE_OPEN_READWRITE); + std::string uuid_str; + int ret = 0; + + if (!GetUuidFromDb(db, appid, uuid_str)) { + uuid_str = GenUuid(); + ret = SetUuidToDb(db, appid, uuid_str); + _E("get uuid generate"); + } + + if (ret == 0) + uuid = std::move(uuid_str); + } catch(const std::runtime_error&) { + uuid = std::nullopt; + } +} + +void CionModule::SetDisplayName(const std::string& appid, + const std::string& service_name, const std::string& display_name, int& ret) { + try { + tizen_base::Database db(DBPATH, SQLITE_OPEN_READWRITE); + std::string uuid; + + ret = 0; + if (!GetUuidFromDb(db, appid, uuid)) { + uuid = GenUuid(); + ret = SetUuidToDb(db, appid, uuid); + if (ret != 0) + return; + } + + auto q = tizen_base::Database::Sql( + "INSERT INTO cion_display_name(service_name, appid, display_name) " + "VALUES (?, ?, ?) ON CONFLICT(service_name, appid) " + "DO UPDATE SET display_name = ? " + "WHERE service_name = ? AND appid = ? ") + .Bind(service_name) + .Bind(appid) + .Bind(display_name) + .Bind(display_name) + .Bind(service_name) + .Bind(appid); + auto r = db.Exec(q); + if (!static_cast(r)) + ret = -1; + } catch(const std::runtime_error&) { + ret = -1; + } +} + +void CionModule::GetDisplayName(const std::string& appid, + const std::string& service_name, std::string& display_name, int& ret) { + try { + tizen_base::Database db(DBPATH, SQLITE_OPEN_READWRITE); + + ret = -1; + auto q = tizen_base::Database::Sql( + "SELECT display_name FROM cion_display_name " + "WHERE appid = ? AND service_name = ?") + .Bind(appid) + .Bind(service_name); + + auto r = db.Exec(q); + if (!static_cast(r)) + return; + + for (const auto& i : r) { + auto [display_name_rec] = i.Get<_>(); + display_name = dbtype_cast(display_name_rec); + ret = 0; + break; + } + } catch(const std::runtime_error&) { + ret = -1; + } +} + +void CionModule::SetEnabled(const std::string& appid, const std::string& service_name, + bool enabled, int& ret) { + try { + tizen_base::Database db(DBPATH, SQLITE_OPEN_READWRITE); + + ret = -1; + auto q = tizen_base::Database::Sql( + "UPDATE cion_display_name SET enabled = ? " + "WHERE appid = ? AND service_name = ?") + .Bind(enabled? 1 : 0) + .Bind(appid) + .Bind(service_name); + + auto r = db.Exec(q); + if (!static_cast(r)) + return; + + auto q2 = tizen_base::Database::Sql( + "SELECT display_name FROM cion_display_name " + "WHERE appid = %Q AND service_name = %Q") + .Bind(appid) + .Bind(service_name); + + auto r2 = db.Exec(q2); + if (!static_cast(r2)) + return; + + for (const auto& i : r2) { + auto [display_name_rec] = i.Get<_>(); + std::string display_name = dbtype_cast(display_name_rec); + if (enabled) + AddEnabledApp(service_name, appid, display_name); + else + RemoveEnabledApp(service_name, appid); + ret = 0; + break; + } + } catch(const std::runtime_error&) { + ret = -1; + } +} + +void CionModule::GetEnabled(const std::string& appid, const std::string& service_name, + bool& enabled, int& ret) { + try { + tizen_base::Database db(DBPATH, SQLITE_OPEN_READWRITE); + + ret = -1; + auto q = tizen_base::Database::Sql( + "SELECT enabled FROM cion_display_name " + "WHERE appid = ? AND service_name = ?") + .Bind(appid) + .Bind(service_name); + + auto r = db.Exec(q); + if (!static_cast(r)) + return; + + for (const auto& i : r) { + auto [enabled_rec] = i.Get<_>(); + enabled = (bool)dbtype_cast(enabled_rec); + ret = 0; + break; + } + } catch(const std::runtime_error&) { + ret = -1; + } +} + +std::optional> CionModule::GetEnabledServiceList() { + try { + tizen_base::Database db(DBPATH, SQLITE_OPEN_READWRITE); + auto q = tizen_base::Database::Sql( + "SELECT service_name, appid, display_name " + "FROM cion_display_name WHERE enabled = 1"); + + auto r = db.Exec(q); + if (!static_cast(r)) + return std::nullopt; + + std::list info_list; + for (const auto& i : r) { + auto [service_name, appid, display_name] = i.Get<_, _, _>(); + info_list.push_back( + CionServiceInfo(dbtype_cast(service_name), + dbtype_cast(appid), + dbtype_cast(display_name))); + } + + return info_list; + } catch(const std::runtime_error&) { + return std::nullopt; + } +} + +} //namespace esd::module diff --git a/src/modules/cion/cion_module.hh b/src/modules/cion/cion_module.hh new file mode 100644 index 0000000..beeaba1 --- /dev/null +++ b/src/modules/cion/cion_module.hh @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_MODULES_CION_CION_MODULE_HH_ +#define EVENTSYSTEM_MODULES_CION_CION_MODULE_HH_ + +#include +#include +#include +#include +#include + +#include "cion_ondemand_server.h" +#include "cion_service_info.hh" +#include "database.hpp" + +namespace esd::module { + +class CionModule : public api::IModule { + public: + CionModule() = default; + virtual ~CionModule() = default; + + bool Startup(api::ToolBox* tools) override; + void Shutdown() override; + + void AddEnabledApp(const std::string& service_name, + const std::string& app_id, const std::string& display_name); + void RemoveEnabledApp(const std::string& service_name, + const std::string& app_id); + std::optional> GetEnabledServiceList(); + void GetUuidWithGenerate(const std::string& appid, + std::optional& uuid); + + private: + bool Init(); + bool DbInit(); + void ChangeListenStatusCionServer(); + void SetDisplayName(const std::string& appid, const std::string& service_name, + const std::string& display_name, int& ret); + void GetDisplayName(const std::string& appid, const std::string& service_name, + std::string& display_name, int& ret); + void SetEnabled(const std::string& appid, const std::string& service_name, + bool enabled, int& ret); + void GetEnabled(const std::string& appid, const std::string& service_name, + bool& enabled, int& ret); + bool GetUuidFromDb(const tizen_base::Database& db, + const std::string& appid, std::string& uuid); + bool SetUuidToDb(const tizen_base::Database& db, + const std::string& appid, const std::string& uuid); + std::string GenUuid(); + + private: + std::shared_ptr esd_cion_server_; + bool is_listening_ = false; +}; + +} // namespace esd::module + +#endif // EVENTSYSTEM_MODULES_CION_CION_MODULE_HH_ \ No newline at end of file diff --git a/src/esd_cion/cion_ondemand_server.cc b/src/modules/cion/cion_ondemand_server.cc similarity index 81% rename from src/esd_cion/cion_ondemand_server.cc rename to src/modules/cion/cion_ondemand_server.cc index 0301b0f..fa396dd 100644 --- a/src/esd_cion/cion_ondemand_server.cc +++ b/src/modules/cion/cion_ondemand_server.cc @@ -14,7 +14,6 @@ * limitations under the License. */ -#include #include #include #include @@ -29,19 +28,20 @@ #include #include -#include "eventsystem_daemon.h" +#include #include "cion_ondemand_server.h" #include "cion_peer_info.h" - +#include "cion_module.hh" namespace { -std::string GetAppVersion(const char* appid) { +std::string GetAppVersion(const std::string& appid) { char *pkgid; char *pkg_version = NULL; pkgmgrinfo_appinfo_h appinfo = NULL; - int retval = pkgmgrinfo_appinfo_get_usr_appinfo(appid, getuid(), &appinfo); + int retval = pkgmgrinfo_appinfo_get_usr_appinfo(appid.c_str(), + getuid(), &appinfo); if (retval != PMINFO_R_OK) return {}; @@ -95,16 +95,6 @@ std::string GetVconfString(const char* key) { return val_str; } -void FreeList(gpointer data) { - cion_service_info_s *info = (cion_service_info_s *)data; - - free(info->appid); - free(info->service_name); - if (info->display_name) - free(info->display_name); - free(info); -} - std::string device_id = GetSystemInfoPlatformString("http://tizen.org/system/tizenid"); std::string device_name = GetVconfString(VCONFKEY_SETAPPL_DEVICE_NAME_STR); std::string device_platform = "Tizen"; @@ -115,8 +105,8 @@ std::string device_type = GetSystemInfoPlatformString("http://tizen.org/system/d } // namespace CionOndemandServer::CionOndemandServer(std::string service_name, - std::string display_name) - : cion::channel::ServerChannel(service_name, display_name) { + std::string display_name, esd::api::IModule* module) + : cion::channel::ServerChannel(service_name, display_name), module_(module) { LoadOndemandServiceList(); } @@ -247,45 +237,36 @@ int CionOndemandServer::OndemandLaunchApp(std::string appid) { } void CionOndemandServer::LoadOndemandServiceList() { - GList *list = nullptr; - int ret = esd_cion_get_enabled_service_list(&list); - if (ret != 0 || list == nullptr) { - _E("Get list error"); - } else { - for (GList *it = g_list_first(list); it; it = g_list_next(it)) { - cion_service_info *cion_info = (cion_service_info_s *)(it->data); - char *app_id = cion_info->appid; - char *service_name = cion_info->service_name; - char *display_name = cion_info->display_name; - char *uuid; - ret = esd_cion_get_uuid_with_generate(app_id, &uuid); - if (ret != 0) { - _E("Get uuid for %s", app_id); - } - - std::string app_version = GetAppVersion(app_id); - - tizen_base::Parcel parcel; - parcel.WriteString(device_id); - parcel.WriteString(device_name); - parcel.WriteString(device_platform); - parcel.WriteString(device_platform_version); - parcel.WriteString(device_type); - parcel.WriteString(std::string(app_id)); - parcel.WriteString(app_version); - parcel.WriteString(std::string(uuid)); - parcel.WriteString(std::string(display_name)); - - std::shared_ptr pi = - std::make_shared(std::string(service_name), - parcel.GetData(), parcel.GetDataSize()); - ondemand_peer_list_.emplace_back(pi); - - free(uuid); + auto* mod = static_cast(module_); + auto ret = mod->GetEnabledServiceList(); + + if (!ret) + return; + + for (const auto& i : *ret) { + std::optional uuid; + mod->GetUuidWithGenerate(i.GetAppId(), uuid); + if (!uuid) { + _E("Get uuid for %s", i.GetAppId().c_str()); } - } - g_list_free_full(list, FreeList); + std::string app_version = GetAppVersion(i.GetAppId()); + tizen_base::Parcel parcel; + parcel.WriteString(device_id); + parcel.WriteString(device_name); + parcel.WriteString(device_platform); + parcel.WriteString(device_platform_version); + parcel.WriteString(device_type); + parcel.WriteString(i.GetAppId()); + parcel.WriteString(app_version); + parcel.WriteString(*uuid); + parcel.WriteString(i.GetDisplayName()); + + std::shared_ptr pi = + std::make_shared(i.GetServiceName(), + parcel.GetData(), parcel.GetDataSize()); + ondemand_peer_list_.emplace_back(pi); + } } void CionOndemandServer::AddOndemandServiceList(std::string service_name, @@ -298,14 +279,15 @@ void CionOndemandServer::AddOndemandServiceList(std::string service_name, } } - char *uuid; - int ret = esd_cion_get_uuid_with_generate(appid.c_str(), &uuid); - if (ret != 0) { + std::optional uuid; + auto* mod = static_cast(module_); + mod->GetUuidWithGenerate(appid, uuid); + if (!uuid) { _E("Get uuid for %s", appid.c_str()); return; } - std::string app_version = GetAppVersion(appid.c_str()); + std::string app_version = GetAppVersion(appid); tizen_base::Parcel parcel; parcel.WriteString(device_id); @@ -315,14 +297,13 @@ void CionOndemandServer::AddOndemandServiceList(std::string service_name, parcel.WriteString(device_type); parcel.WriteString(appid); parcel.WriteString(app_version); - parcel.WriteString(std::string(uuid)); + parcel.WriteString(*uuid); parcel.WriteString(display_name); std::shared_ptr pi = std::make_shared(service_name, parcel.GetData(), parcel.GetDataSize()); ondemand_peer_list_.emplace_back(pi); - free(uuid); _D("[%s:%s] is added to list", appid.c_str(), service_name.c_str()); } diff --git a/src/esd_cion/cion_ondemand_server.h b/src/modules/cion/cion_ondemand_server.h similarity index 95% rename from src/esd_cion/cion_ondemand_server.h rename to src/modules/cion/cion_ondemand_server.h index 3f7ed16..dc7e235 100644 --- a/src/esd_cion/cion_ondemand_server.h +++ b/src/modules/cion/cion_ondemand_server.h @@ -22,13 +22,14 @@ #include #include #include +#include #include "cion_peer_info.h" class CionOndemandServer : public cion::channel::ServerChannel { public: explicit CionOndemandServer(std::string service_name, - std::string display_name); + std::string display_name, esd::api::IModule* module); explicit CionOndemandServer(std::string service_name, std::string display_name, cion::SecurityInfo security); @@ -57,6 +58,7 @@ class CionOndemandServer : public cion::channel::ServerChannel { private: std::list> ondemand_peer_list_; + esd::api::IModule* module_ = nullptr; }; #endif /* EVENTSYSTEM_DAEMON_CION_ONDEMAND_SERVER_H_ */ diff --git a/src/esd_cion/cion_peer_info.cc b/src/modules/cion/cion_peer_info.cc similarity index 100% rename from src/esd_cion/cion_peer_info.cc rename to src/modules/cion/cion_peer_info.cc diff --git a/src/esd_cion/cion_peer_info.h b/src/modules/cion/cion_peer_info.h similarity index 100% rename from src/esd_cion/cion_peer_info.h rename to src/modules/cion/cion_peer_info.h diff --git a/src/modules/cion/cion_service_info.hh b/src/modules/cion/cion_service_info.hh new file mode 100644 index 0000000..cade604 --- /dev/null +++ b/src/modules/cion/cion_service_info.hh @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_MODULES_CION_CION_SERVICE_INFO_HH_ +#define EVENTSYSTEM_MODULES_CION_CION_SERVICE_INFO_HH_ + +#include +#include + +#include + +class CionServiceInfo { +public: + CionServiceInfo(std::string service_name, std::string appid, + std::string display_name) : service_name_(std::move(service_name)), + appid_(std::move(appid)), display_name_(std::move(display_name)) {} + + const std::string& GetServiceName() const { + return service_name_; + } + + const std::string& GetAppId() const { + return appid_; + } + + const std::string& GetDisplayName() const { + return display_name_; + } + +private: + std::string service_name_; + std::string appid_; + std::string display_name_; +}; + +#endif // EVENTSYSTEM_MODULES_CION_CION_SERVICE_INFO_HH_ \ No newline at end of file diff --git a/src/modules/cion/database.hpp b/src/modules/cion/database.hpp new file mode 100644 index 0000000..a31a90e --- /dev/null +++ b/src/modules/cion/database.hpp @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DATABASE_HPP_ +#define DATABASE_HPP_ + +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace tizen_base { + +using DbType = std::variant>; +using _ = DbType; + +template +T dbtype_cast(DbType v) { + return std::get(v); +} + +template +struct num { + static const constexpr auto value = N; +}; + +template +void for_(F func, std::index_sequence) { + (func(num{}), ...); +} + +template +void for_(F func) { + for_(func, std::make_index_sequence()); +} + +class Database { + public: + class TransactionGuard { + public: + TransactionGuard(const TransactionGuard&) = delete; + TransactionGuard& operator = (const TransactionGuard&) = delete; + + TransactionGuard(TransactionGuard&& t) noexcept { + db_ = t.db_; + t.db_ = nullptr; + } + + TransactionGuard& operator = (TransactionGuard&& t) noexcept { + if (this != &t) { + if (db_) + sqlite3_exec(db_, "ROLLBACK", nullptr, nullptr, nullptr); + db_ = t.db_; + t.db_ = nullptr; + } + + return *this; + } + + TransactionGuard(sqlite3* db) : db_(db) { + if (sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL) != SQLITE_OK) { + throw std::runtime_error("begin transaction failed"); + } + } + + ~TransactionGuard() { + if (db_) + sqlite3_exec(db_, "ROLLBACK", nullptr, nullptr, nullptr); + } + + int Commit() { + int ret = sqlite3_exec(db_, "COMMIT", nullptr, nullptr, nullptr); + if (ret != SQLITE_OK) { + sqlite3_exec(db_, "ROLLBACK", nullptr, nullptr, nullptr); + } + + db_ = nullptr; + return ret; + } + + private: + sqlite3* db_ = nullptr; + }; + + class Sql { + public: + Sql(std::string query) : query_(std::move(query)) {} + + Sql& Bind(std::string val) { + bindings_.push_back(DbType(std::move(val))); + return *this; + } + + Sql& Bind(int val) { + bindings_.push_back(DbType(val)); + return *this; + } + + Sql& Bind(double val) { + bindings_.push_back(DbType(val)); + return *this; + } + + Sql& Bind(std::vector val) { + bindings_.push_back(DbType(std::move(val))); + return *this; + } + + Sql& Bind(int pos, std::string val) { + binding_map_[pos] = DbType(std::move(val)); + return *this; + } + + Sql& Bind(int pos, int val) { + binding_map_[pos] = DbType(val); + return *this; + } + + Sql& Bind(int pos, double val) { + binding_map_[pos] = DbType(val); + return *this; + } + + Sql& Bind(int pos, std::vector val) { + binding_map_[pos] = DbType(std::move(val)); + return *this; + } + + Sql& Bind(std::string name, std::string val) { + binding_name_map_[std::move(name)] = DbType(std::move(val)); + return *this; + } + + Sql& Bind(std::string name, int val) { + binding_name_map_[std::move(name)] = DbType(val); + return *this; + } + + Sql& Bind(std::string name, double val) { + binding_name_map_[std::move(name)] = DbType(val); + return *this; + } + + Sql& Bind(std::string name, std::vector val) { + binding_name_map_[std::move(name)] = DbType(std::move(val)); + return *this; + } + + const std::vector& GetBindings() const { + return bindings_; + } + + const std::map& GetBindingMap() const { + return binding_map_; + } + + const std::map& GetBindingNameMap() const { + return binding_name_map_; + } + + const std::string& GetQuery() const { + return query_; + } + + private: + std::string query_; + std::vector bindings_; + std::map binding_map_; + std::map binding_name_map_; + }; + + class Result { + public: + Result() = default; + ~Result() { + if (stmt_) + sqlite3_finalize(stmt_); + } + + Result(const Result&) = delete; + Result& operator = (const Result&) = delete; + + Result(Result&& r) noexcept { + stmt_ = r.stmt_; + r.stmt_ = nullptr; + } + + Result& operator = (Result&& r) noexcept { + if (this != &r) { + if (stmt_) + sqlite3_finalize(stmt_); + stmt_ = r.stmt_; + r.stmt_ = nullptr; + } + + return *this; + } + + class Record { + public: + Record(const sqlite3_stmt* stmt) : stmt_(stmt) {} + + DbType Get(int pos) const { + sqlite3_stmt* stmt = const_cast(stmt_); + int type = sqlite3_column_type(stmt, pos); + if (type == SQLITE_NULL) + throw std::runtime_error("invalid column");; + + DbType dbt; + if (type == SQLITE_TEXT) { + dbt = DbType(reinterpret_cast( + sqlite3_column_text(stmt, pos))); + } else if (type == SQLITE_INTEGER) { + dbt = DbType(sqlite3_column_int(stmt, pos)); + } else if (type == SQLITE_FLOAT) { + dbt = DbType(sqlite3_column_double(stmt, pos)); + } else if (type == SQLITE_BLOB) { + const unsigned char* val = reinterpret_cast( + sqlite3_column_blob(stmt, pos)); + int len = sqlite3_column_bytes(stmt, pos); + + if (!val || len < 0) { + throw std::runtime_error("invalid blob");; + } else { + dbt = DbType(std::vector(val, val + len)); + } + } else { + throw std::runtime_error("invalid column type"); + } + + return dbt; + } + + template + auto Get() const { + std::tuple t; + int pos = 0; + for_>>([&] (auto i) { + std::get(t) = Get(pos++); + }); + + return t; + } + + private: + const sqlite3_stmt* stmt_; + }; + + class Iterator { + public: + Iterator(sqlite3_stmt* stmt) : stmt_(stmt) {} + + Record operator*() { return Record(stmt_); } + + bool operator != (const Iterator& rhs) const { + return stmt_ != rhs.stmt_; + } + + void operator ++() { + int r = sqlite3_step(stmt_); + if (r != SQLITE_ROW) + stmt_ = nullptr; + } + + private: + sqlite3_stmt* stmt_ = nullptr; + }; + + Iterator begin() const { + return Iterator(stmt_); + } + + Iterator end() const { + return Iterator(nullptr); + } + + explicit operator bool() { + if (stmt_ == nullptr) + return false; + return true; + } + + explicit operator int() { + if (db_ == nullptr) + return SQLITE_ERROR; + return sqlite3_errcode(db_); + } + + operator const char*() { + if (db_ == nullptr) + return ""; + return sqlite3_errmsg(db_); + } + + private: + friend class Database; + Result(sqlite3_stmt* stmt, sqlite3* db) : stmt_(stmt), db_(db) {} + + sqlite3_stmt* stmt_ = nullptr; + sqlite3* db_ = nullptr; + }; + + Database(std::string db, int flags) { + int r = sqlite3_open_v2(db.c_str(), &db_, flags, nullptr); + if (r != SQLITE_OK) + throw std::runtime_error("open failed"); + } + + Database(std::string db, int flags, std::function busy_handler) { + int r = sqlite3_open_v2(db.c_str(), &db_, flags, nullptr); + if (r != SQLITE_OK) + throw std::runtime_error("sqlite3_open_v2() failed"); + + busy_handler_ = std::move(busy_handler); + r = sqlite3_busy_handler(db_, [](void* data, int count) { + Database* pDb = static_cast(data); + if (pDb->busy_handler_(count)) + return 1; + return 0; + }, this); + + if (r != SQLITE_OK) { + sqlite3_close_v2(db_); + throw std::runtime_error("sqlite3_busy_handler() failed"); + } + } + + ~Database() { + if (db_) + sqlite3_close_v2(db_); + } + + Database() = default; + Database(const Database&) = delete; + Database& operator = (const Database&) = delete; + + Database(Database&& db) noexcept { + db_ = db.db_; + db.db_ = nullptr; + } + + explicit operator bool() { + if (db_ == nullptr) + return false; + return true; + } + + Database& operator = (Database&& db) noexcept { + if (this != &db) { + if (db_) + sqlite3_close_v2(db_); + db_ = db.db_; + db.db_ = nullptr; + } + + return *this; + } + + TransactionGuard CreateTransactionGuard() { + return TransactionGuard(db_); + } + + Result Exec(const Sql& sql) const { + if (!db_) + throw std::runtime_error("Not opened"); + + sqlite3_stmt* stmt = nullptr; + int r = sqlite3_prepare_v2(db_, sql.GetQuery().c_str(), + -1, &stmt, nullptr); + if (r != SQLITE_OK) { + return { nullptr, nullptr }; + } + + std::unique_ptr stmt_auto(stmt, + sqlite3_finalize); + int pos = 1; + for (const auto& i : sql.GetBindings()) { + Bind(pos++, i, stmt); + } + + for (const auto& i : sql.GetBindingMap()) { + Bind(i.first, i.second, stmt); + } + + for (const auto& i : sql.GetBindingNameMap()) { + int pos = sqlite3_bind_parameter_index(stmt, i.first.c_str()); + if (pos == 0) + throw std::runtime_error("Invalid binding"); + Bind(pos, i.second, stmt); + } + + r = sqlite3_step(stmt); + if (r != SQLITE_ROW && r != SQLITE_DONE) { + return { nullptr, db_ }; + } + + return { stmt_auto.release(), db_ }; + } + + private: + void Bind(int pos, const DbType& type, sqlite3_stmt* stmt) const { + int r; + if (const std::string* pstr = std::get_if(&type)) { + r = sqlite3_bind_text(stmt, pos, (*pstr).c_str(), -1, + SQLITE_TRANSIENT); + } else if (const int* pint = std::get_if(&type)) { + r = sqlite3_bind_int(stmt, pos, (*pint)); + } else if (const double* pdouble = std::get_if(&type)) { + r = sqlite3_bind_double(stmt, pos, (*pdouble)); + } else if (const std::vector* pvector = + std::get_if>(&type)) { + r = sqlite3_bind_blob(stmt, pos, (*pvector).data(), + (*pvector).size(), nullptr); + } else { + r = -1; + } + + if (r != SQLITE_OK) { + throw std::runtime_error("Invalid binding"); + } + } + + private: + sqlite3* db_ = nullptr; + std::function busy_handler_; +}; + +} // namespace tizen_base + +#endif // DATABASE_HPP_ diff --git a/src/modules/dbus_event/CMakeLists.txt b/src/modules/dbus_event/CMakeLists.txt new file mode 100644 index 0000000..869df0b --- /dev/null +++ b/src/modules/dbus_event/CMakeLists.txt @@ -0,0 +1,30 @@ +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} ESD_MOD_DBUS_EVENT_SRC) + +ADD_LIBRARY(${TARGET_ESD_MOD_DBUS_EVENT} ${ESD_MOD_DBUS_EVENT_SRC}) + +TARGET_INCLUDE_DIRECTORIES(${TARGET_ESD_MOD_DBUS_EVENT} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../lib) + +TARGET_LINK_LIBRARIES(${TARGET_ESD_MOD_DBUS_EVENT} PRIVATE ${TARGET_LIB_ESD}) + +APPLY_PKG_CONFIG(${TARGET_ESD_MOD_DBUS_EVENT} PUBLIC + AUL_DEPS + DLOG_DEPS + GIO_DEPS + GLIB_DEPS + VCONF_DEPS + PKGMGR_INFO_DEPS + SECURITY_MANAGER_DEPS + CYNARA_CLIENT_DEPS + CYNARA_CREDS_DBUS_DEPS + CYNARA_SESSION_DEPS + LIBTZPLATFORM_CONFIG_DEPS + CERT_SVC_VCORE_DEPS + CAPI_SYSTEM_INFO_DEPS + PKGMGR_DEPS + EVENTSYSTEM_DEPS +) + +INSTALL(TARGETS ${TARGET_ESD_MOD_DBUS_EVENT} DESTINATION ${ESD_MODULES_DIR}/mod + COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/eventsystem.conf DESTINATION /etc/dbus-1/system.d) diff --git a/src/modules/dbus_event/dbus_event.cc b/src/modules/dbus_event/dbus_event.cc new file mode 100644 index 0000000..6f90a08 --- /dev/null +++ b/src/modules/dbus_event/dbus_event.cc @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include "dbus_event_module.hh" + +#undef EXPORT_API +#define EXPORT_API __attribute__((visibility("default"))) + +extern "C" EXPORT_API esd::api::IModule* ESD_GET_MODULE() { + return new esd::module::DbusEventModule(); +} \ No newline at end of file diff --git a/src/modules/dbus_event/dbus_event_module.cc b/src/modules/dbus_event/dbus_event_module.cc new file mode 100644 index 0000000..dc64a3c --- /dev/null +++ b/src/modules/dbus_event/dbus_event_module.cc @@ -0,0 +1,2464 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "log.hh" +#include "dbus_event_module.hh" + +#define FREE_AND_NULL(ptr) do { \ + if (ptr) { \ + free((void *)ptr); \ + ptr = NULL; \ + } \ +} while (0) + +int __esd_register_vconf_callbacks(); + +namespace { + +#include "introspection_cb.hh" + +constexpr const char ESD_BOOT_COMPLETED[] = "/tmp/esd_ready"; +constexpr const char SYSTEMD_DBUS_DEST[] = "org.freedesktop.systemd1"; +constexpr const char SYSTEMD_DBUS_IFACE_MANAGER[] = "org.freedesktop.systemd1.Manager"; +constexpr const char SYSTEMD_DBUS_PATH[] = "/org/freedesktop/systemd1"; +constexpr const char SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED[] = "StartupFinished"; +constexpr const char SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED[] = "UserSessionStartupFinished"; + +#define DEFAULT_USER tzplatform_getuid(TZ_SYS_DEFAULT_USER) +#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) +constexpr const int ROOT_USER = 0; + +constexpr const char SYS_EVENT_NAME_PREFIX[] = "tizen.system.event"; +constexpr const char SYS_EVENT_OBJ_PATH[] = "/tizen/system/event"; +constexpr const char REQUEST_LAST_DATA[] = "request_last_data"; + +GHashTable *event_launch_table; /* table of events for launch_on_event*/ + +const char *event_launch_support_list[] = { + SYS_EVENT_BATTERY_CHARGER_STATUS, + SYS_EVENT_USB_STATUS, + SYS_EVENT_EARJACK_STATUS, + SYS_EVENT_INCOMMING_MSG, + SYS_EVENT_OUTGOING_MSG, + SYS_EVENT_WIFI_STATE +}; + +struct privilege_info { + const char *event_name; + const char *privilege_name; +}; + +const struct privilege_info privilege_check_list[] = { + {SYS_EVENT_DISPLAY_STATE, "http://tizen.org/privilege/display"}, + {SYS_EVENT_WIFI_STATE, "http://tizen.org/privilege/network.get"}, + {SYS_EVENT_INCOMMING_MSG, "http://tizen.org/privilege/message.read"}, + {SYS_EVENT_OUTGOING_MSG, "http://tizen.org/privilege/message.read"} +}; + +int privilege_check_size = sizeof(privilege_check_list)/sizeof(struct privilege_info); + +const char *earlier_event_list[] = { + SYS_EVENT_ESD_STATUS, + SYS_EVENT_LOW_MEMORY, + SYS_EVENT_BOOT_COMPLETED, + SYS_EVENT_SYSTEM_SHUTDOWN, + SYS_EVENT_BATTERY_CHARGER_STATUS +}; + +GHashTable *earlier_event_table; /* table of events for earlier_data */ + +typedef struct __earlier_table_item { + char *event_name; + guint reg_id; + bundle *earlier_data; /* event-data from earlier occurrence */ +} earlier_item; + +GHashTable *user_last_event_table; /* table of user events for last data */ + +struct __last_event_item { + char *key; + char *app_id; + char *event_name; + char *own_name; + uid_t uid; +}; + +GHashTable *trusted_busname_table; /* table of dbus bus-names for trusted user-event */ + +typedef struct __trusted_busname_item { + char *app_id; + char *bus_name; + int pid; + uid_t uid; +} trusted_item; + +typedef struct __eventlaunch_item_param { + char *app_id; +} eventlaunch_item_param_s; + +enum trusted_result { + TRUSTED_UNKNOWN, + TRUSTED_ALLOWED, + TRUSTED_DENIED, +}; + +typedef struct esd_list_item { + char *pkg_id; + char *app_id; + int trusted_info; + uid_t uid; +} esd_list_item_s; + +typedef struct __event_launch_table_item { + char *event_name; + char *package_name; /* just for passing pointer to app-list removal func */ + GList *app_list_evtlaunch; /* app-list for on-event-launch */ + guint reg_id; + uid_t uid; +} event_launch_item; + +enum __pkg_event_type { + UNKNOWN = 0, + INSTALL, + UNINSTALL, + UPDATE, +}; + +typedef struct __pkgmgr_event { + int type; + char *pkgid; +} esd_pkgmgr_event; + +typedef struct __esd_event_param { + char *event_name; + bundle *event_data; + uid_t sender_uid; + char *sender_appid; + bool is_user_event; + bool trusted; + void *user_data; +} esd_event_param; + +typedef struct esd_info { + pkgmgr_client *client; +} esd_info_s; +static esd_info_s s_info; + +typedef struct __esd_appctrl_cb_data { + char *appid; + char *pkgid; + uid_t uid; +} esd_appctrl_cb_data; + +void __esd_event_handler(char *event_name, bundle *data, void *user_data); +int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data); + +cynara *r_cynara; + +int __esd_init_cynara() { + int ret; + + ret = cynara_initialize(&r_cynara, NULL); + if (ret != CYNARA_API_SUCCESS) { + _E("cynara initialize failed."); + return ret; + } + + return 0; +} + +void __esd_finish_cynara() { + if (r_cynara) + cynara_finish(r_cynara); + r_cynara = NULL; +} + +void free_saved_event(struct __last_event_item *item) { + if (!item) + return; + + free(item->event_name); + free(item->own_name); + free(item->app_id); + free(item); +} + +int __esd_check_earlier_support(const char *event_name) { + int i = 0; + int size = sizeof(earlier_event_list)/sizeof(*earlier_event_list); + + for (i = 0; i < size; i++) { + if (strcmp(earlier_event_list[i], event_name) == 0) + return true; + } + + return false; +} + +bool __esd_check_platform_cert(const char *pkgid, uid_t uid) { + _D("Checking if %s has a platform certification", pkgid); + + int r; + const char *cert_value; + pkgmgrinfo_certinfo_h certinfo; + CertSvcInstance instance; + CertSvcCertificate certificate; + CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC; + + r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo); + if (r != PMINFO_R_OK) { + _E("Failed to create certinfo"); + return false; + } + + r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid); + if (r != PMINFO_R_OK) { + _E("Failed to load certinfo"); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + return false; + } + + r = pkgmgrinfo_pkginfo_get_cert_value(certinfo, + PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value); + if (r != PMINFO_R_OK || cert_value == NULL) { + _E("Failed to get cert value"); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + return false; + } + + r = certsvc_instance_new(&instance); + if (r != CERTSVC_SUCCESS) { + _E("certsvc_instance_new() is failed."); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + return false; + } + + r = certsvc_certificate_new_from_memory(instance, + (const unsigned char *)cert_value, + strlen(cert_value), + CERTSVC_FORM_DER_BASE64, + &certificate); + if (r != CERTSVC_SUCCESS) { + _E("certsvc_certificate_new_from_memory() is failed."); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + certsvc_instance_free(instance); + return false; + } + + r = certsvc_certificate_get_visibility(certificate, &visibility); + if (r != CERTSVC_SUCCESS) + _E("certsvc_certificate_get_visibility() is failed."); + + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + certsvc_certificate_free(certificate); + certsvc_instance_free(instance); + + _D("visibility is %d", visibility); + if (visibility & CERTSVC_VISIBILITY_PLATFORM) { + _D("%s has a platform certification", pkgid); + return true; + } + + return false; +} + +int __esd_check_event_launch_support(const char *event_name) { + int i = 0; + int size = sizeof(event_launch_support_list)/sizeof(*event_launch_support_list); + + for (i = 0; i < size; i++) { + if (strcmp(event_launch_support_list[i], event_name) == 0) + return true; + } + + return false; +} + +int __get_sender_unixinfo(GDBusConnection *conn, const char *sender_name, const char *type) { + GDBusMessage *msg = NULL; + GDBusMessage *reply = NULL; + GError *err = NULL; + GVariant *body; + int ret = -1; + unsigned int value; + + msg = g_dbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", + "org.freedesktop.DBus", type); + if (!msg) { + _E("Can't allocate new method call"); + goto out; + } + + g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name)); + reply = g_dbus_connection_send_message_with_reply_sync(conn, msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err); + + if (!reply) { + if (err != NULL) { + _E("Failed to get info [%s]", err->message); + g_error_free(err); + } + goto out; + } + + body = g_dbus_message_get_body(reply); + g_variant_get(body, "(u)", &value); + ret = (int)value; + +out: + if (msg) + g_object_unref(msg); + if (reply) + g_object_unref(reply); + + return ret; +} + +int __get_sender_pid(GDBusConnection *conn, const char *sender_name) { + int pid = 0; + + pid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixProcessID"); + if (pid < 0) { + _E("failed to get pid"); + pid = 0; + } + + _D("sender_name(%s), pid(%d)", sender_name, pid); + + return pid; +} + +int __get_sender_uid(GDBusConnection *conn, const char *sender_name) { + int uid = -1; + + uid = __get_sender_unixinfo(conn, sender_name, "GetConnectionUnixUser"); + if (uid < 0) + _E("failed to get uid"); + + _D("sender_name(%s), uid(%d)", sender_name, uid); + + return uid; +} + +int __esd_check_certificate_match(uid_t uid, const char *app_id, uid_t from_uid, const char *from_appid) { + pkgmgrinfo_cert_compare_result_type_e res; + int ret = 0; + + _D("uid(%d), app_id(%s), from_uid(%d), from_appid(%s)", uid, app_id, from_uid, from_appid); + + ret = pkgmgrinfo_pkginfo_compare_usr_app_cert_info(app_id, from_appid, from_uid, &res); + if (ret < 0) { + _E("failed to check certificate"); + return ES_R_ERROR; + } + + if (res != PMINFO_CERT_COMPARE_MATCH) { + _D("certificat not match (%s)", app_id); + return ES_R_EINVAL; + } + + return ES_R_OK; +} + +bool __esd_check_application_validation(uid_t uid, const char *appid) { + int ret = 0; + pkgmgrinfo_appinfo_h handle; + + ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &handle); + if (ret != PMINFO_R_OK) + return false; + + pkgmgrinfo_appinfo_destroy_appinfo(handle); + + if (!aul_app_is_running_for_uid(appid, uid)) + return false; + + return true; +} + +void __esd_trusted_busname_print_items() { + GHashTableIter iter; + gpointer key; + gpointer value; + + g_hash_table_iter_init(&iter, trusted_busname_table); + + while (g_hash_table_iter_next(&iter, &key, &value)) { + trusted_item *item = (trusted_item *)value; + if (item) + _D("uid(%d), appid(%s), pid(%d), busname(%s)", item->uid, item->app_id, item->pid, item->bus_name); + } +} + +int __esd_trusted_busname_add_item(uid_t uid, const char *appid, const char *busname, int pid) { + char *app_id = NULL; + char *bus_name = NULL; + trusted_item *item = NULL; + trusted_item *new_item; + + app_id = strdup(appid); + if (app_id == NULL) { + _E("out of memory"); + return ES_R_ENOMEM; + } + + bus_name = strdup(busname); + if (bus_name == NULL) { + _E("out of memory"); + FREE_AND_NULL(app_id); + return ES_R_ENOMEM; + } + + item = (trusted_item *)g_hash_table_lookup(trusted_busname_table, app_id); + + if (item && item->bus_name && strcmp(item->bus_name, bus_name) == 0 && + (item->uid == uid)) { + _D("already exist (%s, %s)", app_id, bus_name); + FREE_AND_NULL(app_id); + FREE_AND_NULL(bus_name); + } else { + new_item = (trusted_item *)calloc(1, sizeof(trusted_item)); + if (new_item == NULL) { + _E("memory alloc failed"); + FREE_AND_NULL(app_id); + FREE_AND_NULL(bus_name); + return ES_R_ENOMEM; + } + new_item->uid = uid; + new_item->app_id = app_id; + new_item->bus_name = bus_name; + new_item->pid = pid; + g_hash_table_insert(trusted_busname_table, new_item->app_id, new_item); + _D("added busname(%s)", new_item->bus_name); + } + + return ES_R_OK; +} + +int __esd_check_trusted_events(GDBusConnection *conn, const char *list_name) { + GVariant *result; + GError *error = NULL; + GVariantIter *iter; + gchar *str; + char tmp_appid[128] = {0, }; + int pid = 0; + int uid = 0; + int ret = 0; + + result = g_dbus_connection_call_sync(conn, + "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", + list_name, NULL, G_VARIANT_TYPE("(as)"), G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + + if (result == NULL) { + _E("get (%s) error(%s)", list_name, error->message); + g_error_free(error); + return ES_R_ERROR; + } + + g_variant_get(result, "(as)", &iter); + while (g_variant_iter_loop(iter, "s", &str)) { + if (!strstr((const char *)str, "event.busname.session")) + continue; + + _D("list(%s), name(%s)", list_name, str); + pid = __get_sender_pid(conn, (const char *)str); + if (pid <= 0) { + _E("failed to get pid(%d)", pid); + continue; + } + + uid = __get_sender_uid(conn, (const char *)str); + if (uid < 0) { + _E("failed to get uid(%d)", uid); + continue; + } + _D("uid(%d)", uid); + + memset(tmp_appid, 0, sizeof(tmp_appid)); + ret = aul_app_get_appid_bypid_for_uid(pid, tmp_appid, sizeof(tmp_appid), (uid_t)uid); + if (ret != AUL_R_OK) { + _E("failed to get appid by pid(%d)", pid); + continue; + } + + _D("appid(%s)", tmp_appid); + if (__esd_check_application_validation((uid_t)uid, tmp_appid)) { + _D("add to table"); + ret = __esd_trusted_busname_add_item((uid_t)uid, tmp_appid, (const char *)str, pid); + if (ret < 0) + _E("failed to add item"); + } + } + g_variant_iter_free(iter); + g_variant_unref(result); + + return ES_R_OK; +} + +int __esd_check_privilege_name(const char *event_name, char **privilege_name) { + int i = 0; + + *privilege_name = NULL; + + for (i = 0; i < privilege_check_size; i++) { + if (strcmp(event_name, privilege_check_list[i].event_name) == 0) { + *privilege_name = (char *)privilege_check_list[i].privilege_name; + _D("[%d] privilege_name(%s)", i, *privilege_name); + break; + } + } + + return ES_R_OK; +} + +bool __esd_check_valid_privilege_by_cynara(const char *appid, const char *client, + const char *session, const char *user, const char *privilege_name) { + int ret = 0; + bool has_privilege = false; + + _D("check privilege, (%s, %s, %s, %s, %s)", appid, client, session, user, privilege_name); + + ret = cynara_check(r_cynara, client, session, user, privilege_name); + if (ret == CYNARA_API_ACCESS_ALLOWED) { + _D("valid privilege"); + has_privilege = true; + } else if (ret == CYNARA_API_ACCESS_DENIED) { + _E("invalid privilege"); + } else { + _E("failed to check privilege, error(%d)", ret); + } + + return has_privilege; +} + +int __esd_check_app_privileged_event(uid_t uid, const char *appid, const char *pkgid, const char *event_name) { + char *privilege_name = NULL; + int ret = 0; + int result = 0; + + _D("event_name(%s), uid(%d), appid(%s), pkgid(%s)", event_name, uid, appid, pkgid); + + __esd_check_privilege_name(event_name, &privilege_name); + + if (privilege_name) { + ret = security_manager_app_has_privilege(appid, privilege_name, uid, &result); + if (ret != SECURITY_MANAGER_SUCCESS) + _E("failed to check privilege(%d)", ret); + _D("result(%d)", result); + } else { + result = 1; + } + + return result; +} + +void __esd_print_appid_with_eventid(gpointer data, gpointer user_data) { + esd_list_item_s *item = (esd_list_item_s *)data; + char *event_name = (char *)user_data; + + _D("event_name(%s)-uid(%d)-app_id(%s)-pkg_id(%s)", event_name, item->uid, item->app_id, item->pkg_id); +} + +void __esd_print_interested_event(gpointer data, gpointer user_data) { + event_launch_item *el_item = (event_launch_item *)data; + char *event_name = (char *)el_item->event_name; + _D("event_name = (%s)", event_name); + g_list_foreach(el_item->app_list_evtlaunch, __esd_print_appid_with_eventid, event_name); +} + +void __esd_launch_table_print_items() { + GHashTableIter iter; + gpointer key; + gpointer value; + + g_hash_table_iter_init(&iter, event_launch_table); + + while (g_hash_table_iter_next(&iter, &key, &value)) + __esd_print_interested_event(value, NULL); +} + +int __esd_find_compare_by_list_item(gconstpointer data, gconstpointer user_data) { + esd_list_item_s *item_1 = (esd_list_item_s *)user_data; + esd_list_item_s *item_2 = (esd_list_item_s *)data; + + return (item_1->uid != item_2->uid) | + strcmp(item_1->app_id, item_2->app_id) | + strcmp(item_1->pkg_id, item_2->pkg_id); +} + +int __esd_add_list_item(uid_t uid, event_launch_item *el_item, + const char *app_id, const char *pkg_id) { + esd_list_item_s *item_of_list = NULL; + + item_of_list = (esd_list_item_s *)calloc(1, sizeof(esd_list_item_s)); + if (item_of_list == NULL) { + _E("out_of_memory"); + return ES_R_ENOMEM; + } + item_of_list->uid = uid; + item_of_list->app_id = (char *)app_id; + item_of_list->pkg_id = (char *)pkg_id; + item_of_list->trusted_info = TRUSTED_UNKNOWN; + el_item->app_list_evtlaunch = + g_list_append(el_item->app_list_evtlaunch, item_of_list); + + return ES_R_OK; +} + +int __esd_add_launch_item(uid_t uid, const char *event_name, + const char *appid, const char *pkgid) { + GList *app_list = NULL; + guint subscription_id = 0; + char *app_id = NULL; + char *pkg_id = NULL; + esd_list_item_s *item_of_list = NULL; + event_launch_item *eli; + event_launch_item *el_item = + (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name); + + if (el_item) { + item_of_list = (esd_list_item_s *)calloc(1, sizeof(esd_list_item_s)); + if (item_of_list == NULL) { + _E("memory alloc failed"); + return ES_R_ENOMEM; + } + item_of_list->uid = uid; + item_of_list->app_id = (char *)appid; + item_of_list->pkg_id = (char *)pkgid; + + app_list = g_list_find_custom(el_item->app_list_evtlaunch, + item_of_list, (GCompareFunc)__esd_find_compare_by_list_item); + free(item_of_list); + if (app_list == NULL) { + _D("add new item (list item only)"); + app_id = strdup((char *)appid); + if (!app_id) { + _E("out_of_memory"); + return ES_R_ENOMEM; + } + pkg_id = strdup((char *)pkgid); + if (!pkg_id) { + _E("out_of_memory"); + FREE_AND_NULL(app_id); + return ES_R_ENOMEM; + } + if (__esd_add_list_item(uid, el_item, app_id, pkg_id) < 0) { + _E("failed to add list item"); + FREE_AND_NULL(app_id); + FREE_AND_NULL(pkg_id); + return ES_R_ERROR; + } + } + } else { + _D("add new item (all)"); + eli = (event_launch_item *)calloc(1, sizeof(event_launch_item)); + if (!eli) { + _E("memory alloc failed"); + return ES_R_ENOMEM; + } + + eli->event_name = strdup(event_name); + if (!eli->event_name) { + _E("out_of_memory"); + FREE_AND_NULL(eli); + return ES_R_ENOMEM; + } + + app_id = strdup((char *)appid); + if (!app_id) { + _E("out_of_memory"); + FREE_AND_NULL(eli->event_name); + FREE_AND_NULL(eli); + return ES_R_ENOMEM; + } + + pkg_id = strdup((char *)pkgid); + if (!pkg_id) { + _E("out_of_memory"); + FREE_AND_NULL(app_id); + FREE_AND_NULL(eli->event_name); + FREE_AND_NULL(eli); + return ES_R_ENOMEM; + } + + if (__esd_add_list_item(uid, eli, app_id, pkg_id) < 0) { + _E("failed to add list item"); + FREE_AND_NULL(app_id); + FREE_AND_NULL(pkg_id); + FREE_AND_NULL(eli->event_name); + FREE_AND_NULL(eli); + return ES_R_ERROR; + } + + g_hash_table_insert(event_launch_table, eli->event_name, eli); + + eventsystem_register_event(eli->event_name, &subscription_id, + (eventsystem_handler)__esd_event_handler, NULL); + if (subscription_id == 0) { + _E("signal subscription error, event_name(%s), app_id(%s)", + eli->event_name, app_id); + return ES_R_ERROR; + } else { + eli->reg_id = subscription_id; + } + } + + return ES_R_OK; +} + +void __esd_remove_all_private_usr_app_list(gpointer data, gpointer user_data) { + esd_list_item_s *item = (esd_list_item_s *)data; + event_launch_item *eli = (event_launch_item *)user_data; + + if (item->uid != GLOBAL_USER && !strcmp(eli->package_name, item->pkg_id)) { + _D("uid(%d), app_id(%s), pkg_id(%s)", item->uid, item->app_id, eli->package_name); + eli->app_list_evtlaunch = g_list_remove_all(eli->app_list_evtlaunch, data); + } +} + +int __esd_launch_table_remove_private_usr_items() { + GHashTableIter iter; + gpointer key; + gpointer value; + event_launch_item *eli = NULL; + GList *first_list = NULL; + + g_hash_table_iter_init(&iter, event_launch_table); + + while (g_hash_table_iter_next(&iter, &key, &value)) { + eli = (event_launch_item *)value; + g_list_foreach(eli->app_list_evtlaunch, __esd_remove_all_private_usr_app_list, eli); + + first_list = g_list_first(eli->app_list_evtlaunch); + if (first_list == NULL) { + if (eli->reg_id) + eventsystem_unregister_event(eli->reg_id); + + g_hash_table_iter_remove(&iter); + } + } + + return ES_R_OK; +} + +void __esd_remove_app_list(gpointer data, gpointer user_data) { + bool skip = false; + esd_list_item_s *item = (esd_list_item_s *)data; + event_launch_item *eli = (event_launch_item *)user_data; + + if (eli->uid != GLOBAL_USER && eli->uid != item->uid) + skip = true; + + if (!skip && !strcmp(eli->package_name, item->pkg_id)) { + _D("pkg_id(%s), app_id(%s)", eli->package_name, item->app_id); + eli->app_list_evtlaunch = + g_list_remove_all(eli->app_list_evtlaunch, data); + } +} + +int __esd_remove_launch_item(uid_t uid, gpointer data, const char *pkg_id) { + event_launch_item *eli = (event_launch_item *)data; + GList *first_list = NULL; + + eli->uid = uid; + eli->package_name = (char *)pkg_id; + g_list_foreach(eli->app_list_evtlaunch, __esd_remove_app_list, eli); + + first_list = g_list_first(eli->app_list_evtlaunch); + if (first_list == NULL) { + if (eli->reg_id) + eventsystem_unregister_event(eli->reg_id); + + return ES_R_REMOVE; + } + + return ES_R_OK; +} + +int __esd_launch_table_remove_items(uid_t uid, const char *pkg_id) { + GHashTableIter iter; + gpointer key; + gpointer value; + + g_hash_table_iter_init(&iter, event_launch_table); + + while (g_hash_table_iter_next(&iter, &key, &value)) { + if (__esd_remove_launch_item(uid, value, pkg_id) == ES_R_REMOVE) { + _D("remove item itself"); + g_hash_table_iter_remove(&iter); + } + } + + return ES_R_OK; +} + +void __esd_event_launch_with_appid(gpointer data, gpointer user_data) { + esd_list_item_s *item = (esd_list_item_s *)data; + uid_t uid = item->uid; + char *app_id = item->app_id; + esd_event_param *eep = (esd_event_param *)user_data; + static unsigned int req_id; + int pid; + char event_uri[1024]; + bundle *b; + int ret; + + _D("launch_on_event: app_id(%s), event_name(%s), uid(%d), is_user(%d), trusted(%d)", + app_id, eep->event_name, uid, eep->is_user_event, eep->trusted); + + if (eep->is_user_event && eep->trusted) { + if (item->trusted_info == TRUSTED_UNKNOWN) { + ret = __esd_check_certificate_match(uid, app_id, eep->sender_uid, eep->sender_appid); + if (ret == ES_R_EINVAL) { + item->trusted_info = TRUSTED_DENIED; + return; + } else if (ret == ES_R_ERROR) { + return; + } else { + item->trusted_info = TRUSTED_ALLOWED; + } + } else if (item->trusted_info == TRUSTED_DENIED) { + return; + } + } + + if (!aul_app_is_running_for_uid(app_id, uid)) { + b = bundle_dup(eep->event_data); + if (eep->is_user_event) + snprintf(event_uri, sizeof(event_uri), "%s%s", USER_EVENT_NAME_PREFIX, eep->event_name); + else + snprintf(event_uri, sizeof(event_uri), "%s%s", SYSTEM_EVENT_NAME_PREFIX, eep->event_name); + + appsvc_set_operation(b, APPSVC_OPERATION_LAUNCH_ON_EVENT); + appsvc_set_uri(b, event_uri); + appsvc_set_appid(b, app_id); + + pid = aul_svc_run_service_async_for_uid(b, req_id++, NULL, eep->user_data, uid); + _D("uid(%d), pid(%d)", uid, pid); + + bundle_free(b); + } else { + _D("already is running or launch failed"); + } +} + +void __esd_check_event_launch_with_eventid(gpointer data, gpointer user_data) { + event_launch_item *el_item = (event_launch_item *)data; + esd_event_param *eep = (esd_event_param *)user_data; + + if (strcmp(eep->event_name, (char *)el_item->event_name) == 0) { + g_list_foreach(el_item->app_list_evtlaunch, + __esd_event_launch_with_appid, user_data); + } +} + +void __esd_launch_event_handler(char *event_name, bundle *data, + const bool is_user_event, gboolean trusted, + const uid_t sender_uid, char *sender_appid, void *user_data) { + const char *val; + const char *msg_type; + const char *msg_id; + esd_event_param *eep; + event_launch_item *el_item; + + _D("event_name(%s)", event_name); + + el_item = (event_launch_item *)g_hash_table_lookup(event_launch_table, event_name); + if (el_item == NULL) + return; + + if (el_item->app_list_evtlaunch != NULL) { + if (is_user_event == false) { + if (strcmp(SYS_EVENT_BATTERY_CHARGER_STATUS, event_name) == 0) { + val = bundle_get_val(data, EVT_KEY_BATTERY_CHARGER_STATUS); + _D("charger val(%s)", val); + if (val && (strcmp(EVT_VAL_BATTERY_CHARGER_CONNECTED, val) != 0)) + return; + } else if (strcmp(SYS_EVENT_USB_STATUS, event_name) == 0) { + val = bundle_get_val(data, EVT_KEY_USB_STATUS); + _D("usb val(%s)", val); + if (val && (strcmp(EVT_VAL_USB_CONNECTED, val) != 0)) + return; + } else if (strcmp(SYS_EVENT_EARJACK_STATUS, event_name) == 0) { + val = bundle_get_val(data, EVT_KEY_EARJACK_STATUS); + _D("earjack val(%s)", val); + if (val && (strcmp(EVT_VAL_EARJACK_CONNECTED, val) != 0)) + return; + } else if (strcmp(SYS_EVENT_INCOMMING_MSG, event_name) == 0) { + msg_type = bundle_get_val(data, EVT_KEY_MSG_TYPE); + _D("msg_type(%s)", msg_type); + if (msg_type == NULL) + return; + + msg_id = bundle_get_val(data, EVT_KEY_MSG_ID); + _D("msg_id(%s)", msg_id); + if (msg_id == NULL) + return; + } else if (strcmp(SYS_EVENT_WIFI_STATE, event_name) == 0) { + val = bundle_get_val(data, EVT_KEY_WIFI_STATE); + if (val == NULL) + return; + _D("wifi_state(%s)", val); + if (strcmp(EVT_VAL_WIFI_CONNECTED, val) != 0) + return; + } + } + + eep = (esd_event_param *)calloc(1, sizeof(esd_event_param)); + if (!eep) { + _E("memory alloc failed"); + return; + } + eep->event_name = event_name; + eep->event_data = data; + eep->sender_uid = sender_uid; + eep->sender_appid = sender_appid; + eep->is_user_event = is_user_event; + eep->trusted = (bool)trusted; + eep->user_data = (void *)user_data; + __esd_check_event_launch_with_eventid(el_item, eep); + free(eep); + } +} + +void __esd_print_earlier_event(gpointer data, gpointer user_data) { + earlier_item *item = (earlier_item *)data; + char *event_name = (char *)item->event_name; + const char *val; + + _D("event_name = (%s)", event_name); + + if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) { + if (item->earlier_data) { + val = bundle_get_val(item->earlier_data, EVT_KEY_BOOT_COMPLETED); + _D("boot_completed(%s)", val); + } + } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) { + if (item->earlier_data) { + val = bundle_get_val(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN); + _D("shutdown(%s)", val); + } + } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) { + if (item->earlier_data) { + val = bundle_get_val(item->earlier_data, EVT_KEY_LOW_MEMORY); + _D("low_memory(%s)", val); + } + } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) { + if (item->earlier_data) { + val = bundle_get_val(item->earlier_data, EVT_KEY_BATTERY_CHARGER_STATUS); + _D("charger_status(%s)", val); + } + } +} + +void __esd_earlier_table_print_items() { + GHashTableIter iter; + gpointer key; + gpointer value; + + g_hash_table_iter_init(&iter, earlier_event_table); + + while (g_hash_table_iter_next(&iter, &key, &value)) + __esd_print_earlier_event(value, NULL); +} + +void __esd_earlier_event_handler(char *event_name, bundle *data, void *user_data) { + earlier_item *item; + _D("event_name(%s)", event_name); + + item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name); + if (item) { + /* update earlier value */ + if (item->earlier_data != NULL) + bundle_free(item->earlier_data); + + item->earlier_data = bundle_dup(data); + } +} + +void __esd_event_handler(char *event_name, bundle *data, void *user_data) { + _D("event_name(%s)", event_name); + + if (__esd_check_earlier_support(event_name)) + __esd_earlier_event_handler(event_name, data, user_data); + + if (__esd_check_event_launch_support(event_name)) + __esd_launch_event_handler(event_name, data, + false, TRUE, ROOT_USER, NULL, user_data); +} + +void __esd_trusted_busname_remove_item(char *bus_name) { + GHashTableIter iter; + gpointer key; + gpointer value; + trusted_item *item; + + g_hash_table_iter_init(&iter, trusted_busname_table); + + while (g_hash_table_iter_next(&iter, &key, &value)) { + item = (trusted_item *)value; + if (item) { + if (strcmp(bus_name, item->bus_name) == 0) { + _D("remove trusted busname item(%s, %s)", item->app_id, item->bus_name); + FREE_AND_NULL(item->app_id); + FREE_AND_NULL(item->bus_name); + FREE_AND_NULL(item); + g_hash_table_iter_remove(&iter); + + __esd_trusted_busname_print_items(); + } + } + } +} + +void __esd_filter_name_owner_changed(GDBusConnection *connection, + const gchar *sender_name, const gchar *object_path, + const gchar *interface_name, const gchar *signal_name, + GVariant *parameters, gpointer user_data) { + char *name = NULL; + char *old_owner = NULL; + char *new_owner = NULL; + int old_len = 0; + int new_len = 0; + + g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner); + + if (strstr(name, "event.busname.session")) { + old_len = strlen(old_owner); + new_len = strlen(new_owner); + + _D("changed name(%s), old_onwer(%s)(%d) -> new_onwer(%s)(%d)", + name, old_owner, old_len, new_owner, new_len); + + if (old_len > 0 && new_len == 0) + __esd_trusted_busname_remove_item(name); + else if (old_len == 0 && new_len > 0) + _D("new name owned"); + else + _E("not-expected name change"); + } +} + +int __esd_dbus_name_monitor(GDBusConnection *connection) { + guint name_owner_changed_id = 0; + + name_owner_changed_id = g_dbus_connection_signal_subscribe(connection, + "org.freedesktop.DBus", "org.freedesktop.DBus", + "NameOwnerChanged", "/org/freedesktop/DBus", NULL, G_DBUS_SIGNAL_FLAGS_NONE, + __esd_filter_name_owner_changed, NULL, NULL); + + _I("name_owner_changed_id(%d)", name_owner_changed_id); + + return ES_R_OK; +} + +int __esd_get_user_items(uid_t uid) { + int ret = 0; + pkgmgrinfo_appinfo_filter_h handle = NULL; + + _I("get user items for uid(%d)", uid); + /* reset user's item */ + __esd_launch_table_remove_private_usr_items(); + + ret = pkgmgrinfo_appinfo_filter_create(&handle); + if (ret < 0) { + _E("failed to create appinfo filter"); + return ES_R_ERROR; + } + ret = pkgmgrinfo_appinfo_filter_add_string(handle, + PMINFO_APPINFO_PROP_APP_COMPONENT, "svcapp"); + if (ret < 0) { + _E("failed to add appinfo filter string"); + pkgmgrinfo_appinfo_filter_destroy(handle); + return ES_R_ERROR; + } + ret = pkgmgrinfo_appinfo_filter_add_string(handle, + PMINFO_APPINFO_PROP_APP_OPERATION, APPSVC_OPERATION_LAUNCH_ON_EVENT); + if (ret < 0) { + _E("failed to add appinfo filter string"); + pkgmgrinfo_appinfo_filter_destroy(handle); + return ES_R_ERROR; + } + ret = pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(handle, + __esd_add_appinfo_handler, &uid, uid); + if (ret < 0) { + _E("appinfo filter foreach error"); + pkgmgrinfo_appinfo_filter_destroy(handle); + return ES_R_ERROR; + } + pkgmgrinfo_appinfo_filter_destroy(handle); + + __esd_launch_table_print_items(); + + return ES_R_OK; +} + +void __esd_signal_handler(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) { + int handle; + bundle *b; + guint64 uid = 0; + + if (!g_strcmp0(signal_name, + SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED)) { + _I("System session finished"); + + b = bundle_create(); + bundle_add_str(b, EVT_KEY_BOOT_COMPLETED, + EVT_VAL_BOOT_COMPLETED_TRUE); + eventsystem_send_system_event(SYS_EVENT_BOOT_COMPLETED, b); + bundle_free(b); + + handle = creat(ESD_BOOT_COMPLETED, 0640); + if (handle != -1) + close(handle); + } else if (!g_strcmp0(signal_name, + SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED)) { + g_variant_get(parameters, "(t)", &uid); + _I("User session finished uid : %d", (int)uid); + if ((uid_t)uid != DEFAULT_USER) + __esd_get_user_items((uid_t)uid); + } +} + +static GDBusNodeInfo *introspection_data; + +int __esd_get_appid_by_pid_for_uid(int pid, uid_t uid, char *app_id, int buf_size) { + int retval = ES_R_OK; + int ret = 0; + + if (pid <= 0) { + _E("invalid pid(%d)", pid); + retval = ES_R_ERROR; + } else if (uid <= 0) { + _E("invalid uid(%d)", uid); + retval = ES_R_ERROR; + } else { + ret = aul_app_get_appid_bypid_for_uid(pid, app_id, buf_size, (uid_t)uid); + if (ret != AUL_R_OK) { + _E("failed to get appid by pid"); + retval = ES_R_ERROR; + } + _D("pid(%d)-uid(%d)-appid(%s)", pid, uid, app_id); + } + + return retval; +} + +int __esd_get_appid_by_pid(int pid, char *app_id, int buf_size) { + int ret; + int fd; + char buf[128] = { 0, }; + + ret = aul_app_get_appid_bypid(pid, app_id, buf_size); + if (ret != AUL_R_OK) { + snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); + + fd = open(buf, O_RDONLY); + if (fd < 0) + return ES_R_ERROR; + + ret = read(fd, app_id, buf_size - 1); + close(fd); + + if (ret <= 0) + return ES_R_ERROR; + + app_id[ret] = '\0'; + ret = ES_R_OK; + } + + return ret; +} + +int check_user_event_sender_valid(const char *event_name, const char *app_id) { + char *valid_name = NULL; + char *temp_name = NULL; + char *tmp = NULL; + int retval = ES_R_OK; + int len = 0; + int valid_name_len = 0; + + temp_name = strdup(event_name); + if (temp_name == NULL) { + _E("out of memory"); + return ES_R_ENOMEM; + } + + tmp = strrchr(temp_name, '.'); + if (tmp == NULL || strlen(tmp) == 0) { + _E("invalid event name"); + FREE_AND_NULL(temp_name); + return ES_R_EINVAL; + } + len = strlen(tmp); + if (len <= 1 || len > 128) { + _E("invalid length(%d) of user-defined name", len); + FREE_AND_NULL(temp_name); + return ES_R_EINVAL; + } + *tmp = '\0'; + + _D("app_id(%s), len(%zu)", app_id, strlen(app_id)); + + valid_name_len = strlen(USER_EVENT_NAME_PREFIX) + strlen(app_id) + 1; + valid_name = (char *)calloc(1, valid_name_len); + if (valid_name == NULL) { + _E("memory alloc failed"); + FREE_AND_NULL(temp_name); + return ES_R_ENOMEM; + } + snprintf(valid_name, valid_name_len, "%s%s", USER_EVENT_NAME_PREFIX, app_id); + _D("valid_name(%s)", valid_name); + + if (strcmp(temp_name, valid_name) != 0) { + _E("appid misamatch"); + retval = ES_R_EINVAL; + } + + FREE_AND_NULL(temp_name); + FREE_AND_NULL(valid_name); + + return retval; +} + +static const GDBusInterfaceVTable interface_vtable = { + esd::module::DbusEventModule::HandleMethodCallCb, + nullptr, + nullptr +}; + +void __esd_on_bus_acquired(GDBusConnection *connection, + const gchar *name, gpointer user_data) { + _I("bus acquired(%s)", name); + + guint reg_id = 0; + guint boot_id = 0; + guint user_boot_id = 0; + GError *error = NULL; + + reg_id = g_dbus_connection_register_object(connection, + ESD_OBJECT_PATH, + introspection_data->interfaces[0], + &interface_vtable, + user_data, NULL, &error); + if (reg_id == 0) { + _E("g_dbus_connection_register_object error(%s)", error->message); + g_error_free(error); + } + + boot_id = g_dbus_connection_signal_subscribe(connection, + NULL, + SYSTEMD_DBUS_IFACE_MANAGER, + SYSTEMD_DBUS_SIGNAL_STARTUP_FINISHED, + SYSTEMD_DBUS_PATH, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + __esd_signal_handler, + NULL, + NULL); + + if (boot_id == 0) + _E("g_dbus_connection_signal_subscribe() is failed."); + + user_boot_id = g_dbus_connection_signal_subscribe(connection, + NULL, + SYSTEMD_DBUS_IFACE_MANAGER, + SYSTEMD_DBUS_SIGNAL_USER_STARTUP_FINISHED, + SYSTEMD_DBUS_PATH, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + __esd_signal_handler, + NULL, + NULL); + + if (user_boot_id == 0) + _E("g_dbus_connection_signal_subscribe() is failed."); +} + +void __esd_on_name_acquired(GDBusConnection *connection, + const gchar *name, gpointer user_data) { + bundle *b; + + __esd_check_trusted_events(connection, "ListNames"); + __esd_check_trusted_events(connection, "ListActivatableNames"); + + b = bundle_create(); + bundle_add_str(b, EVT_KEY_ESD_STATUS, EVT_VAL_ESD_STARTED); + eventsystem_send_system_event(SYS_EVENT_ESD_STATUS, b); + bundle_free(b); + + __esd_register_vconf_callbacks(); + + __esd_trusted_busname_print_items(); + + __esd_get_user_items(DEFAULT_USER); + + __esd_dbus_name_monitor(connection); +} + +void __esd_on_name_lost(GDBusConnection *connection, + const gchar *name, gpointer user_data) { +} + +void __esd_pkgmgr_event_free(esd_pkgmgr_event *pkg_event) { + pkg_event->type = UNKNOWN; + if (pkg_event->pkgid) { + free(pkg_event->pkgid); + pkg_event->pkgid = NULL; + } +} + +int __esd_appcontrol_cb(const char *operation, + const char *uri, const char *mime, void *data) { + esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)data; + char *appid = NULL; + char *pkgid = NULL; + char *event_name = NULL; + uid_t uid = 0; + + if (cb_data == NULL) { + _E("invalid data"); + return 0; + } + appid = cb_data->appid; + pkgid = cb_data->pkgid; + uid = cb_data->uid; + + _D("uid(%d), appid(%s), pkgid(%s), operation(%s), uri(%s), mime(%s)", + uid, appid, pkgid, operation, uri, mime); + + if (!strcmp(operation, APPSVC_OPERATION_LAUNCH_ON_EVENT)) { + if (uri && !strncmp(uri, SYSTEM_EVENT_NAME_PREFIX, strlen(SYSTEM_EVENT_NAME_PREFIX))) { + event_name = strdup(&uri[8]); + if (event_name) { + _D("appid(%s), event_name(%s)", appid, event_name); + if (!__esd_check_event_launch_support(event_name)) + _E("failed to add item (not support event)"); + else if (!__esd_check_app_privileged_event(uid, appid, pkgid, event_name)) + _E("failed to add item (no privilege)"); + else if (__esd_add_launch_item(uid, event_name, appid, pkgid)) + _E("failed to add item"); + + } else { + _E("out of memory"); + } + } else if (uri && !strncmp(uri, USER_EVENT_NAME_PREFIX, strlen(USER_EVENT_NAME_PREFIX))) { + event_name = strdup(uri); + if (event_name) { + _D("appid(%s), event_name(%s)", appid, event_name); + if (__esd_check_platform_cert(pkgid, uid)) { + if (__esd_add_launch_item(uid, event_name, appid, pkgid)) + _E("failed to add item"); + } + } else { + _E("out of memory"); + } + } + FREE_AND_NULL(event_name); + } + + return 0; +} + +int __esd_add_appinfo_handler(const pkgmgrinfo_appinfo_h handle, void *data) { + char *appid = NULL; + char *pkgid = NULL; + int ret = 0; + uid_t *p_uid = NULL; + + if (data == NULL) { + _E("invalid data"); + return ES_R_ERROR; + } + + p_uid = (uid_t *)data; + + ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid); + if (ret < 0) { + _E("failed to get appid"); + return ES_R_ERROR; + } + + ret = pkgmgrinfo_appinfo_get_appid(handle, &appid); + if (ret < 0) { + _E("failed to get appid"); + return ES_R_ERROR; + } + + esd_appctrl_cb_data *cb_data = (esd_appctrl_cb_data *)calloc(1, sizeof(esd_appctrl_cb_data)); + + if (cb_data == NULL) { + _E("memory alloc failed"); + return ES_R_ENOMEM; + } + cb_data->appid = strdup(appid); + if (cb_data->appid == NULL) { + _E("out_of_memory"); + FREE_AND_NULL(cb_data); + return ES_R_ENOMEM; + } + cb_data->pkgid = strdup(pkgid); + if (cb_data->pkgid == NULL) { + _E("out_of_memory"); + FREE_AND_NULL(cb_data->appid); + FREE_AND_NULL(cb_data); + return ES_R_ENOMEM; + } + cb_data->uid = *p_uid; + + ret = pkgmgrinfo_appinfo_foreach_appcontrol(handle, + (pkgmgrinfo_app_control_list_cb)__esd_appcontrol_cb, cb_data); + + FREE_AND_NULL(cb_data->pkgid); + FREE_AND_NULL(cb_data->appid); + FREE_AND_NULL(cb_data); + + if (ret < 0) { + _E("failed to get appcontrol info"); + return ES_R_ERROR; + } + + return ES_R_OK; +} + +int __esd_pkgmgr_event_callback(uid_t target_uid, int req_id, + const char *pkg_type, const char *pkgid, const char *key, + const char *val, const void *pmsg, void *data) { + esd_pkgmgr_event *pkg_event = (esd_pkgmgr_event *)data; + pkgmgrinfo_pkginfo_h handle = NULL; + int ret = 0; + + _D("target_uid(%d), req_id(%d), pkg_type(%s), pkgid(%s), key(%s), val(%s)", + target_uid, req_id, pkg_type, pkgid, key, val); + + if (strncmp(key, "start", strlen(key)) == 0) { + if (strcmp(val, "install") == 0) { + _D("install start"); + pkg_event->type = INSTALL; + } else if (strcmp(val, "uninstall") == 0) { + _D("unistall start"); + pkg_event->type = UNINSTALL; + } else if (strcmp(val, "update") == 0) { + _D("update start"); + pkg_event->type = UPDATE; + } else { + _D("val(%s) start", val); + __esd_pkgmgr_event_free(pkg_event); + } + } else if (strcmp(key, "end") == 0 && strcmp(val, "ok") == 0) { + if (pkg_event->type == INSTALL || pkg_event->type == UPDATE) { + _D("install end (ok)"); + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, target_uid, &handle); + if (ret < 0) { + _E("failed to get pkginfo"); + __esd_pkgmgr_event_free(pkg_event); + return 0; + } + ret = pkgmgrinfo_appinfo_get_usr_list(handle, + PMINFO_SVC_APP, __esd_add_appinfo_handler, &target_uid, target_uid); + if (ret < 0) { + _E("failed to get appinfo"); + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + __esd_pkgmgr_event_free(pkg_event); + return 0; + } + ret = pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + if (ret < 0) { + _E("failed to destroy pkginfo"); + __esd_pkgmgr_event_free(pkg_event); + return 0; + } + } else if (pkg_event->type == UNINSTALL) { + _D("uninstall end (ok)"); + __esd_launch_table_remove_items(target_uid, pkgid); + __esd_launch_table_print_items(); + } + __esd_pkgmgr_event_free(pkg_event); + } else if (strcmp(key, "end") == 0 && strcmp(val, "fail") == 0) { + _E("pkg_event(%d) falied", pkg_event->type); + __esd_pkgmgr_event_free(pkg_event); + } else { + if (strcmp(key, "install_percent") != 0) + __esd_pkgmgr_event_free(pkg_event); + } + + return 0; +} + +void __esd_remove_esd_list_item(gpointer data, gpointer user_data) { + esd_list_item_s *item = (esd_list_item_s *)data; + + free(item->app_id); + free(item->pkg_id); +} + +} // namespace + +namespace esd::module { + +bool DbusEventModule::Startup(api::ToolBox* tools) { + tools_ = tools; + if (!Init()) + return false; + return BeforeLoop(); +} + +void DbusEventModule::Shutdown() { + Fini(); +} + +bool DbusEventModule::Init() { + int req_id = 0; + int ret = 0; + pkgmgr_client *client; + esd_pkgmgr_event *pkg_event; + + __esd_init_cynara(); + + client = pkgmgr_client_new(PC_LISTENING); + if (client == NULL) { + _E("set pkgmgr client failed"); + __esd_finish_cynara(); + return false; + } + + pkg_event = (esd_pkgmgr_event *)calloc(1, sizeof(esd_pkgmgr_event)); + if (pkg_event == NULL) { + _E("memory alloc failed"); + ret = pkgmgr_client_free(client); + if (ret != PKGMGR_R_OK) + _E("pkgmgr_client_free failed(%d)", ret); + __esd_finish_cynara(); + return false; + } + + req_id = pkgmgr_client_listen_status(client, __esd_pkgmgr_event_callback, pkg_event); + if (req_id < 0) { + _E("pkgmgr client listen failed"); + ret = pkgmgr_client_free(client); + if (ret != PKGMGR_R_OK) + _E("pkgmgr_client_free failed(%d)", ret); + free(pkg_event); + __esd_finish_cynara(); + return false; + } + + s_info.client = client; + + _I("esd init done"); + + return true; +} + +void DbusEventModule::Fini() { + gpointer key; + gpointer value; + GHashTableIter iter; + trusted_item *item; + event_launch_item *el_item; + int ret = 0; + earlier_item *er_item; + + _D("esd finalize"); + + if (trusted_busname_table) { + g_hash_table_iter_init(&iter, trusted_busname_table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + item = (trusted_item *)value; + if (item) { + free(item->app_id); + free(item->bus_name); + free(item); + } else { + _E("item is null"); + } + g_hash_table_iter_remove(&iter); + } + g_hash_table_unref(trusted_busname_table); + } + + if (earlier_event_table) { + g_hash_table_iter_init(&iter, earlier_event_table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + er_item = (earlier_item *)value; + if (er_item) { + eventsystem_unregister_event(er_item->reg_id); + free(er_item->event_name); + bundle_free(er_item->earlier_data); + free(er_item); + } else { + _E("ealier item is NULL"); + } + g_hash_table_iter_remove(&iter); + } + g_hash_table_unref(earlier_event_table); + } + + g_hash_table_destroy(user_last_event_table); + + if (event_launch_table) { + g_hash_table_iter_init(&iter, event_launch_table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + el_item = (event_launch_item *)value; + if (el_item) { + eventsystem_unregister_event(el_item->reg_id); + free(el_item->event_name); + g_list_foreach(el_item->app_list_evtlaunch, + __esd_remove_esd_list_item, NULL); + g_list_free(el_item->app_list_evtlaunch); + free(el_item); + } else { + _E("item is NULL"); + } + g_hash_table_iter_remove(&iter); + } + g_hash_table_unref(event_launch_table); + } + + if (introspection_data) + g_dbus_node_info_unref(introspection_data); + + if (s_info.client) { + ret = pkgmgr_client_free(s_info.client); + if (ret != PKGMGR_R_OK) + _E("pkgmgr_client_free failed(%d)", ret); + } + + __esd_finish_cynara(); + + _D("esd finalize end"); +} + +bool DbusEventModule::BeforeLoop() { + int ret = 0; + GError *error = NULL; + guint owner_id = 0; + + guint subscription_id = 0; + int i; + int size; + char *event_name; + int fd; + int val; + int status; + int charger_status; + int charge_now; + earlier_item *item; + + earlier_event_table = g_hash_table_new(g_str_hash, g_str_equal); + user_last_event_table = g_hash_table_new_full(g_str_hash, + g_str_equal, NULL, (GDestroyNotify)free_saved_event); + + _I("register events for earlier_data"); + size = sizeof(earlier_event_list)/sizeof(*earlier_event_list); + for (i = 0; i < size; i++) { + event_name = (char *)earlier_event_list[i]; + _I("event_name(%s)", event_name); + + item = (earlier_item *)calloc(1, sizeof(earlier_item)); + if (item == NULL) { + _E("memery alloc failed"); + return false; + } + item->event_name = strdup(event_name); + if (item->event_name == NULL) { + _E("out of memory"); + free(item); + return false; + } + + /* set initial data */ + if (strcmp(event_name, SYS_EVENT_BOOT_COMPLETED) == 0) { + fd = open(ESD_BOOT_COMPLETED, O_RDONLY); + if (fd < 0) { + _D("open file error(%d)", fd); + } else { + item->earlier_data = bundle_create(); + bundle_add_str(item->earlier_data, EVT_KEY_BOOT_COMPLETED, + EVT_VAL_BOOT_COMPLETED_TRUE); + close(fd); + } + } else if (strcmp(event_name, SYS_EVENT_SYSTEM_SHUTDOWN) == 0) { + ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &val); + if (ret != VCONF_OK) { + _E("failed to get power_off status (%d)", ret); + } else { + if (val == VCONFKEY_SYSMAN_POWER_OFF_DIRECT || + val == VCONFKEY_SYSMAN_POWER_OFF_RESTART) { + /* power-off requested */ + item->earlier_data = bundle_create(); + bundle_add_str(item->earlier_data, EVT_KEY_SYSTEM_SHUTDOWN, + EVT_VAL_SYSTEM_SHUTDOWN_TRUE); + } + } + } else if (strcmp(event_name, SYS_EVENT_LOW_MEMORY) == 0) { + ret = vconf_get_int(VCONFKEY_SYSMAN_LOW_MEMORY, &status); + if (ret != VCONF_OK) { + _E("failed to get low_memory status (%d)", ret); + } else { + item->earlier_data = bundle_create(); + if (status == VCONFKEY_SYSMAN_LOW_MEMORY_SOFT_WARNING) + bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY, + EVT_VAL_MEMORY_SOFT_WARNING); + else if (status == VCONFKEY_SYSMAN_LOW_MEMORY_HARD_WARNING) + bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY, + EVT_VAL_MEMORY_HARD_WARNING); + else + bundle_add_str(item->earlier_data, EVT_KEY_LOW_MEMORY, + EVT_VAL_MEMORY_NORMAL); + } + } else if (strcmp(event_name, SYS_EVENT_BATTERY_CHARGER_STATUS) == 0) { + ret = vconf_get_int(VCONFKEY_SYSMAN_CHARGER_STATUS, &charger_status); + if (ret != VCONF_OK) { + _E("failed to get charger_status (%d)", ret); + } else { + ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &charge_now); + if (ret != VCONF_OK) + _E("failed to get charge_now (%d)", ret); + } + + if (ret == VCONF_OK) { + item->earlier_data = bundle_create(); + if (charger_status == VCONFKEY_SYSMAN_CHARGER_CONNECTED) { + if (charge_now == 0) { + bundle_add_str(item->earlier_data, + EVT_KEY_BATTERY_CHARGER_STATUS, + EVT_VAL_BATTERY_CHARGER_DISCHARGING); + } else { + bundle_add_str(item->earlier_data, + EVT_KEY_BATTERY_CHARGER_STATUS, + EVT_VAL_BATTERY_CHARGER_CHARGING); + } + } else { + bundle_add_str(item->earlier_data, + EVT_KEY_BATTERY_CHARGER_STATUS, + EVT_VAL_BATTERY_CHARGER_DISCONNECTED); + } + } + } + + eventsystem_register_event(event_name, &subscription_id, + (eventsystem_handler)__esd_event_handler, NULL); + if (subscription_id == 0) { + _E("signal subscription error, event_name(%s)", event_name); + if (item->earlier_data) + bundle_free(item->earlier_data); + free(item->event_name); + free(item); + + return false; + } else { + item->reg_id = subscription_id; + } + + g_hash_table_insert(earlier_event_table, event_name, item); + } + + __esd_earlier_table_print_items(); + + event_launch_table = g_hash_table_new(g_str_hash, g_str_equal); + trusted_busname_table = g_hash_table_new(g_str_hash, g_str_equal); + + /* gdbus setup for method call */ + introspection_data = g_dbus_node_info_new_for_xml(INTROSPECTION_XML, &error); + if (!introspection_data) { + _E("g_dbus_node_info_new_for_xml error(%s)", error->message); + g_error_free(error); + return false; + } + + owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, + ESD_BUS_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + __esd_on_bus_acquired, + __esd_on_name_acquired, + __esd_on_name_lost, + this, NULL); + if (!owner_id) { + _E("g_bus_own_name error"); + g_dbus_node_info_unref(introspection_data); + return false; + } + + _I("esd before_loop done"); + + return true; +} + +void DbusEventModule::HandleMethodCallCb(GDBusConnection *connection, + const gchar *sender, const gchar *object_path, + const gchar *interface_name, const gchar *method_name, + GVariant *parameters, GDBusMethodInvocation *invocation, + gpointer user_data) { + + static std::map> dispatcher = { + { "CheckSenderValidation", &DbusEventModule::CheckSenderValidMethodCall }, + { "GetTrustedPeerList", &DbusEventModule::GetTrustedPeerMethodCall }, + { "SetupTrustedPeer", &DbusEventModule::SetupTrustedPeerMethodCall }, + { "CheckPrivilegeValidation", &DbusEventModule::CheckPrivilegeValidMethodCall }, + { "CheckUserSendValidation", &DbusEventModule::CheckSendEventValidMethodCall }, + { "GetEarlierData", &DbusEventModule::GetEarlierDataMethodCall }, + { "KeepLastData", &DbusEventModule::KeepLastDataMethodCall }, + { "CheckLastData", &DbusEventModule::CheckLastDataMethodCall }, + { "LaunchOnEventFromUserEvent", &DbusEventModule::LaunchOnEventFromUserEventMethodCall }, + { "CionGetUuid", &DbusEventModule::GetUuidMethodCall }, + { "CionSetDisplayName", &DbusEventModule::SetDisplayNameMethodCall }, + { "CionGetDisplayName", &DbusEventModule::GetDisplayNameMethodCall }, + { "CionSetEnabled", &DbusEventModule::SetEnabledMethodCall }, + { "CionGetEnabled", &DbusEventModule::GetEnabledMethodCall } + }; + + if (dispatcher.find(method_name) == dispatcher.end()) + return; + + auto* mod = reinterpret_cast(user_data); + dispatcher[method_name](*mod, connection, sender, parameters, invocation); +} + +std::string DbusEventModule::GetSenderAppId(GDBusConnection* connection, + const gchar* sender) { + int sender_pid = __get_sender_pid(connection, sender); + char app_id[128] = { 0, }; + if (__esd_get_appid_by_pid(sender_pid, app_id, sizeof(app_id)) < 0) { + _E("failed to get appid by pid"); + return ""; + } + + return app_id; +} + +void DbusEventModule::CheckSendEventValidMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant *param = NULL; + int result = 0; + char *event_name = NULL; + char app_id[128] = {0, }; + int sender_pid = 0; + uid_t sender_uid = 0; + + g_variant_get(parameters, "(&s)", &event_name); + _D("event_name(%s)", event_name); + + sender_pid = __get_sender_pid(connection, sender); + sender_uid = (uid_t)__get_sender_uid(connection, sender); + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { + result = ES_R_ERROR; + } else { + if (check_user_event_sender_valid(event_name, app_id) < 0) { + _E("invalid sender"); + result = ES_R_EINVAL; + } else { + result = 1; + } + } + + param = g_variant_new("(i)", result); + _D("event_name(%s), result(%d)", event_name, result); + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::CheckSenderValidMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant *param = NULL; + int result = 0; + char *event_name = NULL; + char app_id[128] = {0, }; + int event_sender_pid = 0; + uid_t sender_uid = 0; + + g_variant_get(parameters, "(i&s)", &event_sender_pid, &event_name); + _D("event_sender_pid(%d), event_name(%s)", event_sender_pid, event_name); + + sender_uid = (uid_t)__get_sender_uid(connection, sender); + if (__esd_get_appid_by_pid_for_uid(event_sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { + result = ES_R_ERROR; + } else { + if (check_user_event_sender_valid(event_name, app_id) < 0) { + _E("invalid sender"); + result = ES_R_EINVAL; + } else { + result = 1; + } + } + + param = g_variant_new("(is)", result, app_id); + _D("event_name(%s), result(%d)", event_name, result); + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::GetTrustedPeerMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant *param = NULL; + int result = 0; + GVariantBuilder *builder = NULL; + GHashTableIter iter; + gpointer key, value; + char *event_name = NULL; + char app_id[128] = {0, }; + int sender_pid = 0; + uid_t sender_uid = 0; + int ret = 0; + uid_t uid = 0; + char *_appid = NULL; + char *_busname = NULL; + trusted_item *item; + + g_variant_get(parameters, "(&s)", &event_name); + _D("event_name(%s)", event_name); + + sender_pid = __get_sender_pid(connection, sender); + sender_uid = (uid_t)__get_sender_uid(connection, sender); + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { + result = ES_R_ERROR; + } else { + builder = g_variant_builder_new(G_VARIANT_TYPE("as")); + + g_hash_table_iter_init(&iter, trusted_busname_table); + while (g_hash_table_iter_next(&iter, &key, &value)) { + item = (trusted_item *)value; + uid = item->uid; + _appid = item->app_id; + _busname = item->bus_name; + + if (uid != GLOBAL_USER && uid != sender_uid) + continue; + + ret = __esd_check_certificate_match(uid, _appid, sender_uid, app_id); + if (ret == ES_R_OK) + g_variant_builder_add(builder, "s", _busname); + } + + result = 1; + } + + param = g_variant_new("(ias)", result, builder); + _D("result(%d)", result); + g_dbus_method_invocation_return_value(invocation, param); + if (builder) + g_variant_builder_unref(builder); +} + +void DbusEventModule::SetupTrustedPeerMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant *param = NULL; + int result = 0; + char *event_name = NULL; + char *destination_name = NULL; + char app_id[128] = {0, }; + int sender_pid = 0; + uid_t sender_uid = 0; + int ret = 0; + + g_variant_get(parameters, "(&s&s)", &event_name, &destination_name); + _D("event_name(%s), destination_name(%s)", event_name, destination_name); + + if (destination_name && destination_name[0] != '\0') { + sender_pid = __get_sender_pid(connection, sender); + sender_uid = (uid_t)__get_sender_uid(connection, sender); + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { + result = ES_R_ERROR; + } else { + ret = __esd_trusted_busname_add_item(sender_uid, app_id, destination_name, + sender_pid); + if (ret < 0) { + _E("failed to add trusted busname item"); + result = ES_R_ERROR; + } else { + result = 1; + } + } + } else { + _E("invalid destination name"); + result = ES_R_ERROR; + } + + param = g_variant_new("(i)", result); + _D("event_name(%s), result(%d)", event_name, result); + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::CheckPrivilegeValidMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant *param = NULL; + int result = 0; + char *event_name = NULL; + char *privilege_name = NULL; + char app_id[128] = {0, }; + int sender_pid = 0; + uid_t sender_uid = 0; + char *client = NULL; + char *session = NULL; + char *user = NULL; + int ret = 0; + + g_variant_get(parameters, "(&s)", &event_name); + __esd_check_privilege_name(event_name, &privilege_name); + _D("event_name(%s), privilege_name(%s)", event_name, privilege_name); + + if (privilege_name) { + sender_pid = __get_sender_pid(connection, sender); + sender_uid = (uid_t)__get_sender_uid(connection, sender); + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, sizeof(app_id)) < 0) { + result = ES_R_ERROR; + } else { + ret = cynara_creds_gdbus_get_client(connection, sender, CLIENT_METHOD_DEFAULT, &client); + if (ret != CYNARA_API_SUCCESS) { + _E("failed to get client"); + result = ES_R_EINVAL; + goto out; + } + + ret = cynara_creds_gdbus_get_user(connection, sender, USER_METHOD_DEFAULT, &user); + if (ret != CYNARA_API_SUCCESS) { + _E("failed to get user"); + result = ES_R_EINVAL; + goto out; + } + + session = cynara_session_from_pid(sender_pid); + if (session == NULL) { + _E("failed to get session"); + result = ES_R_EINVAL; + goto out; + } + + _D("app_id(%s), client(%s), session(%s), user(%s)", app_id, client, session, user); + if (__esd_check_valid_privilege_by_cynara(app_id, client, session, user, privilege_name)) + result = 1; + else + result = ES_R_EINVAL; + } + } else { + result = 1; + } + +out: + g_free(client); + g_free(user); + g_free(session); + param = g_variant_new("(i)", result); + _D("event_name(%s), result(%d)", event_name, result); + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::GetEarlierDataMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant *param = NULL; + int result = ES_R_ERROR; + char *event_name = NULL; + bundle *b = NULL; + bundle_raw *raw = NULL; + int len = 0; + earlier_item *item; + + g_variant_get(parameters, "(&s)", &event_name); + _D("event_name(%s)", event_name); + + item = (earlier_item *)g_hash_table_lookup(earlier_event_table, event_name); + if (item != NULL) { + if (item->earlier_data) { + b = bundle_dup(item->earlier_data); + bundle_add_str(b, "is_earlier_data", "true"); + result = ES_R_OK; + } + } + + if (result == ES_R_ERROR) + b = bundle_create(); + + bundle_encode(b, &raw, &len); + bundle_free(b); + + param = g_variant_new("(iis)", result, len, raw); + + _D("result(%d), len(%d)", result, len); + g_dbus_method_invocation_return_value(invocation, param); + + bundle_free_encoded_rawdata(&raw); +} + +void DbusEventModule::KeepLastDataMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant *param; + int result = ES_R_OK; + char *event_name; + char *own_name; + char *key; + char app_id[128]; + int sender_pid; + uid_t sender_uid; + struct __last_event_item *item; + + g_variant_get(parameters, "(&s&s)", &event_name, &own_name); + + if (!event_name || !own_name) { + result = ES_R_ERROR; + _E("invalid event_name and own_name"); + goto out; + } + + sender_pid = __get_sender_pid(connection, sender); + sender_uid = (uid_t)__get_sender_uid(connection, sender); + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, + sizeof(app_id)) < 0) { + _E("failed to get appid by pid"); + result = ES_R_ERROR; + goto out; + } + + key = (char *)malloc(sizeof(event_name) + 10); + if (!key) { + result = ES_R_ENOMEM; + _E("out of memory"); + goto out; + } + + snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid); + item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table, + key); + if (!item) { + item = (struct __last_event_item *)calloc(1, sizeof(*item)); + if (!item) { + result = ES_R_ERROR; + goto out; + } + item->key = key; + item->event_name = strdup(event_name); + item->own_name = strdup(own_name); + item->uid = sender_uid; + item->app_id = strdup(app_id); + g_hash_table_insert(user_last_event_table, + item->key, item); + } else { + free(item->own_name); + item->own_name = strdup(own_name); + } + +out: + param = g_variant_new("(i)", result); + + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::CheckLastDataMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant *param; + int result = ES_R_OK; + char *event_name; + char *own_name; + char *key; + char app_id[128]; + int sender_pid; + uid_t sender_uid; + struct __last_event_item *item; + + g_variant_get(parameters, "(&s&s)", &event_name, &own_name); + + if (!event_name || !own_name) { + result = ES_R_ERROR; + _E("invalid event_name and own_name"); + goto out; + } + + sender_pid = __get_sender_pid(connection, sender); + sender_uid = (uid_t)__get_sender_uid(connection, sender); + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, + sizeof(app_id)) < 0) { + result = ES_R_ERROR; + _E("failed to get appid by pid"); + goto out; + } + + key = (char *)malloc(sizeof(event_name) + 10); + if (!key) { + result = ES_R_ENOMEM; + _E("out of memory"); + goto out; + } + + snprintf(key, sizeof(event_name) + 10, "%s_%d", event_name, sender_uid); + item = (struct __last_event_item *)g_hash_table_lookup(user_last_event_table, + key); + free(key); + if (item) { + GVariant *gv; + bundle *b; + bundle_raw *raw; + int len; + int ret; + GError *error = NULL; + + b = bundle_create(); + if (!b) { + result = ES_R_ERROR; + goto out; + } + bundle_add_str(b, EVT_KEY_KEPT_EVENT_NAME, event_name); + bundle_add_str(b, EVT_KEY_KEPT_OWN_NAME, own_name); + if (__esd_check_certificate_match(item->uid, item->app_id, + sender_uid, app_id) == ES_R_OK) + bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "true"); + else + bundle_add_str(b, EVT_KEY_KEPT_IS_TRUSTED, "false"); + + bundle_encode(b, &raw, &len); + gv = g_variant_new("(us)", len, raw); + ret = g_dbus_connection_emit_signal(connection, + item->own_name, + SYS_EVENT_OBJ_PATH, + SYS_EVENT_NAME_PREFIX, + REQUEST_LAST_DATA, + gv, + &error); + if (ret == FALSE) { + _E("Unable to emit signal: %s", error->message); + g_error_free(error); + } + bundle_free_encoded_rawdata(&raw); + bundle_free(b); + } + +out: + param = g_variant_new("(i)", result); + + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::LaunchOnEventFromUserEventMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant *param; + int result = ES_R_OK; + int len; + gboolean trusted; + int sender_pid; + uid_t sender_uid; + char *event_name; + char app_id[128]; + char *buf; + bundle *b; + + g_variant_get(parameters, "(&s&sib)", &event_name, &buf, &len, &trusted); + + if (!event_name) { + result = ES_R_ERROR; + _E("invalid event_name"); + goto out; + } + + sender_pid = __get_sender_pid(connection, sender); + sender_uid = (uid_t)__get_sender_uid(connection, sender); + if (__esd_get_appid_by_pid_for_uid(sender_pid, sender_uid, app_id, + sizeof(app_id)) < 0) { + _E("failed to get appid by pid"); + result = ES_R_ERROR; + goto out; + } + + b = bundle_decode((bundle_raw *)buf, len); + if (b == NULL) { + _E("Out of memory"); + result = ES_R_ENOMEM; + goto out; + } + + __esd_launch_event_handler(event_name, b, true, trusted, + sender_uid, app_id, NULL); + + bundle_free(b); + +out: + param = g_variant_new("(i)", result); + + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::GetUuidMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant* param = nullptr; + int result = ES_R_OK; + std::optional uuid; + + std::string app_id = GetSenderAppId(connection, sender); + if (app_id.empty()) { + param = g_variant_new("(is)", ES_R_ERROR, ""); + g_dbus_method_invocation_return_value(invocation, param); + return; + } + + if (tools_->GetMethodBroker().Invoke("Cion.GetUuidWithGenerate", + app_id, uuid)) { + param = g_variant_new("(is)", ES_R_OK, (*uuid).c_str()); + } else { + result = ES_R_ERROR; + } + + if (param == nullptr) + param = g_variant_new("(is)", result, ""); + + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::SetDisplayNameMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant* param = nullptr; + int result = ES_R_OK; + char* display_name = nullptr; + char* service_name = nullptr; + int ret = 0; + + std::string app_id = GetSenderAppId(connection, sender); + if (app_id.empty()) { + param = g_variant_new("(i)", ES_R_ERROR); + g_dbus_method_invocation_return_value(invocation, param); + return; + } + + g_variant_get(parameters, "(&s&s)", &service_name, &display_name); + + if (!tools_->GetMethodBroker().Invoke("Cion.SetDisplayName", app_id, + service_name, display_name, ret)) { + result = ES_R_ERROR; + } + + if (ret != 0) + result = ES_R_ERROR; + + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::GetDisplayNameMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant* param = nullptr; + int result = ES_R_OK; + char* service_name = nullptr; + std::string display_name; + int ret = -1; + + std::string app_id = GetSenderAppId(connection, sender); + if (app_id.empty()) { + param = g_variant_new("(is)", ES_R_ERROR, ""); + g_dbus_method_invocation_return_value(invocation, param); + return; + } + + g_variant_get(parameters, "(&s)", &service_name); + + if (tools_->GetMethodBroker().Invoke("Cion.GetDisplayName", + app_id.c_str(), service_name, display_name, ret)) { + if (ret == 0) + param = g_variant_new("(is)", result, display_name); + } else { + result = ES_R_ERROR; + } + + if (param == nullptr) + param = g_variant_new("(is)", result, ""); + + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::SetEnabledMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant* param = nullptr; + int result = ES_R_OK; + gboolean enabled; + char* service_name = nullptr; + int ret = -1; + + std::string app_id = GetSenderAppId(connection, sender); + if (app_id.empty()) { + param = g_variant_new("(i)", ES_R_ERROR); + g_dbus_method_invocation_return_value(invocation, param); + return; + } + + g_variant_get(parameters, "(&sb)", &service_name, &enabled); + + if (!tools_->GetMethodBroker().Invoke("Cion.SetEnabled", app_id, + service_name, (bool)enabled, ret)) { + result = ES_R_ERROR; + } + + if (ret != 0) + result = ES_R_ERROR; + + param = g_variant_new("(i)", result); + g_dbus_method_invocation_return_value(invocation, param); +} + +void DbusEventModule::GetEnabledMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation) { + GVariant* param = nullptr; + int result = ES_R_OK; + char* service_name = nullptr; + bool enabled = false; + int ret = -1; + + std::string app_id = GetSenderAppId(connection, sender); + if (app_id.empty()) { + param = g_variant_new("(ib)", ES_R_ERROR, false); + g_dbus_method_invocation_return_value(invocation, param); + return; + } + + g_variant_get(parameters, "(&s)", &service_name); + if (!tools_->GetMethodBroker().Invoke("Cion.GetEnabled", app_id, + service_name, enabled, ret)) { + result = ES_R_ERROR; + } else if (ret != 0) { + result = ES_R_ERROR; + } else { + param = g_variant_new("(ib)", result, enabled); + } + + if (param == nullptr) + param = g_variant_new("(ib)", result, false); + + g_dbus_method_invocation_return_value(invocation, param); +} + + +} // namespace esd::module \ No newline at end of file diff --git a/src/modules/dbus_event/dbus_event_module.hh b/src/modules/dbus_event/dbus_event_module.hh new file mode 100644 index 0000000..29788a9 --- /dev/null +++ b/src/modules/dbus_event/dbus_event_module.hh @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef EVENTSYSTEM_MODULES_DBUS_EVENT_DBUS_EVENT_MODULE_HH_ +#define EVENTSYSTEM_MODULES_DBUS_EVENT_DBUS_EVENT_MODULE_HH_ + +#include +#include + +#include + +namespace esd::module { + +class DbusEventModule : public api::IModule { + public: + DbusEventModule() = default; + virtual ~DbusEventModule() = default; + + bool Startup(api::ToolBox* tools) override; + void Shutdown() override; + + static void HandleMethodCallCb(GDBusConnection *connection, + const gchar *sender, const gchar *object_path, + const gchar *interface_name, const gchar *method_name, + GVariant *parameters, GDBusMethodInvocation *invocation, + gpointer user_data); + + private: + bool Init(); + void Fini(); + bool BeforeLoop(); + void GetUuidMethodCall(GDBusConnection* connection, const gchar* sender, + GVariant* parameters, GDBusMethodInvocation* invocation); + void SetDisplayNameMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, GDBusMethodInvocation* invocation); + void GetDisplayNameMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void SetEnabledMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void GetEnabledMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void CheckSenderValidMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void GetTrustedPeerMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void SetupTrustedPeerMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void CheckPrivilegeValidMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void GetEarlierDataMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void KeepLastDataMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void CheckLastDataMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void LaunchOnEventFromUserEventMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + void CheckSendEventValidMethodCall(GDBusConnection* connection, + const gchar* sender, GVariant* parameters, + GDBusMethodInvocation* invocation); + std::string GetSenderAppId(GDBusConnection* connection, const gchar* sender); + + private: + api::ToolBox* tools_ = nullptr; +}; + +} // namespace esd::module + +#endif // EVENTSYSTEM_MODULES_DBUS_EVENT_DBUS_EVENT_MODULE_HH_ \ No newline at end of file diff --git a/src/modules/dbus_event/esd_system_event.cc b/src/modules/dbus_event/esd_system_event.cc new file mode 100644 index 0000000..816353e --- /dev/null +++ b/src/modules/dbus_event/esd_system_event.cc @@ -0,0 +1,561 @@ +#include +#include +#include +#include +#include +#include + +#include + +namespace { + +/* table item : sent system-event by esd */ +static GHashTable *esd_sent_table; + +typedef struct __esd_sent_table_item { + char *event_name; + bundle *event_data; +} esd_sent_item; + +struct esd_vconf_handler { + const char *key; + void (*esd_vconfcb_fn) (keynode_t *node, void *user_data); +}; + +int __esd_event_data_compare(bundle *b1, bundle *b2, const char *key) { + int ret = 0; + int tmp1 = 0; + int tmp2 = 0; + char *str1 = NULL; + char *str2 = NULL; + + if (bundle_get_count(b1) == bundle_get_count(b2)) { + tmp1 = bundle_get_str(b1, key, &str1); + tmp2 = bundle_get_str(b2, key, &str2); + if (tmp1 == BUNDLE_ERROR_NONE && tmp2 == BUNDLE_ERROR_NONE) { + if (strcmp(str1, str2) != 0) { + _D("new event_data : value check"); + ret = 1; + } + } + } else { + _D("new event_data : bundle_count check"); + ret = 1; + } + + if (ret == 0) + _D("same event_data"); + + return ret; +} + +int __esd_send_system_event(const char *event_name, bundle *b, const char *key) { + int ret = ES_R_OK; + esd_sent_item *item = + (esd_sent_item *)g_hash_table_lookup(esd_sent_table, event_name); + + if (item && __esd_event_data_compare(item->event_data, b, key) == 0) { + _D("skip send: same with previous data"); + } else { + ret = eventsystem_send_system_event(event_name, b); + if (ret != ES_R_OK) { + _E("failed to send event"); + goto out; + } + + if (item) { + bundle_free(item->event_data); + item->event_data = bundle_dup(b); + } else { + item = (esd_sent_item *)calloc(1, sizeof(esd_sent_item)); + if (item == NULL) { + _E("memory alloc failed"); + ret = ES_R_ERROR; + goto out; + } + item->event_name = strdup(event_name); + if (item->event_name == NULL) { + _E("out of memory"); + free(item); + item = nullptr; + ret = ES_R_ERROR; + goto out; + } + item->event_data = bundle_dup(b); + } + + g_hash_table_insert(esd_sent_table, item->event_name, item); + } + +out: + return ret; +} + +void __esd_vconfcb_location_use_mylocation(keynode_t *node, void *user_data) { + int ret = 0; + int enabled = 0; + bundle *b = NULL; + const char *key = NULL; + const char *val = NULL; + + _D("vconfcb called"); + + ret = vconf_get_int(VCONFKEY_LOCATION_USE_MY_LOCATION, &enabled); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + key = EVT_KEY_LOCATION_ENABLE_STATE; + + if (enabled) + val = EVT_VAL_LOCATION_ENABLED; + else + val = EVT_VAL_LOCATION_DISABLED; + + b = bundle_create(); + bundle_add_str(b, key, val); + + if (__esd_send_system_event(SYS_EVENT_LOCATION_ENABLE_STATE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); +} + +void __esd_vconfcb_location_enabled(keynode_t *node, void *user_data) { + int ret = 0; + int enabled = 0; + bundle *b = NULL; + const char *key = NULL; + const char *val = NULL; + + _D("vconfcb called"); + + ret = vconf_get_int(VCONFKEY_LOCATION_ENABLED, &enabled); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + key = EVT_KEY_GPS_ENABLE_STATE; + + if (enabled) + val = EVT_VAL_GPS_ENABLED; + else + val = EVT_VAL_GPS_DISABLED; + + b = bundle_create(); + bundle_add_str(b, key, val); + + if (__esd_send_system_event(SYS_EVENT_GPS_ENABLE_STATE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); +} + +void __esd_vconfcb_location_network_enabled(keynode_t *node, void *user_data) { + int ret = 0; + int enabled = 0; + bundle *b = NULL; + const char *key = NULL; + const char *val = NULL; + + _D("vconfcb called"); + + ret = vconf_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &enabled); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + key = EVT_KEY_NPS_ENABLE_STATE; + + if (enabled) + val = EVT_VAL_NPS_ENABLED; + else + val = EVT_VAL_NPS_DISABLED; + + b = bundle_create(); + bundle_add_str(b, key, val); + + if (__esd_send_system_event(SYS_EVENT_NPS_ENABLE_STATE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); +} + +void __esd_vconfcb_language_set(keynode_t *node, void *user_data) { + char *str = 0; + bundle *b = NULL; + const char *key = NULL; + + _D("vconfcb called"); + + str = vconf_get_str(VCONFKEY_LANGSET); + if (str == NULL) { + _E("failed to get vconf str"); + return; + } + + key = EVT_KEY_LANGUAGE_SET; + + b = bundle_create(); + bundle_add_str(b, key, str); + + if (__esd_send_system_event(SYS_EVENT_LANGUAGE_SET, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); + if (str) + free(str); +} + +void __esd_vconfcb_hour_format(keynode_t *node, void *user_data) { + int ret = 0; + int hours = 0; + bundle *b = NULL; + const char *key = NULL; + const char *val = NULL; + + _D("vconfcb called"); + + ret = vconf_get_int(VCONFKEY_REGIONFORMAT_TIME1224, &hours); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + key = EVT_KEY_HOUR_FORMAT; + + if (hours == VCONFKEY_TIME_FORMAT_24) + val = EVT_VAL_HOURFORMAT_24; + else + val = EVT_VAL_HOURFORMAT_12; + + b = bundle_create(); + bundle_add_str(b, key, val); + + if (__esd_send_system_event(SYS_EVENT_HOUR_FORMAT, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); +} + +void __esd_vconfcb_region_format(keynode_t *node, void *user_data) { + char *str = 0; + bundle *b = NULL; + const char *key = NULL; + + _D("vconfcb called"); + + str = vconf_get_str(VCONFKEY_REGIONFORMAT); + if (str == NULL) { + _E("failed to get vconf str"); + return; + } + + key = EVT_KEY_REGION_FORMAT; + + b = bundle_create(); + bundle_add_str(b, key, str); + + if (__esd_send_system_event(SYS_EVENT_REGION_FORMAT, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); + if (str) + free(str); +} + +void __esd_vconfcb_vibration_status(keynode_t *node, void *user_data) { + int ret = 0; + int vibration_on = 0; + int sound_on = 0; + bundle *b = NULL; + char *key = NULL; + char *val = NULL; + + _D("vconfcb called"); + + ret = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibration_on); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + ret = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound_on); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + if (vibration_on) { + key = EVT_KEY_VIBRATION_STATE; + val = EVT_VAL_VIBRATION_ON; + b = bundle_create(); + bundle_add_str(b, key, val); + if (__esd_send_system_event(SYS_EVENT_VIBRATION_STATE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); + + key = EVT_KEY_SILENT_MODE; + val = EVT_VAL_SILENTMODE_OFF; + b = bundle_create(); + bundle_add_str(b, key, val); + if (__esd_send_system_event(SYS_EVENT_SILENT_MODE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); + } else { + key = EVT_KEY_VIBRATION_STATE; + val = EVT_VAL_VIBRATION_OFF; + b = bundle_create(); + bundle_add_str(b, key, val); + if (__esd_send_system_event(SYS_EVENT_VIBRATION_STATE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); + + if (!sound_on) { + key = EVT_KEY_SILENT_MODE; + val = EVT_VAL_SILENTMODE_ON; + b = bundle_create(); + bundle_add_str(b, key, val); + if (__esd_send_system_event(SYS_EVENT_SILENT_MODE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); + } + } +} + +void __esd_vconfcb_sound_status(keynode_t *node, void *user_data) { + int ret = 0; + int vibration_on = 0; + int sound_on = 0; + bundle *b = NULL; + char *key = NULL; + char *val = NULL; + + _D("vconfcb called"); + + ret = vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibration_on); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + ret = vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound_on); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + if (sound_on) { + key = EVT_KEY_VIBRATION_STATE; + val = EVT_VAL_VIBRATION_OFF; + b = bundle_create(); + bundle_add_str(b, key, val); + if (__esd_send_system_event(SYS_EVENT_VIBRATION_STATE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); + + key = EVT_KEY_SILENT_MODE; + val = EVT_VAL_SILENTMODE_OFF; + b = bundle_create(); + bundle_add_str(b, key, val); + if (__esd_send_system_event(SYS_EVENT_SILENT_MODE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); + } else { + if (!vibration_on) { + key = EVT_KEY_SILENT_MODE; + val = EVT_VAL_SILENTMODE_ON; + b = bundle_create(); + bundle_add_str(b, key, val); + if (__esd_send_system_event(SYS_EVENT_SILENT_MODE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); + } + } +} + +void __esd_vconfcb_auto_rotate(keynode_t *node, void *user_data) { + int ret = 0; + int enabled = 0; + bundle *b = NULL; + const char *key = NULL; + const char *val = NULL; + + _D("vconfcb called"); + + ret = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &enabled); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + key = EVT_KEY_SCREEN_AUTOROTATE_STATE; + + if (enabled) + val = EVT_VAL_SCREEN_AUTOROTATE_ON; + else + val = EVT_VAL_SCREEN_AUTOROTATE_OFF; + + b = bundle_create(); + bundle_add_str(b, key, val); + + if (__esd_send_system_event(SYS_EVENT_SCREEN_AUTOROTATE_STATE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); +} + +void __esd_vconfcb_mobiledata_state(keynode_t *node, void *user_data) { + int ret = 0; + int enabled = 0; + bundle *b = NULL; + const char *key = NULL; + const char *val = NULL; + + _D("vconfcb called"); + + ret = vconf_get_bool(VCONFKEY_3G_ENABLE, &enabled); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + key = EVT_KEY_MOBILE_DATA_STATE; + + if (enabled) + val = EVT_VAL_MOBILE_DATA_ON; + else + val = EVT_VAL_MOBILE_DATA_OFF; + + b = bundle_create(); + bundle_add_str(b, key, val); + + if (__esd_send_system_event(SYS_EVENT_MOBILE_DATA_STATE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); +} + +void __esd_vconfcb_roaming_state(keynode_t *node, void *user_data) { + int ret = 0; + int enabled = 0; + bundle *b = NULL; + const char *key = NULL; + const char *val = NULL; + + _D("vconfcb called"); + + ret = vconf_get_bool(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL, &enabled); + if (ret != VCONF_OK) { + _E("failed to get vconf (%d)", ret); + return; + } + + key = EVT_KEY_DATA_ROAMING_STATE; + + if (enabled) + val = EVT_VAL_DATA_ROAMING_ON; + else + val = EVT_VAL_DATA_ROAMING_OFF; + + b = bundle_create(); + bundle_add_str(b, key, val); + + if (__esd_send_system_event(SYS_EVENT_DATA_ROAMING_STATE, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); +} + +void __esd_vconfcb_font_set(keynode_t *node, void *user_data) { + char *str = 0; + bundle *b = NULL; + const char *key = NULL; + + _D("vconfcb called"); + + str = vconf_get_str(VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME); + if (str == NULL) { + _E("failed to get vconf str"); + return; + } + + key = EVT_KEY_FONT_SET; + + b = bundle_create(); + bundle_add_str(b, key, str); + + if (__esd_send_system_event(SYS_EVENT_FONT_SET, b, key) != ES_R_OK) + _E("failed to send event"); + + if (b) + bundle_free(b); + if (str) + free(str); +} + +struct esd_vconf_handler vconf_callbacks[] = { + {VCONFKEY_LOCATION_USE_MY_LOCATION, __esd_vconfcb_location_use_mylocation}, + {VCONFKEY_LOCATION_ENABLED, __esd_vconfcb_location_enabled}, + {VCONFKEY_LOCATION_NETWORK_ENABLED, __esd_vconfcb_location_network_enabled}, + {VCONFKEY_LANGSET, __esd_vconfcb_language_set}, + {VCONFKEY_REGIONFORMAT_TIME1224, __esd_vconfcb_hour_format}, + {VCONFKEY_REGIONFORMAT, __esd_vconfcb_region_format}, + {VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, __esd_vconfcb_vibration_status}, + {VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, __esd_vconfcb_sound_status}, + {VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, __esd_vconfcb_auto_rotate}, + {VCONFKEY_3G_ENABLE, __esd_vconfcb_mobiledata_state}, + {VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL, __esd_vconfcb_roaming_state}, + {VCONFKEY_SETAPPL_ACCESSIBILITY_FONT_NAME, __esd_vconfcb_font_set}, +}; + +int vconfcbs_size = sizeof(vconf_callbacks)/sizeof(struct esd_vconf_handler); + +} // namespace + +int __esd_register_vconf_callbacks() { + int i = 0; + int ret = 0; + int result = ES_R_OK; + + esd_sent_table = g_hash_table_new(g_str_hash, g_str_equal); + + _D("vconf callbacks size(%d)", vconfcbs_size); + for (i = 0; i < vconfcbs_size; i++) { + ret = vconf_notify_key_changed(vconf_callbacks[i].key, + vconf_callbacks[i].esd_vconfcb_fn, NULL); + if (ret != VCONF_OK) { + _E("failed to register vconf callback (%s)", vconf_callbacks[i].key); + result = ES_R_ERROR; + break; + } + } + + return result; +} diff --git a/eventsystem.conf b/src/modules/dbus_event/eventsystem.conf similarity index 100% rename from eventsystem.conf rename to src/modules/dbus_event/eventsystem.conf diff --git a/src/modules/dbus_event/introspection_cb.hh b/src/modules/dbus_event/introspection_cb.hh new file mode 100644 index 0000000..7c35174 --- /dev/null +++ b/src/modules/dbus_event/introspection_cb.hh @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2022 Samsung Electronics Co., Ltd. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +constexpr const char INTROSPECTION_XML[] = R"__esd( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)__esd"; -- 2.7.4