Merge Version 0.5.5 96/45296/1 accepted/tizen/mobile/20150810.043507 accepted/tizen/tv/20150810.043545 submit/tizen_mobile/20150810.020750 submit/tizen_tv/20150810.020506
authorMu-Woong <muwoong.lee@samsung.com>
Tue, 4 Aug 2015 12:14:57 +0000 (21:14 +0900)
committerMu-Woong <muwoong.lee@samsung.com>
Tue, 4 Aug 2015 12:14:57 +0000 (21:14 +0900)
- 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 <muwoong.lee@samsung.com>
13 files changed:
packaging/context-service.spec
src/client_request.cpp
src/client_request.h
src/context_mgr_impl.cpp
src/context_trigger/context_monitor.cpp
src/context_trigger/fact_reader.cpp
src/context_trigger/fact_reader.h
src/context_trigger/rule_manager.cpp
src/db_mgr_impl.cpp
src/dbus_server_impl.cpp
src/dbus_server_impl.h
src/request.cpp
src/request.h

index 61ef9fd..9d4bcb8 100644 (file)
@@ -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
index 54a4ea2..8270b06 100644 (file)
@@ -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)
index 30181f0..ed5ef6a 100644 (file)
@@ -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;
        };
index 0f44381..c58b4c7 100644 (file)
@@ -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());
index 239f55d..966c62d 100644 (file)
@@ -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);
        }
 
index cd09a00..3c219d2 100644 (file)
@@ -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);
index d0a0dfd..4cbbbd7 100644 (file)
@@ -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);
index b131227..2241daa 100644 (file)
@@ -29,6 +29,7 @@
 #include <context_trigger_types_internal.h>
 #include <context_trigger.h>
 #include <db_mgr.h>
+#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);
                }
        }
 }
index 369e6a1..a75f292 100644 (file)
@@ -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<std::string>::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 << ",";
index ac464ea..aeee103 100644 (file)
@@ -17,6 +17,7 @@
 #include <signal.h>
 #include <glib.h>
 #include <gio/gio.h>
+#include <app_manager.h>
 
 #include <types_internal.h>
 #include <dbus_listener_iface.h>
@@ -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<unsigned int*>(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);
+}
index 3f31e1f..8e85c8c 100644 (file)
 
 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 */
 
index 26e9b3e..df24f52 100644 (file)
@@ -55,3 +55,8 @@ ctx::json& ctx::request_info::get_description()
 {
        return _description;
 }
+
+const char* ctx::request_info::get_app_id()
+{
+       return NULL;
+}
index 2a3e45b..755a979 100644 (file)
@@ -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;