From: Mu-Woong Date: Tue, 4 Aug 2015 12:14:57 +0000 (+0900) Subject: Merge Version 0.5.5 X-Git-Tag: accepted/tizen/mobile/20150810.043507^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=daa66adff2f2ab1cb3c40574d771e6594abcf6e4;p=platform%2Fcore%2Fcontext%2Fcontext-service.git Merge Version 0.5.5 - Modified dbmgr to escape "'\ while insertion - Fix get_provider() to skip trigger's permission check - Add dbus call action handling routine to trigge - Add 'app_id' member variable to the client request class - Add util functions for dbus service activation - Modify trigger fact_reader's unsubscribe function to require 'subject' Change-Id: I7baa8c4291efe90f5883f9a2c3b124ff5c92f182 Signed-off-by: Mu-Woong --- diff --git a/packaging/context-service.spec b/packaging/context-service.spec index 61ef9fd..9d4bcb8 100644 --- a/packaging/context-service.spec +++ b/packaging/context-service.spec @@ -1,6 +1,6 @@ Name: context-service Summary: Context-Service -Version: 0.5.3 +Version: 0.5.5 Release: 1 Group: System/Service License: Apache-2.0 diff --git a/src/client_request.cpp b/src/client_request.cpp index 54a4ea2..8270b06 100644 --- a/src/client_request.cpp +++ b/src/client_request.cpp @@ -24,8 +24,9 @@ ctx::client_request::client_request(int type, const char *client, int req_id, const char *subj, const char *desc, - const char *sender, GDBusMethodInvocation *inv) + const char *sender, char *app_id, GDBusMethodInvocation *inv) : request_info(type, client, req_id, subj, desc) + , __app_id(app_id) , __sender(sender) , __invocation(inv) { @@ -35,6 +36,13 @@ ctx::client_request::~client_request() { if (__invocation) g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT)); + + g_free(__app_id); +} + +const char* ctx::client_request::get_app_id() +{ + return __app_id; } bool ctx::client_request::reply(int error) diff --git a/src/client_request.h b/src/client_request.h index 30181f0..ed5ef6a 100644 --- a/src/client_request.h +++ b/src/client_request.h @@ -26,15 +26,17 @@ namespace ctx { public: client_request(int type, const char *client, int req_id, const char *subj, const char *desc, - const char *sender, GDBusMethodInvocation *inv); + const char *sender, char *app_id, GDBusMethodInvocation *inv); ~client_request(); + const char *get_app_id(); bool reply(int error); bool reply(int error, ctx::json &request_result); bool reply(int error, ctx::json &request_result, ctx::json &data_read); bool publish(int error, ctx::json &data); private: + char *__app_id; std::string __sender; GDBusMethodInvocation *__invocation; }; diff --git a/src/context_mgr_impl.cpp b/src/context_mgr_impl.cpp index 0f44381..c58b4c7 100644 --- a/src/context_mgr_impl.cpp +++ b/src/context_mgr_impl.cpp @@ -176,7 +176,8 @@ ctx::context_provider_iface *ctx::context_manager_impl::get_provider(ctx::reques return NULL; } - if (!ctx::privilege_manager::is_allowed(request->get_client(), it->second.privilege)) { + if (!STR_EQ(TRIGGER_CLIENT_NAME, request->get_client()) && + !ctx::privilege_manager::is_allowed(request->get_client(), it->second.privilege)) { _W("Permission denied"); request->reply(ERR_PERMISSION_DENIED); delete request; @@ -208,7 +209,7 @@ void ctx::context_manager_impl::subscribe(ctx::request_info *request) void ctx::context_manager_impl::unsubscribe(ctx::request_info *request) { - _I(CYAN("'%s' unsubscribes RID-%d"), request->get_client(), request->get_id()); + _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->get_client(), request->get_subject(), request->get_id()); // Search the subscribe request to be removed request_list_t::iterator target = find_request(subscribe_request_list, request->get_client(), request->get_id()); diff --git a/src/context_trigger/context_monitor.cpp b/src/context_trigger/context_monitor.cpp index 239f55d..966c62d 100644 --- a/src/context_trigger/context_monitor.cpp +++ b/src/context_trigger/context_monitor.cpp @@ -74,7 +74,7 @@ int ctx::context_monitor::unsubscribe(int rule_id, std::string subject, ctx::jso read_req_cnt_map[req_id]--; if (read_req_cnt_map[req_id] == 0) { - reader->unsubscribe(req_id); + reader->unsubscribe(subject.c_str(), req_id); read_req_cnt_map.erase(req_id); } diff --git a/src/context_trigger/fact_reader.cpp b/src/context_trigger/fact_reader.cpp index cd09a00..3c219d2 100644 --- a/src/context_trigger/fact_reader.cpp +++ b/src/context_trigger/fact_reader.cpp @@ -178,12 +178,12 @@ void ctx::fact_reader::unsubscribe(const char* subject, json* option) int rid = find_sub(subject, option); IF_FAIL_VOID_TAG(rid > 0, _W, "Unknown subscription for %s", subject); - unsubscribe(rid); + unsubscribe(subject, rid); } -void ctx::fact_reader::unsubscribe(int subscription_id) +void ctx::fact_reader::unsubscribe(const char *subject, int subscription_id) { - fact_request *req = new(std::nothrow) fact_request(REQ_UNSUBSCRIBE, CLIENT_NAME, subscription_id, "", NULL, NULL); + fact_request *req = new(std::nothrow) fact_request(REQ_UNSUBSCRIBE, CLIENT_NAME, subscription_id, subject, NULL, NULL); IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed"); g_idle_add(send_request, req); diff --git a/src/context_trigger/fact_reader.h b/src/context_trigger/fact_reader.h index d0a0dfd..4cbbbd7 100644 --- a/src/context_trigger/fact_reader.h +++ b/src/context_trigger/fact_reader.h @@ -36,7 +36,7 @@ namespace ctx { int subscribe(const char *subject, json *option, bool wait_response = false); void unsubscribe(const char *subject, json *option); - void unsubscribe(int subscription_id); + void unsubscribe(const char *subject, int subscription_id); bool read(const char *subject, json *option, context_fact& fact); void reply_result(int req_id, int error, json *request_result = NULL, json *fact = NULL); diff --git a/src/context_trigger/rule_manager.cpp b/src/context_trigger/rule_manager.cpp index b131227..2241daa 100644 --- a/src/context_trigger/rule_manager.cpp +++ b/src/context_trigger/rule_manager.cpp @@ -29,6 +29,7 @@ #include #include #include +#include "../dbus_server_impl.h" #include "rule_manager.h" #include "script_generator.h" #include "trigger.h" @@ -929,6 +930,30 @@ static void trigger_action_notification(ctx::json& action, std::string creator) } } +static void trigger_action_dbus_call(ctx::json& action) +{ + std::string bus_name, object, iface, method, user_data; + + action.get(NULL, CT_RULE_ACTION_DBUS_NAME, &bus_name); + IF_FAIL_VOID_TAG(!bus_name.empty(), _E, "No target bus name"); + + action.get(NULL, CT_RULE_ACTION_DBUS_OBJECT, &object); + IF_FAIL_VOID_TAG(!object.empty(), _E, "No object path"); + + action.get(NULL, CT_RULE_ACTION_DBUS_INTERFACE, &iface); + IF_FAIL_VOID_TAG(!iface.empty(), _E, "No interface name"); + + action.get(NULL, CT_RULE_ACTION_DBUS_METHOD, &method); + IF_FAIL_VOID_TAG(!method.empty(), _E, "No method name"); + + if (!action.get(NULL, CT_RULE_ACTION_DBUS_USER_DATA, &user_data)) { + _E("No user data"); + return; + } + + ctx::dbus_server::call(bus_name.c_str(), object.c_str(), iface.c_str(), method.c_str(), user_data.c_str()); +} + void ctx::rule_manager::on_rule_triggered(int rule_id) { _D(YELLOW("Rule%d is triggered"), rule_id); @@ -953,6 +978,8 @@ void ctx::rule_manager::on_rule_triggered(int rule_id) std::string creator; record[0].get(NULL, "creator", &creator); trigger_action_notification(action, creator); + } else if (type.compare(CT_RULE_ACTION_TYPE_DBUS_CALL) == 0) { + trigger_action_dbus_call(action); } } } diff --git a/src/db_mgr_impl.cpp b/src/db_mgr_impl.cpp index 369e6a1..a75f292 100644 --- a/src/db_mgr_impl.cpp +++ b/src/db_mgr_impl.cpp @@ -152,13 +152,16 @@ bool ctx::db_manager_impl::insert(unsigned int query_id, const char* table_name, std::ostringstream colstream; std::ostringstream valstream; - for (std::list::iterator it = keys.begin(); it != keys.end(); ++it) { std::string s; int64_t i; if (record.get(NULL, (*it).c_str(), &s)) { colstream << *it << ","; - valstream << "'" << s << "',"; + + char* buf = sqlite3_mprintf("%Q", s.c_str()); + IF_FAIL_RETURN_TAG(buf, false, _E, "Memory allocation failed"); + valstream << buf << ","; + sqlite3_free(buf); } else if (record.get(NULL, (*it).c_str(), &i)) { colstream << *it << ","; valstream << i << ","; diff --git a/src/dbus_server_impl.cpp b/src/dbus_server_impl.cpp index ac464ea..aeee103 100644 --- a/src/dbus_server_impl.cpp +++ b/src/dbus_server_impl.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -89,7 +90,11 @@ static void handle_request(const char *sender, GVariant *param, GDBusMethodInvoc return; } - ctx::client_request *request = new(std::nothrow) ctx::client_request(req_type, smack_label.c_str(), req_id, subject, input, sender, invocation); + char *app_id = NULL; + app_manager_get_app_id(pid, &app_id); + _D("AppId: %s", app_id); + + ctx::client_request *request = new(std::nothrow) ctx::client_request(req_type, smack_label.c_str(), req_id, subject, input, sender, app_id, invocation); if (!request) { _E("Memory allocation failed"); g_dbus_method_invocation_return_value(invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT)); @@ -207,10 +212,34 @@ void ctx::dbus_server_impl::publish(const char* dest, int req_id, const char* su GVariant *param = g_variant_new("(isis)", req_id, subject, error, data); IF_FAIL_VOID_TAG(param, _E, "Memory allocation failed"); - GError *err = NULL; g_dbus_connection_call(dbus_connection, dest, DBUS_PATH, DBUS_IFACE, - METHOD_RESPOND, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, NULL, &err); - HANDLE_GERROR(err); + METHOD_RESPOND, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, NULL, NULL); +} + +static void handle_call_result(GObject *source, GAsyncResult *res, gpointer user_data) +{ + _I("Call %u done", *static_cast(user_data)); + + GDBusConnection *conn = G_DBUS_CONNECTION(source); + GError *error = NULL; + g_dbus_connection_call_finish(conn, res, &error); + HANDLE_GERROR(error); +} + +void ctx::dbus_server_impl::call(const char *dest, const char *obj, const char *iface, const char *method, const char *data) +{ + IF_FAIL_VOID_TAG(dest && obj && iface && method && data, _E, "Parameter null"); + + static unsigned int call_count = 0; + ++call_count; + + _SI("Call %u: %s, %s, %s.%s, %s", call_count, dest, obj, iface, method, data); + + GVariant *param = g_variant_new("(s)", data); + IF_FAIL_VOID_TAG(param, _E, "Memory allocation failed"); + + g_dbus_connection_call(dbus_connection, dest, obj, iface, method, param, NULL, + G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, handle_call_result, &call_count); } static void handle_signal_received(GDBusConnection *conn, const gchar *sender, @@ -242,3 +271,8 @@ void ctx::dbus_server::publish(const char* dest, int req_id, const char* subject { _instance->publish(dest, req_id, subject, error, data); } + +void ctx::dbus_server::call(const char *dest, const char *obj, const char *iface, const char *method, const char *data) +{ + _instance->call(dest, obj, iface, method, data); +} diff --git a/src/dbus_server_impl.h b/src/dbus_server_impl.h index 3f31e1f..8e85c8c 100644 --- a/src/dbus_server_impl.h +++ b/src/dbus_server_impl.h @@ -23,21 +23,23 @@ namespace ctx { class dbus_server_impl : public dbus_server_iface { - public: - dbus_server_impl(); - ~dbus_server_impl(); + public: + dbus_server_impl(); + ~dbus_server_impl(); - bool init(); - void release(); + bool init(); + void release(); - void publish(const char* dest, int req_id, const char* subject, int error, const char* data); - int64_t signal_subscribe(const char* sender, const char* path, const char* iface, const char* name, dbus_listener_iface* listener); - void signal_unsubscribe(int64_t subscription_id); + void publish(const char *dest, int req_id, const char *subject, int error, const char *data); + void call(const char *dest, const char *obj, const char *iface, const char *method, const char *data); + int64_t signal_subscribe(const char *sender, const char *path, const char *iface, const char *name, dbus_listener_iface *listener); + void signal_unsubscribe(int64_t subscription_id); }; /* class ctx::dbus_server */ namespace dbus_server { - void publish(const char* dest, int req_id, const char* subject, int error, const char* data); + void publish(const char *dest, int req_id, const char *subject, int error, const char *data); + void call(const char *dest, const char *obj, const char *iface, const char *method, const char *data); } } /* namespace ctx */ diff --git a/src/request.cpp b/src/request.cpp index 26e9b3e..df24f52 100644 --- a/src/request.cpp +++ b/src/request.cpp @@ -55,3 +55,8 @@ ctx::json& ctx::request_info::get_description() { return _description; } + +const char* ctx::request_info::get_app_id() +{ + return NULL; +} diff --git a/src/request.h b/src/request.h index 2a3e45b..755a979 100644 --- a/src/request.h +++ b/src/request.h @@ -33,6 +33,7 @@ namespace ctx { const char *get_subject(); ctx::json& get_description(); + virtual const char *get_app_id(); virtual bool reply(int error) = 0; virtual bool reply(int error, ctx::json &request_result) = 0; virtual bool reply(int error, ctx::json &request_result, ctx::json &data_read) = 0;