--- /dev/null
+/*
+ * Copyright (c) 2015 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 <unistd.h>
+#include <glib.h>
+#include <app_manager.h>
+#include <types_internal.h>
+#include "DBusServer.h"
+#include "access_control/peer_creds.h"
+#include "ClientRequest.h"
+
+ctx::ClientRequest::ClientRequest(int type, int reqId, const char *subj, const char *desc,
+ ctx::credentials *creds, const char *sender, GDBusMethodInvocation *inv) :
+ RequestInfo(type, reqId, subj, desc),
+ __credentials(creds),
+ __dbusSender(sender),
+ __invocation(inv)
+{
+}
+
+ctx::ClientRequest::~ClientRequest()
+{
+ if (__invocation)
+ g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT));
+
+ delete __credentials;
+}
+
+const ctx::credentials* ctx::ClientRequest::getCredentials()
+{
+ return __credentials;
+}
+
+const char* ctx::ClientRequest::getPackageId()
+{
+ if (__credentials)
+ return __credentials->package_id;
+
+ return NULL;
+}
+
+const char* ctx::ClientRequest::getClient()
+{
+ if (__credentials)
+ return __credentials->client;
+
+ return NULL;
+}
+
+bool ctx::ClientRequest::reply(int error)
+{
+ IF_FAIL_RETURN(__invocation, true);
+
+ _I("Reply %#x", error);
+
+ g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", error, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT));
+ __invocation = NULL;
+ return true;
+}
+
+bool ctx::ClientRequest::reply(int error, ctx::Json& requestResult)
+{
+ IF_FAIL_RETURN(__invocation, true);
+ IF_FAIL_RETURN(_type != REQ_READ_SYNC, true);
+
+ std::string result = requestResult.str();
+ IF_FAIL_RETURN(!result.empty(), false);
+
+ _I("Reply %#x", error);
+ _SD("Result: %s", result.c_str());
+
+ g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", error, result.c_str(), EMPTY_JSON_OBJECT));
+ __invocation = NULL;
+
+ return true;
+}
+
+bool ctx::ClientRequest::reply(int error, ctx::Json& requestResult, ctx::Json& dataRead)
+{
+ if (__invocation == NULL) {
+ return publish(error, dataRead);
+ }
+
+ std::string result = requestResult.str();
+ std::string data = dataRead.str();
+ IF_FAIL_RETURN(!result.empty() && !data.empty(), false);
+
+ _I("Reply %#x", error);
+ _SD("Result: %s", result.c_str());
+ _SD("Data: %s", data.c_str());
+
+ g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", error, result.c_str(), data.c_str()));
+ __invocation = NULL;
+
+ return true;
+}
+
+bool ctx::ClientRequest::publish(int error, ctx::Json& data)
+{
+ DBusServer::publish(__dbusSender, _reqId, _subject, error, data.str());
+ return true;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_CLIENT_REQUEST_H_
+#define _CONTEXT_CLIENT_REQUEST_H_
+
+#include <gio/gio.h>
+#include "Request.h"
+
+namespace ctx {
+
+ class ClientRequest : public RequestInfo {
+ public:
+ ClientRequest(int type, int reqId, const char *subj, const char *desc,
+ credentials *creds, const char *sender, GDBusMethodInvocation *inv);
+ ~ClientRequest();
+
+ const credentials* getCredentials();
+ const char* getPackageId();
+ const char* getClient();
+ bool reply(int error);
+ bool reply(int error, ctx::Json &requestResult);
+ bool reply(int error, ctx::Json &requestResult, ctx::Json &dataRead);
+ bool publish(int error, ctx::Json &data);
+
+ private:
+ credentials *__credentials;
+ std::string __dbusSender;
+ GDBusMethodInvocation *__invocation;
+ };
+
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_CLIENT_REQUEST_H_ */
#include <types_internal.h>
#include "server.h"
-#include "client_request.h"
+#include "ClientRequest.h"
#include "access_control/peer_creds.h"
#include "DBusServer.h"
return;
}
- client_request *request = new(std::nothrow) client_request(reqType, reqId, subject, input, creds, sender, invocation);
+ ClientRequest *request = new(std::nothrow) ClientRequest(reqType, reqId, subject, input, creds, sender, 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));
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <glib.h>
+#include <types_internal.h>
+#include "Request.h"
+
+ctx::RequestInfo::RequestInfo(int type, int reqId, const char* subj, const char* desc) :
+ _type(type),
+ _reqId(reqId),
+ _subject(subj),
+ _description(desc)
+{
+}
+
+ctx::RequestInfo::~RequestInfo()
+{
+}
+
+int ctx::RequestInfo::getType()
+{
+ return _type;
+}
+
+int ctx::RequestInfo::getId()
+{
+ return _reqId;
+}
+
+const ctx::credentials* ctx::RequestInfo::getCredentials()
+{
+ return NULL;
+}
+
+const char* ctx::RequestInfo::getPackageId()
+{
+ return NULL;
+}
+
+const char* ctx::RequestInfo::getClient()
+{
+ return NULL;
+}
+
+const char* ctx::RequestInfo::getSubject()
+{
+ return _subject.c_str();
+}
+
+ctx::Json& ctx::RequestInfo::getDescription()
+{
+ return _description;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_REQUEST_INFO_H_
+#define _CONTEXT_REQUEST_INFO_H_
+
+#include <string>
+#include <Json.h>
+
+namespace ctx {
+
+ /* Forward declaration */
+ class credentials;
+
+ class RequestInfo {
+ public:
+ RequestInfo(int type, int reqId, const char *subj, const char *desc);
+ virtual ~RequestInfo();
+
+ int getType();
+ int getId();
+ const char* getSubject();
+ ctx::Json& getDescription();
+
+ virtual const credentials* getCredentials();
+ virtual const char* getPackageId();
+ /* TODO: remove this getClient() */
+ virtual const char* getClient();
+ virtual bool reply(int error) = 0;
+ virtual bool reply(int error, ctx::Json &requestResult) = 0;
+ virtual bool reply(int error, ctx::Json &requestResult, ctx::Json &dataRead) = 0;
+ virtual bool publish(int error, ctx::Json &data) = 0;
+
+ protected:
+ int _type;
+ int _reqId;
+ std::string _subject;
+ ctx::Json _description;
+ };
+
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_REQUEST_INFO_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <unistd.h>
-#include <glib.h>
-#include <app_manager.h>
-#include <types_internal.h>
-#include "DBusServer.h"
-#include "access_control/peer_creds.h"
-#include "client_request.h"
-
-ctx::client_request::client_request(int type, int req_id, const char *subj, const char *desc,
- ctx::credentials *creds, const char *sender, GDBusMethodInvocation *inv)
- : request_info(type, req_id, subj, desc)
- , __credentials(creds)
- , __dbus_sender(sender)
- , __invocation(inv)
-{
-}
-
-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));
-
- delete __credentials;
-}
-
-const ctx::credentials* ctx::client_request::get_credentials()
-{
- return __credentials;
-}
-
-const char* ctx::client_request::get_package_id()
-{
- if (__credentials)
- return __credentials->package_id;
-
- return NULL;
-}
-
-const char* ctx::client_request::get_client()
-{
- if (__credentials)
- return __credentials->client;
-
- return NULL;
-}
-
-bool ctx::client_request::reply(int error)
-{
- IF_FAIL_RETURN(__invocation, true);
-
- _I("Reply %#x", error);
-
- g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", error, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT));
- __invocation = NULL;
- return true;
-}
-
-bool ctx::client_request::reply(int error, ctx::Json& request_result)
-{
- IF_FAIL_RETURN(__invocation, true);
- IF_FAIL_RETURN(_type != REQ_READ_SYNC, true);
-
- std::string result = request_result.str();
- IF_FAIL_RETURN(!result.empty(), false);
-
- _I("Reply %#x", error);
- _SD("Result: %s", result.c_str());
-
- g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", error, result.c_str(), EMPTY_JSON_OBJECT));
- __invocation = NULL;
-
- return true;
-}
-
-bool ctx::client_request::reply(int error, ctx::Json& request_result, ctx::Json& data_read)
-{
- if (__invocation == NULL) {
- return publish(error, data_read);
- }
-
- std::string result = request_result.str();
- std::string data = data_read.str();
- IF_FAIL_RETURN(!result.empty() && !data.empty(), false);
-
- _I("Reply %#x", error);
- _SD("Result: %s", result.c_str());
- _SD("Data: %s", data.c_str());
-
- g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", error, result.c_str(), data.c_str()));
- __invocation = NULL;
-
- return true;
-}
-
-bool ctx::client_request::publish(int error, ctx::Json& data)
-{
- DBusServer::publish(__dbus_sender, _req_id, _subject, error, data.str());
- return true;
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_CLIENT_REQUEST_H__
-#define __CONTEXT_CLIENT_REQUEST_H__
-
-#include <gio/gio.h>
-#include "request.h"
-
-namespace ctx {
-
- class client_request : public request_info {
- public:
- client_request(int type, int req_id, const char *subj, const char *desc,
- credentials *creds, const char *sender, GDBusMethodInvocation *inv);
- ~client_request();
-
- const credentials* get_credentials();
- const char* get_package_id();
- const char* get_client();
- 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:
- credentials *__credentials;
- std::string __dbus_sender;
- GDBusMethodInvocation *__invocation;
- };
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_CLIENT_REQUEST_H__ */
#include <provider_iface.h>
#include "server.h"
#include "access_control/privilege.h"
-#include "request.h"
+#include "Request.h"
#include "provider.h"
#include "context_mgr_impl.h"
-#include "context_trigger/template_manager.h"
+#include "trigger/TemplateManager.h"
/* Context Providers */
#include <internal/device_context_provider.h>
if (!initialized) {
__trigger_item_list.push_back(trigger_item_format_s(subject, operation, attributes, options, (owner)? owner : ""));
} else {
- ctx::template_manager* tmpl_mgr = ctx::template_manager::get_instance();
- IF_FAIL_RETURN_TAG(tmpl_mgr, false, _E, "Memory allocation failed");
- tmpl_mgr->register_template(subject, operation, attributes, options, owner);
+ ctx::trigger::TemplateManager* tmplMgr = ctx::trigger::TemplateManager::getInstance();
+ IF_FAIL_RETURN_TAG(tmplMgr, false, _E, "Memory allocation failed");
+ tmplMgr->registerTemplate(subject, operation, attributes, options, owner);
}
return true;
if (!initialized) {
__trigger_item_list.push_back(trigger_item_format_s(subject));
} else {
- ctx::template_manager* tmpl_mgr = ctx::template_manager::get_instance();
- IF_FAIL_RETURN_TAG(tmpl_mgr, false, _E, "Memory allocation failed");
- tmpl_mgr->unregister_template(subject);
+ ctx::trigger::TemplateManager* tmplMgr = ctx::trigger::TemplateManager::getInstance();
+ IF_FAIL_RETURN_TAG(tmplMgr, false, _E, "Memory allocation failed");
+ tmplMgr->unregisterTemplate(subject);
}
return true;
return true;
}
-void ctx::context_manager_impl::assign_request(ctx::request_info* request)
+void ctx::context_manager_impl::assign_request(ctx::RequestInfo* request)
{
if (handle_custom_request(request)) {
delete request;
return;
}
- auto it = provider_handle_map.find(request->get_subject());
+ auto it = provider_handle_map.find(request->getSubject());
if (it == provider_handle_map.end()) {
_W("Unsupported subject");
request->reply(ERR_NOT_SUPPORTED);
return;
}
- if (!it->second->is_allowed(request->get_credentials())) {
+ if (!it->second->is_allowed(request->getCredentials())) {
_W("Permission denied");
request->reply(ERR_PERMISSION_DENIED);
delete request;
return;
}
- switch (request->get_type()) {
+ switch (request->getType()) {
case REQ_SUBSCRIBE:
it->second->subscribe(request);
break;
return true;
}
-bool ctx::context_manager_impl::handle_custom_request(ctx::request_info* request)
+bool ctx::context_manager_impl::handle_custom_request(ctx::RequestInfo* request)
{
- std::string subject = request->get_subject();
+ std::string subject = request->getSubject();
IF_FAIL_RETURN( subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_ADD ||
subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_REMOVE ||
subject == CONTEXT_TRIGGER_SUBJECT_CUSTOM_PUBLISH, false);
- const char* pkg_id = request->get_package_id();
+ const char* pkg_id = request->getPackageId();
if (pkg_id == NULL) {
request->reply(ERR_OPERATION_FAILED);
return true;
}
- ctx::Json desc = request->get_description();
+ ctx::Json desc = request->getDescription();
std::string name;
desc.get(NULL, CT_CUSTOM_NAME, &name);
std::string subj = pkg_id + std::string("::") + name;
/* Forward declaration */
class credentials;
- class request_info;
+ class RequestInfo;
class context_provider_handler;
class context_manager_impl : public context_manager_iface {
bool init();
void release();
- void assign_request(ctx::request_info *request);
+ void assign_request(ctx::RequestInfo *request);
bool is_supported(const char *subject);
bool is_allowed(const credentials *creds, const char *subject);
bool pop_trigger_item(std::string &subject, int &operation, ctx::Json &attributes, ctx::Json &options, std::string &owner, bool& unregister);
void _reply_to_read(const char *subject, ctx::Json &option, int error, ctx::Json &data_read);
/* For custom request */
- bool handle_custom_request(ctx::request_info* request);
+ bool handle_custom_request(ctx::RequestInfo* request);
}; /* class context_manager_impl */
} /* namespace ctx */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <app_control.h>
-#include <app_control_internal.h>
-#include <bundle.h>
-#include <device/display.h>
-#include <notification.h>
-#include <notification_internal.h>
-#include <runtime_info.h>
-#include <system_settings.h>
-#include <context_trigger_types_internal.h>
-#include <Json.h>
-#include "../DBusServer.h"
-#include "action_manager.h"
-
-static void trigger_action_app_control(ctx::Json& action);
-static void trigger_action_notification(ctx::Json& action, std::string pkg_id);
-static void trigger_action_dbus_call(ctx::Json& action);
-
-void ctx::action_manager::trigger_action(ctx::Json& action, std::string pkg_id)
-{
- std::string type;
- action.get(NULL, CT_RULE_ACTION_TYPE, &type);
-
- if (type.compare(CT_RULE_ACTION_TYPE_APP_CONTROL) == 0) {
- trigger_action_app_control(action);
- } else if (type.compare(CT_RULE_ACTION_TYPE_NOTIFICATION) == 0) {
- trigger_action_notification(action, pkg_id);
- } else if (type.compare(CT_RULE_ACTION_TYPE_DBUS_CALL) == 0) {
- trigger_action_dbus_call(action);
- }
-}
-
-void trigger_action_app_control(ctx::Json& action)
-{
- int error;
- std::string appctl_str;
- action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctl_str);
-
- char* str = static_cast<char*>(malloc(appctl_str.length()));
- if (str == NULL) {
- _E("Memory allocation failed");
- return;
- }
- appctl_str.copy(str, appctl_str.length(), 0);
- bundle_raw* encoded = reinterpret_cast<unsigned char*>(str);
- bundle* appctl_bundle = bundle_decode(encoded, appctl_str.length());
-
- app_control_h app = NULL;
- app_control_create(&app);
- app_control_import_from_bundle(app, appctl_bundle);
-
- error = app_control_send_launch_request(app, NULL, NULL);
- if (error != APP_CONTROL_ERROR_NONE) {
- _E("Launch request failed(%d)", error);
- } else {
- _D("Launch request succeeded");
- }
- bundle_free(appctl_bundle);
- free(str);
- app_control_destroy(app);
-
- error = device_display_change_state(DISPLAY_STATE_NORMAL);
- if (error != DEVICE_ERROR_NONE) {
- _E("Change display state failed(%d)", error);
- }
-}
-
-void trigger_action_notification(ctx::Json& action, std::string pkg_id)
-{
- int error;
- notification_h notification = notification_create(NOTIFICATION_TYPE_NOTI);
- std::string title;
- if (action.get(NULL, CT_RULE_ACTION_NOTI_TITLE, &title)) {
- error = notification_set_text(notification, NOTIFICATION_TEXT_TYPE_TITLE, title.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
- if (error != NOTIFICATION_ERROR_NONE) {
- _E("Set notification title failed(%d)", error);
- }
- }
-
- std::string content;
- if (action.get(NULL, CT_RULE_ACTION_NOTI_CONTENT, &content)) {
- error = notification_set_text(notification, NOTIFICATION_TEXT_TYPE_CONTENT, content.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
- if (error != NOTIFICATION_ERROR_NONE) {
- _E("Set notification contents failed(%d)", error);
- }
- }
-
- std::string image_path;
- if (action.get(NULL, CT_RULE_ACTION_NOTI_ICON_PATH, &image_path)) {
- error = notification_set_image(notification, NOTIFICATION_IMAGE_TYPE_ICON, image_path.c_str());
- if (error != NOTIFICATION_ERROR_NONE) {
- _E("Set notification icon image failed(%d)", error);
- }
- }
-
- std::string appctl_str;
- char* str = NULL;
- bundle_raw* encoded = NULL;
- bundle* appctl_bundle = NULL;
- app_control_h app = NULL;
- if (action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctl_str)) {
- str = static_cast<char*>(malloc(appctl_str.length()));
- if (str == NULL) {
- _E("Memory allocation failed");
- notification_free(notification);
- return;
- }
- appctl_str.copy(str, appctl_str.length(), 0);
- encoded = reinterpret_cast<unsigned char*>(str);
- appctl_bundle = bundle_decode(encoded, appctl_str.length());
-
- app_control_create(&app);
- app_control_import_from_bundle(app, appctl_bundle);
-
- error = notification_set_launch_option(notification, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL, app);
- if (error != NOTIFICATION_ERROR_NONE) {
- _E("Set launch option failed(%d)", error);
- }
- }
-
- if (!pkg_id.empty()) {
- error = notification_set_pkgname(notification, pkg_id.c_str());
- if (error != NOTIFICATION_ERROR_NONE) {
- _E("Set package id(%s) failed(%#x)", pkg_id.c_str(), error);
- }
- }
-
- bool silent = true;
- error = system_settings_get_value_bool(SYSTEM_SETTINGS_KEY_SOUND_SILENT_MODE, &silent);
- if (error != SYSTEM_SETTINGS_ERROR_NONE) {
- _E("Get system setting(silent mode) failed(%d)", error);
- }
-
- bool vibration = true;
- error = runtime_info_get_value_bool(RUNTIME_INFO_KEY_VIBRATION_ENABLED, &vibration);
- if (error != RUNTIME_INFO_ERROR_NONE) {
- _E("Get runtime info(vibration) failed(%d)", error);
- }
-
- if (!silent) {
- error = notification_set_sound(notification, NOTIFICATION_SOUND_TYPE_DEFAULT, NULL);
- if (error != NOTIFICATION_ERROR_NONE) {
- _E("Set notification sound failed(%d)", error);
- }
-
- if (vibration) {
- error = notification_set_vibration(notification, NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL);
- if (error != NOTIFICATION_ERROR_NONE) {
- _E("Set notification vibration failed(%d)", error);
- }
- }
- }
-
- error = notification_post(notification);
- if (error != NOTIFICATION_ERROR_NONE) {
- _E("Post notification failed(%d)", error);
- } else {
- _D("Post notification succeeded");
- }
-
- bundle_free(appctl_bundle);
- free(str);
- notification_free(notification);
- if (app) {
- app_control_destroy(app);
- }
-
- error = device_display_change_state(DISPLAY_STATE_NORMAL);
- if (error != DEVICE_ERROR_NONE) {
- _E("Change display state failed(%d)", error);
- }
-}
-
-void trigger_action_dbus_call(ctx::Json& action)
-{
- std::string bus_name, object, iface, method;
- GVariant *param = NULL;
-
- 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");
-
- action.get(NULL, CT_RULE_ACTION_DBUS_PARAMETER, ¶m);
-
- ctx::DBusServer::call(bus_name, object, iface, method, param);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_ACTION_MANAGER_H__
-#define __CONTEXT_ACTION_MANAGER_H__
-
-namespace ctx {
-
- class Json;
-
- namespace action_manager {
-
- void trigger_action(ctx::Json& action, std::string pkg_id);
-
- }
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_ACTION_MANAGER_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_FACT_TYPES_H__
-#define __CONTEXT_FACT_TYPES_H__
-
-#define CONTEXT_FACT_EVENT "EVENT"
-#define CONTEXT_FACT_CONDITION "CONDITION"
-#define CONTEXT_FACT_NAME "NAME"
-#define CONTEXT_FACT_OPTION "OPTION"
-#define CONTEXT_FACT_DATA "DATA"
-
-#endif //__CONTEXT_FACT_TYPES_H__
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_CONTEXT_LISTENER_INTERFACE_H__
-#define __CONTEXT_CONTEXT_LISTENER_INTERFACE_H__
-
-namespace ctx {
- /* Forward Declaration */
- class Json;
-
- class context_listener_iface {
- public:
- virtual ~context_listener_iface() {}
-
- virtual void on_event_received(std::string name, ctx::Json option, ctx::Json data) = 0;
-
- virtual void on_condition_received(std::string name, ctx::Json option, ctx::Json data) = 0;
- };
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_CONTEXT_LISTENER_INTERFACE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <types_internal.h>
-#include "../access_control/privilege.h"
-#include "../context_mgr_impl.h"
-#include "context_monitor.h"
-#include "fact_request.h"
-#include "context_listener_iface.h"
-
-static int last_rid;
-static int last_err;
-
-ctx::context_monitor *ctx::context_monitor::_instance = NULL;
-ctx::context_manager_impl *ctx::context_monitor::_context_mgr = NULL;
-
-static int generate_req_id()
-{
- static int req_id = 0;
-
- if (++req_id < 0) {
- // Overflow handling
- req_id = 1;
- }
-
- return req_id;
-}
-
-ctx::context_monitor::context_monitor()
-{
-}
-
-ctx::context_monitor::~context_monitor()
-{
-}
-
-void ctx::context_monitor::set_context_manager(ctx::context_manager_impl* ctx_mgr)
-{
- _context_mgr = ctx_mgr;
-}
-
-ctx::context_monitor* ctx::context_monitor::get_instance()
-{
- IF_FAIL_RETURN_TAG(_context_mgr, NULL, _E, "Context manager is needed");
-
- IF_FAIL_RETURN(!_instance, _instance);
-
- _instance = new(std::nothrow) context_monitor();
- IF_FAIL_RETURN_TAG(_instance, NULL, _E, "Memory alllocation failed");
-
- return _instance;
-}
-
-void ctx::context_monitor::destroy()
-{
- if (_instance) {
- delete _instance;
- _instance = NULL;
- }
-}
-
-int ctx::context_monitor::subscribe(int rule_id, std::string subject, ctx::Json option, context_listener_iface* listener)
-{
- int req_id = _subscribe(subject.c_str(), &option, listener);
- IF_FAIL_RETURN_TAG(req_id > 0, req_id, _E, "Subscribe event failed");
- _D(YELLOW("Subscribe event(rule%d). req%d"), rule_id, req_id);
-
- return ERR_NONE;
-}
-
-int ctx::context_monitor::_subscribe(const char* subject, Json* option, context_listener_iface* listener)
-{
- IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER);
-
- int rid = find_sub(REQ_SUBSCRIBE, subject, option);
- if (rid > 0) {
- add_listener(REQ_SUBSCRIBE, rid, listener);
- _D("Duplicated request for %s", subject);
- return rid;
- }
-
- rid = generate_req_id();
-
- fact_request *req = new(std::nothrow) fact_request(REQ_SUBSCRIBE,
- rid, subject, option ? option->str().c_str() : NULL, this);
- IF_FAIL_RETURN_TAG(req, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
-
- _context_mgr->assign_request(req);
- add_sub(REQ_SUBSCRIBE, rid, subject, option, listener);
-
- if (last_err != ERR_NONE) {
- remove_sub(REQ_SUBSCRIBE, rid);
- _E("Subscription request failed: %#x", last_err);
- return last_err;
- }
-
- return rid;
-}
-
-int ctx::context_monitor::unsubscribe(int rule_id, std::string subject, ctx::Json option, context_listener_iface* listener)
-{
- int rid = find_sub(REQ_SUBSCRIBE, subject.c_str(), &option);
- if (rid < 0) {
- _D("Invalid unsubscribe request");
- return ERR_INVALID_PARAMETER;
- }
-
- if (remove_listener(REQ_SUBSCRIBE, rid, listener) <= 0) {
- _unsubscribe(subject.c_str(), rid);
- }
- _D(YELLOW("Unsubscribe event(rule%d). req%d"), rule_id, rid);
-
- return ERR_NONE;
-}
-
-void ctx::context_monitor::_unsubscribe(const char *subject, int subscription_id)
-{
- fact_request *req = new(std::nothrow) fact_request(REQ_UNSUBSCRIBE, subscription_id, subject, NULL, NULL);
- IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed");
-
- _context_mgr->assign_request(req);
- remove_sub(REQ_SUBSCRIBE, subscription_id);
-}
-
-int ctx::context_monitor::read(std::string subject, Json option, context_listener_iface* listener)
-{
- int req_id = _read(subject.c_str(), &option, listener);
- IF_FAIL_RETURN_TAG(req_id > 0, ERR_OPERATION_FAILED, _E, "Read condition failed");
- _D(YELLOW("Read condition(%s). req%d"), subject.c_str(), req_id);
-
- return ERR_NONE;
-}
-
-int ctx::context_monitor::_read(const char* subject, Json* option, context_listener_iface* listener)
-{
- IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER);
-
- int rid = find_sub(REQ_READ, subject, option);
- if (rid > 0) {
- add_listener(REQ_READ, rid, listener);
- _D("Duplicated request for %s", subject);
- return rid;
- }
-
- rid = generate_req_id();
-
- fact_request *req = new(std::nothrow) fact_request(REQ_READ,
- rid, subject, option ? option->str().c_str() : NULL, this);
- IF_FAIL_RETURN_TAG(req, -1, _E, "Memory allocation failed");
-
- _context_mgr->assign_request(req);
- add_sub(REQ_READ, rid, subject, option, listener);
-
- if (last_err != ERR_NONE) {
- _E("Read request failed: %#x", last_err);
- return -1;
- }
-
- return rid;
-}
-
-bool ctx::context_monitor::is_supported(std::string subject)
-{
- return _context_mgr->is_supported(subject.c_str());
-}
-
-bool ctx::context_monitor::is_allowed(const char *client, const char *subject)
-{
- //TODO: re-implement this in the proper 3.0 style
- //return _context_mgr->is_allowed(client, subject);
- return true;
-}
-
-int ctx::context_monitor::find_sub(request_type type, const char* subject, Json* option)
-{
- // @return request id
- subscr_map_t* map = (type == REQ_SUBSCRIBE)? &subscr_map : &read_map;
-
- Json opt_j;
- if (option) {
- opt_j = *option;
- }
-
- for (subscr_map_t::iterator it = map->begin(); it != map->end(); ++it) {
- if ((*(it->second)).subject == subject && (*(it->second)).option == opt_j) {
- return it->first;
- }
- }
-
- return -1;
-}
-
-bool ctx::context_monitor::add_sub(request_type type, int sid, const char* subject, Json* option, context_listener_iface* listener)
-{
- subscr_map_t* map = (type == REQ_SUBSCRIBE)? &subscr_map : &read_map;
-
- subscr_info_s *info = new(std::nothrow) subscr_info_s(sid, subject, option);
- IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed");
- info->listener_list.push_back(listener);
-
- map->insert(std::pair<int, subscr_info_s*>(sid, info));
- return true;
-}
-
-void ctx::context_monitor::remove_sub(request_type type, const char* subject, Json* option)
-{
- subscr_map_t* map = (type == REQ_SUBSCRIBE)? &subscr_map : &read_map;
-
- Json opt_j;
- if (option) {
- opt_j = *option;
- }
-
- for (subscr_map_t::iterator it = map->begin(); it != map->end(); ++it) {
- if ((*(it->second)).subject == subject && (*(it->second)).option == opt_j) {
- delete it->second;
- map->erase(it);
- return;
- }
- }
-}
-
-void ctx::context_monitor::remove_sub(request_type type, int sid)
-{
- subscr_map_t* map = (type == REQ_SUBSCRIBE)? &subscr_map : &read_map;
-
- subscr_info_s* info = map->at(sid);
- info->listener_list.clear();
-
- delete info;
- map->erase(sid);
-
- return;
-}
-
-int ctx::context_monitor::add_listener(request_type type, int sid, context_listener_iface* listener)
-{
- // @return number of listeners for the corresponding sid
- subscr_map_t* map = (type == REQ_SUBSCRIBE)? &subscr_map : &read_map;
-
- subscr_map_t::iterator it = map->find(sid);
-
- subscr_info_s* info = it->second;
- info->listener_list.push_back(listener);
-
- return info->listener_list.size();
-}
-
-int ctx::context_monitor::remove_listener(request_type type, int sid, context_listener_iface* listener)
-{
- // @return number of listeners for the corresponding sid
- subscr_map_t* map = (type == REQ_SUBSCRIBE)? &subscr_map : &read_map;
-
- subscr_map_t::iterator it = map->find(sid);
-
- subscr_info_s* info = it->second;
-
- for (listener_list_t::iterator it2 = info->listener_list.begin(); it2 != info->listener_list.end(); ++it2) {
- if (*it2 == listener) {
- info->listener_list.erase(it2);
- break;
- }
- }
-
- return info->listener_list.size();
-}
-
-void ctx::context_monitor::reply_result(int req_id, int error, Json* request_result)
-{
- _D("Request result received: %d", req_id);
-
- last_rid = req_id;
- last_err = error;
-}
-
-void ctx::context_monitor::reply_result(int req_id, int error, const char* subject, Json* option, Json* fact)
-{
- _D(YELLOW("Condition received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str());
-
- subscr_map_t::iterator it = read_map.find(req_id);
- IF_FAIL_VOID_TAG(it != read_map.end(), _E, "Request id not found");
-
- subscr_info_s* info = it->second;
- for (listener_list_t::iterator it2 = info->listener_list.begin(); it2 != info->listener_list.end(); ++it2) {
- (*it2)->on_condition_received(subject, *option, *fact);
- }
-
- remove_sub(REQ_READ, req_id);
-}
-
-void ctx::context_monitor::publish_fact(int req_id, int error, const char* subject, Json* option, Json* fact)
-{
- _D(YELLOW("Event received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str());
-
- subscr_map_t::iterator it = subscr_map.find(req_id);
- IF_FAIL_VOID_TAG(it != subscr_map.end(), _E, "Request id not found");
-
- subscr_info_s* info = it->second;
- for (listener_list_t::iterator it2 = info->listener_list.begin(); it2 != info->listener_list.end(); ++it2) {
- (*it2)->on_event_received(subject, *option, *fact);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_MONITOR_H__
-#define __CONTEXT_MONITOR_H__
-
-#include <list>
-#include <map>
-#include <Json.h>
-
-namespace ctx {
-
- class fact_request;
- class context_manager_impl;
- class context_listener_iface;
-
- class context_monitor {
- public:
- static context_monitor* get_instance();
- static void set_context_manager(ctx::context_manager_impl* ctx_mgr);
- static void destroy();
-
- int subscribe(int rule_id, std::string subject, ctx::Json option, context_listener_iface* listener);
- int unsubscribe(int rule_id, std::string subject, ctx::Json option, context_listener_iface* listener);
- int read(std::string subject, Json option, context_listener_iface* listener);
- bool is_supported(std::string subject);
- bool is_allowed(const char *client, const char *subject);
-
- void reply_result(int req_id, int error, Json *request_result = NULL);
- void reply_result(int req_id, int error, const char *subject, ctx::Json *option, ctx::Json *fact);
- void publish_fact(int req_id, int error, const char *subject, ctx::Json *option, ctx::Json *fact);
-
- private:
- context_monitor();
- context_monitor(const context_monitor& other);
- ~context_monitor();
-
- static context_monitor *_instance;
- static context_manager_impl *_context_mgr;
-
- int _subscribe(const char* subject, ctx::Json* option, context_listener_iface* listener);
- void _unsubscribe(const char *subject, int subscription_id);
- int _read(const char *subject, ctx::Json *option, context_listener_iface* listener);
-
- typedef std::list<context_listener_iface*> listener_list_t;
-
- struct subscr_info_s {
- int sid;
- std::string subject;
- ctx::Json option;
- listener_list_t listener_list;
-
- subscr_info_s(int id, const char *subj, ctx::Json *opt)
- : sid(id), subject(subj)
- {
- if (opt)
- option = *opt;
- }
- };
-
- typedef std::map<int, subscr_info_s*> subscr_map_t;
- subscr_map_t subscr_map;
- subscr_map_t read_map;
-
- int find_sub(request_type type, const char *subject, ctx::Json *option);
- bool add_sub(request_type type, int sid, const char *subject, ctx::Json *option, context_listener_iface* listener);
- void remove_sub(request_type type, const char *subject, ctx::Json *option);
- void remove_sub(request_type type, int sid);
- int add_listener(request_type type, int sid, context_listener_iface* listener);
- int remove_listener(request_type type, int sid, context_listener_iface* listener);
-
- }; /* class context_monitor */
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_MONITOR_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <types_internal.h>
-#include "fact.h"
-
-ctx::context_fact::context_fact()
- : req_id(-1)
- , error(ERR_NONE)
-{
-}
-
-ctx::context_fact::context_fact(int id, int err, const char* s, ctx::Json& o, ctx::Json& d)
- : req_id(id)
- , error(err)
- , subject(s)
- , option(o)
- , data(d)
-{
-}
-
-ctx::context_fact::~context_fact()
-{
-}
-
-void ctx::context_fact::set_req_id(int id)
-{
- req_id = id;
-}
-
-void ctx::context_fact::set_error(int err)
-{
- error = err;
-}
-
-void ctx::context_fact::set_subject(const char* s)
-{
- subject = s;
-}
-
-void ctx::context_fact::set_option(ctx::Json& o)
-{
- option = o;
-}
-
-void ctx::context_fact::set_data(ctx::Json& d)
-{
- data = d;
-}
-
-int ctx::context_fact::get_req_id()
-{
- return req_id;
-}
-
-int ctx::context_fact::get_error()
-{
- return error;
-}
-
-const char* ctx::context_fact::get_subject()
-{
- return subject.c_str();
-}
-
-ctx::Json& ctx::context_fact::get_option()
-{
- return option;
-}
-
-ctx::Json& ctx::context_fact::get_data()
-{
- return data;
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_CONTEXT_TRIGGER_FACT_H__
-#define __CONTEXT_CONTEXT_TRIGGER_FACT_H__
-
-#include <string>
-#include <Json.h>
-
-namespace ctx {
-
- class context_fact {
- private:
- int req_id;
- int error;
- std::string subject;
- ctx::Json option;
- ctx::Json data;
-
- public:
- context_fact();
- context_fact(int id, int err, const char* s, ctx::Json& o, ctx::Json& d);
- ~context_fact();
-
- void set_req_id(int id);
- void set_error(int err);
- void set_subject(const char* s);
- void set_option(ctx::Json& o);
- void set_data(ctx::Json& d);
-
- int get_req_id();
- int get_error();
- const char* get_subject();
- ctx::Json& get_option();
- ctx::Json& get_data();
- };
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_CONTEXT_TRIGGER_FACT_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <types_internal.h>
-#include "fact_request.h"
-
-ctx::fact_request::fact_request(int type, int req_id, const char* subj, const char* desc, context_monitor* ctx_monitor)
- : request_info(type, req_id, subj, desc)
- , _ctx_monitor(ctx_monitor)
- , replied(false)
-{
-}
-
-ctx::fact_request::~fact_request()
-{
- reply(ERR_OPERATION_FAILED);
-}
-
-const char* ctx::fact_request::get_client()
-{
- return "TRIGGER";
-}
-
-bool ctx::fact_request::reply(int error)
-{
- IF_FAIL_RETURN(!replied && _ctx_monitor, true);
- _ctx_monitor->reply_result(_req_id, error);
- replied = (error != ERR_NONE);
- return true;
-}
-
-bool ctx::fact_request::reply(int error, ctx::Json& request_result)
-{
- IF_FAIL_RETURN(!replied && _ctx_monitor, true);
- _ctx_monitor->reply_result(_req_id, error, &request_result);
- replied = (error != ERR_NONE);
- return true;
-}
-
-bool ctx::fact_request::reply(int error, ctx::Json& request_result, ctx::Json& data_read)
-{
- IF_FAIL_RETURN(!replied && _ctx_monitor, true);
- _ctx_monitor->reply_result(_req_id, error, _subject.c_str(), &get_description(), &data_read);
- return (replied = true);
-}
-
-bool ctx::fact_request::publish(int error, ctx::Json& data)
-{
- IF_FAIL_RETURN(_ctx_monitor, true);
- _ctx_monitor->publish_fact(_req_id, error, _subject.c_str(), &get_description(), &data);
- return true;
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_TRIGGER_FACT_REQUEST_H__
-#define __CONTEXT_TRIGGER_FACT_REQUEST_H__
-
-#include "context_monitor.h"
-#include "../request.h"
-
-namespace ctx {
-
- class fact_request : public request_info {
- public:
- fact_request(int type, int req_id, const char* subj, const char* desc, context_monitor* ctx_monitor);
- ~fact_request();
-
- const char* get_client();
- 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:
- context_monitor *_ctx_monitor;
- bool replied;
- };
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_TRIGGER_FACT_REQUEST_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <context_trigger_types_internal.h>
-#include "rule.h"
-#include "action_manager.h"
-#include "rule_evaluator.h"
-#include "context_monitor.h"
-#include "context_fact_types.h"
-#include "rule_manager.h"
-
-ctx::rule_manager *ctx::trigger_rule::rule_mgr = NULL;
-
-ctx::trigger_rule::trigger_rule(int i, ctx::Json& d, const char* p, rule_manager* rm)
- : result(EMPTY_JSON_OBJECT)
- , id(i)
- , pkg_id(p)
-{
- // Rule manager
- if (!rule_mgr) {
- rule_mgr = rm;
- }
-
- // Statement
- statement = d.str();
-
- // Event
- ctx::Json e;
- d.get(NULL, CT_RULE_EVENT, &e);
- event = new(std::nothrow) context_item_s(e);
-
- // Condition
- int cond_num = d.getSize(NULL, CT_RULE_CONDITION);
- for (int j = 0; j < cond_num; j++) {
- ctx::Json c;
- d.getAt(NULL, CT_RULE_CONDITION, j, &c);
- condition.push_back(new(std::nothrow) context_item_s(c));
- }
-
- // Action
- ctx::Json a;
- d.get(NULL, CT_RULE_ACTION, &a);
- action = a.str();
-}
-
-ctx::trigger_rule::~trigger_rule()
-{
- // Release resources
- delete event;
- for (std::list<context_item_t>::iterator it = condition.begin(); it != condition.end(); ++it) {
- delete *it;
- }
-}
-
-int ctx::trigger_rule::start(void)
-{
- // Subscribe event
- int error = ctx::context_monitor::get_instance()->subscribe(id, event->name, event->option, this);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to start rule%d", id);
-
- return error;
-}
-
-int ctx::trigger_rule::stop(void)
-{
- // Unsubscribe event
- int error = ctx::context_monitor::get_instance()->unsubscribe(id, event->name, event->option, this);
- if (error == ERR_NOT_SUPPORTED) {
- _E("Stop rule%d (event not supported)");
- return ERR_NONE;
- }
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", id);
-
- return error;
-}
-
-bool ctx::trigger_rule::set_condition_option_based_on_event(ctx::Json& option)
-{
- // Set condition option if it references event data
- std::list<std::string> option_keys;
- option.getKeys(&option_keys);
-
- for (std::list<std::string>::iterator it = option_keys.begin(); it != option_keys.end(); ++it) {
- std::string opt_key = (*it);
-
- std::string opt_val;
- if (option.get(NULL, opt_key.c_str(), &opt_val)) {
- if (opt_val.find("?") != 0) {
- continue;
- }
-
- std::string event_key = opt_val.substr(1, opt_val.length() - 1);
-
- std::string new_str;
- int new_val;
- if (result.get(CONTEXT_FACT_EVENT "." CONTEXT_FACT_DATA, event_key.c_str(), &new_str)) {
- option.set(NULL, opt_key.c_str(), new_str);
- } else if (result.get(CONTEXT_FACT_EVENT "." CONTEXT_FACT_DATA, event_key.c_str(), &new_val)) {
- option.set(NULL, opt_key.c_str(), new_val);
- } else {
- _W("Failed to find '%s' in event data", event_key.c_str());
- return false;
- }
- }
- }
-
- return true;
-}
-
-void ctx::trigger_rule::on_event_received(std::string name, ctx::Json option, ctx::Json data)
-{
- if (result != EMPTY_JSON_OBJECT) {
- clear_result();
- }
-
- // Check if creator package is uninstalled
- if (ctx::rule_manager::is_uninstalled_package(pkg_id)) {
- _D("Creator(%s) of rule%d is uninstalled.", pkg_id.c_str(), id);
- g_idle_add(handle_uninstalled_rule, &pkg_id);
- return;
- }
-
- _D("Rule%d received event data", id);
-
- // Set event data
- result.set(CONTEXT_FACT_EVENT, CONTEXT_FACT_NAME, name);
- result.set(CONTEXT_FACT_EVENT, CONTEXT_FACT_OPTION, option);
- result.set(CONTEXT_FACT_EVENT, CONTEXT_FACT_DATA, data);
-
- if (condition.size() == 0) {
- on_context_data_prepared();
- return;
- }
-
- IF_FAIL_VOID_TAG(ctx::rule_evaluator::evaluate_rule(statement, result), _E, "Event not matched");
-
- // Request read conditions
- for (std::list<context_item_t>::iterator it = condition.begin(); it != condition.end(); ++it) {
- ctx::Json cond_option = (*it)->option.str();
- if (!set_condition_option_based_on_event(cond_option)) { // cond_option should be copy of original option.
- clear_result();
- return;
- }
-
- int error = ctx::context_monitor::get_instance()->read((*it)->name.c_str(), cond_option, this);
- IF_FAIL_VOID_TAG(error == ERR_NONE, _E, "Failed to read condition");
- }
-
- // TODO timer set
-}
-
-void ctx::trigger_rule::on_condition_received(std::string name, ctx::Json option, ctx::Json data)
-{
- _D("Rule%d received condition data", id);
-
- // Set condition data
- ctx::Json item;
- item.set(NULL, CONTEXT_FACT_NAME, name);
- item.set(NULL, CONTEXT_FACT_OPTION, option);
- item.set(NULL, CONTEXT_FACT_DATA, data);
- result.append(NULL, CONTEXT_FACT_CONDITION, item);
-
- if (result.getSize(NULL, CONTEXT_FACT_CONDITION) == (int) condition.size()) {
- on_context_data_prepared();
- }
-}
-
-void ctx::trigger_rule::clear_result()
-{
- result = EMPTY_JSON_OBJECT;
- // TODO timer cancel
-}
-
-void ctx::trigger_rule::on_context_data_prepared(void)
-{
- if (ctx::rule_evaluator::evaluate_rule(statement, result)) {
- ctx::action_manager::trigger_action(action, pkg_id);
- }
- clear_result();
-}
-
-gboolean ctx::trigger_rule::handle_uninstalled_rule(gpointer data)
-{
- std::string* pkg_id = static_cast<std::string*>(data);
- rule_mgr->handle_rule_of_uninstalled_package(*pkg_id);
-
- return FALSE;
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_TRIGGER_RULE_H__
-#define __CONTEXT_TRIGGER_RULE_H__
-
-#include <string>
-#include <Json.h>
-#include "context_listener_iface.h"
-
-namespace ctx {
-
- class rule_manager;
-
- class trigger_rule : public context_listener_iface {
- private:
- struct context_item_s {
- std::string name;
- ctx::Json option;
- context_item_s(ctx::Json item) {
- std::string n;
- item.get(NULL, CT_RULE_EVENT_ITEM, &n);
- name = n;
-
- ctx::Json o;
- if (item.get(NULL, CT_RULE_EVENT_OPTION, &o))
- option = o.str();
- }
- };
-
- typedef struct context_item_s* context_item_t;
- ctx::Json statement;
- context_item_t event;
- std::list<context_item_t> condition;
- ctx::Json action;
- ctx::Json result;
-
- static rule_manager* rule_mgr;
-
- void clear_result(void);
- bool set_condition_option_based_on_event(ctx::Json& option);
- void on_context_data_prepared(void);
-
- static gboolean handle_uninstalled_rule(gpointer data);
-
- public:
- int id;
- std::string pkg_id;
-
- trigger_rule(int i, ctx::Json& d, const char* p, rule_manager* rm);
- ~trigger_rule();
-
- int start(void);
- int stop(void);
-
- void on_event_received(std::string name, ctx::Json option, ctx::Json data);
- void on_condition_received(std::string name, ctx::Json option, ctx::Json data);
-
- };
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_TRIGGER_RULE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <Json.h>
-#include <types_internal.h>
-#include <context_trigger_types_internal.h>
-#include "rule_evaluator.h"
-#include "context_fact_types.h"
-
-#define AND_STRING "and"
-#define OR_STRING "or"
-#define EVENT_REFERENCE "?"
-#define OPERATOR_EQ "=="
-#define OPERATOR_NEQ "!="
-#define OPERATOR_LEQ "<="
-#define OPERATOR_GEQ ">="
-#define OPERATOR_LT "<"
-#define OPERATOR_GT ">"
-
-ctx::rule_evaluator::rule_evaluator()
-{
-}
-
-bool ctx::rule_evaluator::compare_string(std::string operation, std::string rule_var, std::string fact_var)
-{
- if (operation == OPERATOR_EQ) {
- return (rule_var == fact_var);
- } else if (operation == OPERATOR_NEQ) {
- return (rule_var != fact_var);
- } else {
- _E("Operator %s not supported", operation.c_str());
- return false;
- }
-}
-
-bool ctx::rule_evaluator::compare_int(std::string operation, int rule_var, int fact_var)
-{
- if (operation == OPERATOR_EQ) {
- return (rule_var == fact_var);
- } else if (operation == OPERATOR_NEQ) {
- return (rule_var != fact_var);
- } else if (operation == OPERATOR_LEQ) {
- return (rule_var <= fact_var);
- } else if (operation == OPERATOR_GEQ) {
- return (rule_var >= fact_var);
- } else if (operation == OPERATOR_LT) {
- return (rule_var < fact_var);
- } else if (operation == OPERATOR_GT) {
- return (rule_var > fact_var);
- } else {
- _E("Operator %s not supported", operation.c_str());
- return false;
- }
-}
-
-bool ctx::rule_evaluator::replace_data_references(ctx::Json& rule_data_arr, ctx::Json event_fact_data)
-{
- std::string arr_string;
- std::string event_reference_string;
- int event_reference_int;
-
- for (int i = 0; i < rule_data_arr.getSize(NULL, CT_RULE_DATA_VALUE_ARR); i++) {
- if (!rule_data_arr.getAt(NULL, CT_RULE_DATA_VALUE_ARR, i, &arr_string)) {
- continue;
- }
- if (arr_string.substr(0, 1) != EVENT_REFERENCE) {
- continue;
- }
-
- std::string event_key = arr_string.substr(1, arr_string.length() - 1);
- if (event_fact_data.get(NULL, event_key.c_str(), &event_reference_string)) {
- rule_data_arr.setAt(NULL, CT_RULE_DATA_VALUE_ARR, i, event_reference_string);
- } else if (event_fact_data.get(NULL, event_key.c_str(), &event_reference_int)) {
- rule_data_arr.setAt(NULL, CT_RULE_DATA_VALUE_ARR, i, event_reference_int);
- } else {
- _W("Option %s not found in event_data", event_key.c_str());
- }
- }
-
- return true;
-}
-
-bool ctx::rule_evaluator::replace_option_references(ctx::Json& rule_option, ctx::Json event_fact_data)
-{
- std::list<std::string> key_list;
- rule_option.getKeys(&key_list);
-
- for (std::list<std::string>::iterator it = key_list.begin(); it != key_list.end(); ++it) {
- std::string option_key = *it;
- std::string rule_key_value_str;
-
- if (!rule_option.get(NULL, (*it).c_str(), &rule_key_value_str)) {
- continue;
- }
- if (!(rule_key_value_str.substr(0, 1) == EVENT_REFERENCE)) {
- continue;
- }
-
- int rule_event_key_value_int;
- std::string rule_event_key_value_str;
- std::string event_key = rule_key_value_str.substr(1, rule_key_value_str.length() - 1);
- if (event_fact_data.get(NULL, event_key.c_str(), &rule_event_key_value_str)) {
- rule_option.set(NULL, (*it).c_str(), rule_event_key_value_str);
- } else if (event_fact_data.get(NULL, event_key.c_str(), &rule_event_key_value_int)) {
- rule_option.set(NULL, (*it).c_str(), rule_event_key_value_int);
- } else {
- _W("Option %s not found in event_data", event_key.c_str());
- return false;
- }
- }
-
- return true;
-}
-
-bool ctx::rule_evaluator::replace_event_references(ctx::Json& rule, ctx::Json& fact)
-{
- ctx::Json event_fact_data;
- if (!fact.get(CONTEXT_FACT_EVENT, CONTEXT_FACT_DATA, &event_fact_data)) {
- _E("No event data found, error");
- return false;
- }
-
- ctx::Json rule_condition;
- for (int i = 0; rule.getAt(NULL, CT_RULE_CONDITION, i, &rule_condition); i++) {
- ctx::Json rule_data_arr;
- for (int j = 0; rule_condition.getAt(NULL, CT_RULE_DATA_ARR, j, &rule_data_arr); j++) {
- replace_data_references(rule_data_arr, event_fact_data);
- }
-
- ctx::Json rule_option;
- if (rule_condition.get(NULL, CT_RULE_CONDITION_OPTION, &rule_option)) {
- replace_option_references(rule_option, event_fact_data);
- }
- }
-
- return true;
-}
-
-bool ctx::rule_evaluator::evaluate_data_string(ctx::Json& rule_data_arr, std::string fact_value_str)
-{
- std::string operate_internal;
- rule_data_arr.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &operate_internal);
- bool is_and = false;
- if (AND_STRING == operate_internal) {
- is_and = true;
- }
-
- std::string operator_str;
- for (int j = 0; rule_data_arr.getAt(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, j, &operator_str); j++) {
- bool data_arr_vale_match;
- std::string get_str_val;
- rule_data_arr.getAt(NULL, CT_RULE_DATA_VALUE_ARR, j, &get_str_val);
- data_arr_vale_match = compare_string(operator_str, fact_value_str, get_str_val);
-
- if (is_and && !data_arr_vale_match) {
- return false;
- } else if (!is_and && data_arr_vale_match) {
- return true;
- }
- }
- return is_and;
-}
-
-bool ctx::rule_evaluator::evaluate_data_int(ctx::Json& rule_data_arr, int fact_value_int)
-{
- std::string operate_internal;
- rule_data_arr.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &operate_internal);
- bool is_and = false;
- if (AND_STRING == operate_internal) {
- is_and = true;
- }
-
- std::string operator_str;
- for (int j = 0; rule_data_arr.getAt(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, j, &operator_str); j++) {
- bool data_arr_vale_match;
- int get_int_val;
- if (!rule_data_arr.getAt(NULL, CT_RULE_DATA_VALUE_ARR, j, &get_int_val)) {
- data_arr_vale_match = false;
- }
- data_arr_vale_match = compare_int(operator_str, fact_value_int, get_int_val);
-
- if (is_and && !data_arr_vale_match) {
- return false;
- } else if (!is_and && data_arr_vale_match) {
- return true;
- }
- }
- return is_and;
-}
-
-bool ctx::rule_evaluator::evaluate_item(ctx::Json& rule_item, ctx::Json& fact_item)
-{
- ctx::Json rule_data_arr;
- if (rule_item.getSize(NULL, CT_RULE_DATA_ARR) == 0) {
- return true;
- }
-
- std::string operate;
- bool is_and = false;
- rule_item.get(NULL, CT_RULE_CONDITION_OPERATOR, &operate);
- if (AND_STRING == operate) {
- is_and = true;
- }
-
- for (int i = 0; rule_item.getAt(NULL, CT_RULE_DATA_ARR, i, &rule_data_arr); i++) {
- std::string data_key;
- rule_data_arr.get(NULL, CT_RULE_DATA_KEY, &data_key);
- std::string fact_value_str;
- int fact_value_int;
-
- bool rule_data_arr_true;
- if (fact_item.get(CONTEXT_FACT_DATA, data_key.c_str(), &fact_value_str)) {
- rule_data_arr_true = evaluate_data_string(rule_data_arr, fact_value_str);
- } else if (fact_item.get(CONTEXT_FACT_DATA, data_key.c_str(), &fact_value_int)) {
- rule_data_arr_true = evaluate_data_int(rule_data_arr, fact_value_int);
- } else {
- _W("Could not get value corresponding to data key %s", data_key.c_str());
- rule_data_arr_true = false;
- }
-
- if (is_and && !rule_data_arr_true) {
- return false;
- } else if (!is_and && rule_data_arr_true) {
- return true;
- }
- }
- return is_and;
-}
-
-bool ctx::rule_evaluator::check_rule_event(ctx::Json& rule, ctx::Json& fact)
-{
- ctx::Json fact_item;
- fact.get(NULL, CONTEXT_FACT_EVENT, &fact_item);
- ctx::Json rule_item;
- rule.get(NULL, CT_RULE_EVENT, &rule_item);
- return evaluate_item(rule_item, fact_item);
-}
-
-ctx::Json ctx::rule_evaluator::find_condition_fact(ctx::Json& rule_condition, ctx::Json& fact)
-{
- ctx::Json fact_condition;
- std::string item_name_rule_condition;
- rule_condition.get(NULL, CT_RULE_CONDITION_ITEM, &item_name_rule_condition);
-
- std::string item_name_fact_condition;
- for (int i = 0; fact.getAt(NULL, CONTEXT_FACT_CONDITION, i, &fact_condition); i++) {
- fact_condition.get(NULL, CONTEXT_FACT_NAME, &item_name_fact_condition);
- if (item_name_fact_condition != item_name_rule_condition) {
- continue;
- }
-
- ctx::Json rule_condition_option;
- ctx::Json fact_condition_option;
- rule_condition.get(NULL, CT_RULE_CONDITION_OPTION, &rule_condition_option);
- fact_condition.get(NULL, CONTEXT_FACT_OPTION, &fact_condition_option);
- if (fact_condition_option == rule_condition_option) {
- return fact_condition;
- }
- }
-
- _W(YELLOW("find_condition failed for condition"));
- return EMPTY_JSON_OBJECT;
-}
-
-bool ctx::rule_evaluator::check_rule_condition(ctx::Json& rule, ctx::Json& fact)
-{
- ctx::Json rule_condition;
- ctx::Json fact_condition;
-
- std::string operate;
- rule.get(NULL, CT_RULE_OPERATOR, &operate);
- bool is_and = false;
- if (operate == AND_STRING) {
- is_and = true;
- }
-
- for (int i = 0; rule.getAt(NULL, CT_RULE_CONDITION, i, &rule_condition); i++) {
- fact_condition = find_condition_fact(rule_condition, fact);
- bool condition_satisfied;
- if (fact_condition == EMPTY_JSON_OBJECT) {
- condition_satisfied = false;
- } else {
- condition_satisfied = evaluate_item(rule_condition, fact_condition);
- }
-
- if (is_and && !condition_satisfied) {
- return false;
- } else if (!is_and && condition_satisfied) {
- return true;
- }
- }
-
- return is_and;
-}
-
-bool ctx::rule_evaluator::evaluate_rule(ctx::Json rule, ctx::Json fact)
-{
- _D("Rule is %s ", rule.str().c_str());
- _D("fact is %s ", fact.str().c_str());
- rule_evaluator eval;
- bool ret;
- ctx::Json temp_json;
- if (fact.get(NULL, CT_RULE_CONDITION, &temp_json)) {
- ctx::Json rule_copy(rule.str());
- if (!eval.replace_event_references(rule_copy, fact)) {
- _W("Replace failed");
- }
- ret = eval.check_rule_condition(rule_copy, fact);
- _D("Checking condition %s", ret ? "true" : "false");
- } else {
- ret = eval.check_rule_event(rule, fact);
- _D("Checking event %s", ret ? "true" : "false");
- }
- return ret;
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_RULE_EVALUATOR_H__
-#define __CONTEXT_RULE_EVALUATOR_H__
-
-namespace ctx {
-
- class Json;
-
- class rule_evaluator {
- private:
- rule_evaluator();
- bool evaluate_item(ctx::Json& rule_item, ctx::Json& fact_item);
- bool compare_int(std::string operation, int rule_var, int fact_var);
- bool compare_string(std::string operation, std::string rule_var, std::string fact_var);
- bool check_rule_event(ctx::Json& rule, ctx::Json& fact);
- ctx::Json find_condition_fact(ctx::Json& rule_condition, ctx::Json& fact);
- bool check_rule_condition(ctx::Json& rule, ctx::Json& fact);
- bool replace_data_references(ctx::Json& rule_data_arr, ctx::Json event_fact_data);
- bool replace_option_references(ctx::Json& rule_option, ctx::Json event_fact_data);
- bool replace_event_references(ctx::Json& rule, ctx::Json& fact);
- bool evaluate_data_string(ctx::Json& rule_data_arr, std::string fact_value_str);
- bool evaluate_data_int(ctx::Json& rule_data_arr, int fact_value_int);
- public:
- static bool evaluate_rule(ctx::Json rule, ctx::Json data);
- };
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_RULE_EVALUATOR_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <sstream>
-#include <Json.h>
-#include <context_trigger_types_internal.h>
-#include <db_mgr.h>
-#include <package_manager.h>
-#include "rule_manager.h"
-#include "context_monitor.h"
-#include "rule.h"
-#include "timer.h"
-
-#define RULE_TABLE "context_trigger_rule"
-
-static int string_to_int(std::string str)
-{
- int i;
- std::istringstream convert(str);
-
- if (!(convert >> i))
- i = 0;
-
- return i;
-}
-
-static std::string int_to_string(int i)
-{
- std::ostringstream convert;
- convert << i;
- std::string str = convert.str();
- return str;
-}
-
-ctx::rule_manager::rule_manager()
-{
-}
-
-ctx::rule_manager::~rule_manager()
-{
-}
-
-bool ctx::rule_manager::init()
-{
- bool ret;
- int error;
-
- // Create tables into db (rule, template)
- std::string q1 = std::string("status INTEGER DEFAULT 0 NOT NULL, creator TEXT DEFAULT '' NOT NULL,")
- + "package_id TEXT DEFAULT '' NOT NULL, description TEXT DEFAULT '',"
- + "details TEXT DEFAULT '' NOT NULL";
- ret = db_manager::create_table(1, RULE_TABLE, q1.c_str(), NULL, NULL);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Create rule table failed");
-
- // Before re-enable rules, handle uninstalled app's rules
- if (get_uninstalled_app() > 0) {
- error = clear_rule_of_uninstalled_package(true);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Failed to remove uninstalled apps' rules while initialization");
- }
- ret = reenable_rule();
-
- return ret;
-}
-
-void ctx::rule_manager::handle_rule_of_uninstalled_package(std::string pkg_id)
-{
- uninstalled_packages.insert(pkg_id);
- clear_rule_of_uninstalled_package();
-}
-
-int ctx::rule_manager::get_uninstalled_app(void)
-{
- // Return number of uninstalled apps
- std::string q1 = "SELECT DISTINCT package_id FROM context_trigger_rule";
-
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(q1.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, -1, _E, "Query package ids of registered rules failed");
-
- std::vector<Json>::iterator vec_end = record.end();
- for (std::vector<Json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
- ctx::Json elem = *vec_pos;
- std::string pkg_id;
- elem.get(NULL, "package_id", &pkg_id);
-
- if (is_uninstalled_package(pkg_id)) {
- uninstalled_packages.insert(pkg_id);
- }
- }
-
- return uninstalled_packages.size();
-}
-
-bool ctx::rule_manager::is_uninstalled_package(std::string pkg_id)
-{
- IF_FAIL_RETURN_TAG(!pkg_id.empty(), false, _D, "Empty package id");
-
- package_info_h pkg_info;
- int error = package_manager_get_package_info(pkg_id.c_str(), &pkg_info);
-
- if (error == PACKAGE_MANAGER_ERROR_NONE) {
- package_info_destroy(pkg_info);
- } else if (error == PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE) {
- // Uninstalled package found
- _D("Uninstalled package found: %s", pkg_id.c_str());
- return true;
- } else {
- _E("Failed to get package info(%s): %d", pkg_id.c_str(), error);
- }
-
- return false;
-}
-
-int ctx::rule_manager::clear_rule_of_uninstalled_package(bool is_init)
-{
- if (uninstalled_packages.size() <= 0) {
- return ERR_NONE;
- }
-
- int error;
- bool ret;
-
- _D("Clear uninstalled packages' rule started");
- // Package list
- std::string pkg_list = "(";
- std::set<std::string>::iterator it = uninstalled_packages.begin();
- pkg_list += "package_id = '" + *it + "'";
- it++;
- for (; it != uninstalled_packages.end(); ++it) {
- pkg_list += " OR package_id = '" + *it + "'";
- }
- pkg_list += ")";
-
- // After event received, disable all the enabled rules of uninstalled apps
- if (!is_init) {
- std::string q1 = "SELECT row_id FROM context_trigger_rule WHERE status = 2 and (";
- q1 += pkg_list;
- q1 += ")";
-
- std::vector<Json> record;
- ret = db_manager::execute_sync(q1.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query enabled rules of uninstalled packages");
-
- std::vector<Json>::iterator vec_end = record.end();
- for (std::vector<Json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
- ctx::Json elem = *vec_pos;
- int rule_id;
- elem.get(NULL, "row_id", &rule_id);
- error = disable_rule(rule_id);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rule" );
- }
- _D("Uninstalled packages' rules are disabled");
- }
-
- // Delete rules of uninstalled packages from DB
- std::string q2 = "DELETE FROM context_trigger_rule WHERE " + pkg_list;
- std::vector<Json> dummy;
- ret = db_manager::execute_sync(q2.c_str(), &dummy);
- IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to remove rules from db");
- _D("Uninstalled packages' rules are deleted from db");
-
- uninstalled_packages.clear();
-
- return ERR_NONE;
-}
-
-int ctx::rule_manager::pause_rule_with_item(std::string& subject)
-{
- std::string q = "SELECT row_id FROM context_trigger_rule WHERE (status=2) AND (details LIKE '%\"ITEM_NAME\":\"" + subject + "\"%');";
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query row_ids to be paused");
- IF_FAIL_RETURN(record.size() > 0, ERR_NONE);
-
- _D("Pause rules related to %s", subject.c_str());
- std::vector<Json>::iterator vec_end = record.end();
- for (std::vector<Json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
- ctx::Json elem = *vec_pos;
- int row_id;
- elem.get(NULL, "row_id", &row_id);
-
- int error = pause_rule(row_id);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rules using custom item");
- }
-
- return ERR_NONE;
-}
-
-int ctx::rule_manager::resume_rule_with_item(std::string& subject)
-{
- std::string q = "SELECT row_id FROM context_trigger_rule WHERE (status=1) AND (details LIKE '%\"ITEM_NAME\":\"" + subject + "\"%');";
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query paused rule ids failed");
- IF_FAIL_RETURN(record.size() > 0, ERR_NONE);
-
- _D("Resume rules related to %s", subject.c_str());
- std::string q_rowid;
- std::vector<Json>::iterator vec_end = record.end();
- for (std::vector<Json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
- ctx::Json elem = *vec_pos;
- int row_id;
- elem.get(NULL, "row_id", &row_id);
-
- int error = enable_rule(row_id);
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to resume rule");
- }
-
- return ERR_NONE;
-}
-
-bool ctx::rule_manager::reenable_rule(void)
-{
- int error;
- std::string q = "SELECT row_id FROM context_trigger_rule WHERE status = 2";
-
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Query row_ids of enabled rules failed");
- IF_FAIL_RETURN_TAG(record.size() > 0, true, _D, "No rule to re-enable");
-
- _D(YELLOW("Re-enable rule started"));
-
- std::string q_rowid;
- q_rowid.clear();
- std::vector<Json>::iterator vec_end = record.end();
- for (std::vector<Json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
- ctx::Json elem = *vec_pos;
- int row_id;
- elem.get(NULL, "row_id", &row_id);
-
- error = enable_rule(row_id);
- if (error == ERR_NOT_SUPPORTED) {
- q_rowid += "(row_id = " + int_to_string(row_id) + ") OR ";
- } else if (error != ERR_NONE) {
- _E("Re-enable rule%d failed(%d)", row_id, error);
- }
- }
- IF_FAIL_RETURN(!q_rowid.empty(), true);
- q_rowid = q_rowid.substr(0, q_rowid.length() - 4);
-
- // For rules which is failed to re-enable
- std::string q_update = "UPDATE context_trigger_rule SET status = 1 WHERE " + q_rowid;
- std::vector<Json> record2;
- ret = db_manager::execute_sync(q_update.c_str(), &record2);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to update rules as paused");
-
- return true;
-}
-
-bool ctx::rule_manager::rule_data_arr_elem_equals(ctx::Json& lelem, ctx::Json& relem)
-{
- std::string lkey, rkey;
- lelem.get(NULL, CT_RULE_DATA_KEY, &lkey);
- relem.get(NULL, CT_RULE_DATA_KEY, &rkey);
- if (lkey.compare(rkey))
- return false;
-
- int lvc, rvc, lvoc, rvoc;
- lvc = lelem.getSize(NULL, CT_RULE_DATA_VALUE_ARR);
- rvc = relem.getSize(NULL, CT_RULE_DATA_VALUE_ARR);
- lvoc = lelem.getSize(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR);
- rvoc = relem.getSize(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR);
- if (!((lvc == rvc) && (lvc == lvoc) && (lvc && rvoc)))
- return false;
-
- if (lvc > 1) {
- std::string lop, rop;
- lelem.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &lop);
- relem.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &rop);
- if (lop.compare(rop))
- return false;
- }
-
- for (int i = 0; i < lvc; i++) {
- bool found = false;
- std::string lv, lvo;
- lelem.getAt(NULL, CT_RULE_DATA_VALUE_ARR, i, &lv);
- lelem.getAt(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, i, &lvo);
-
- for (int j = 0; j < lvc; j++) {
- std::string rv, rvo;
- relem.getAt(NULL, CT_RULE_DATA_VALUE_ARR, j, &rv);
- relem.getAt(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, j, &rvo);
-
- if (!lv.compare(rv) && !lvo.compare(rvo)) {
- found = true;
- break;
- }
- }
- if (!found)
- return false;
- }
-
- return true;
-}
-
-bool ctx::rule_manager::rule_item_equals(ctx::Json& litem, ctx::Json& ritem)
-{
- // Compare item name
- std::string lei, rei;
- litem.get(NULL, CT_RULE_EVENT_ITEM, &lei);
- ritem.get(NULL, CT_RULE_EVENT_ITEM, &rei);
- if (lei.compare(rei))
- return false;
-
- // Compare option
- ctx::Json loption, roption;
- litem.get(NULL, CT_RULE_EVENT_OPTION, &loption);
- ritem.get(NULL, CT_RULE_EVENT_OPTION, &roption);
- if (loption != roption)
- return false;
-
- int ledac, redac;
- ledac = litem.getSize(NULL, CT_RULE_DATA_ARR);
- redac = ritem.getSize(NULL, CT_RULE_DATA_ARR);
- if (ledac != redac)
- return false;
-
- // Compare item operator;
- if (ledac > 1 ) {
- std::string leop, reop;
- litem.get(NULL, CT_RULE_EVENT_OPERATOR, &leop);
- ritem.get(NULL, CT_RULE_EVENT_OPERATOR, &reop);
- if (leop.compare(reop))
- return false;
- }
-
- for (int i = 0; i < ledac; i++) {
- bool found = false;
- ctx::Json lelem;
- litem.getAt(NULL, CT_RULE_DATA_ARR, i, &lelem);
-
- for (int j = 0; j < ledac; j++) {
- ctx::Json relem;
- ritem.getAt(NULL, CT_RULE_DATA_ARR, j, &relem);
-
- if (rule_data_arr_elem_equals(lelem, relem)) {
- found = true;
- break;
- }
- }
- if (!found)
- return false;
- }
-
- return true;
-}
-
-bool ctx::rule_manager::rule_equals(ctx::Json& lrule, ctx::Json& rrule)
-{
- // Compare event
- ctx::Json le, re;
- lrule.get(NULL, CT_RULE_EVENT, &le);
- rrule.get(NULL, CT_RULE_EVENT, &re);
- if (!rule_item_equals(le, re))
- return false;
-
- // Compare conditions
- int lcc, rcc;
- lcc = lrule.getSize(NULL, CT_RULE_CONDITION);
- rcc = rrule.getSize(NULL, CT_RULE_CONDITION);
- if (lcc != rcc)
- return false;
-
- if (lcc > 1) {
- std::string lop, rop;
- lrule.get(NULL, CT_RULE_OPERATOR, &lop);
- rrule.get(NULL, CT_RULE_OPERATOR, &rop);
- if (lop.compare(rop))
- return false;
- }
-
- for (int i = 0; i < lcc; i++) {
- bool found = false;
- ctx::Json lc;
- lrule.getAt(NULL, CT_RULE_CONDITION, i, &lc);
-
- for (int j = 0; j < lcc; j++) {
- ctx::Json rc;
- rrule.getAt(NULL, CT_RULE_CONDITION, j, &rc);
-
- if (rule_item_equals(lc, rc)) {
- found = true;
- break;
- }
- }
- if (!found)
- return false;
- }
-
- // Compare action
- ctx::Json laction, raction;
- lrule.get(NULL, CT_RULE_ACTION, &laction);
- rrule.get(NULL, CT_RULE_ACTION, &raction);
- if (laction != raction)
- return false;
-
- return true;
-}
-
-int64_t ctx::rule_manager::get_duplicated_rule_id(std::string pkg_id, ctx::Json& rule)
-{
- std::string q = "SELECT row_id, description, details FROM context_trigger_rule WHERE package_id = '";
- q += pkg_id;
- q += "'";
-
- std::vector<Json> d_record;
- bool ret = db_manager::execute_sync(q.c_str(), &d_record);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Query row_id, details by package id failed");
-
- ctx::Json r_details;
- rule.get(NULL, CT_RULE_DETAILS, &r_details);
- std::string r_desc;
- rule.get(NULL, CT_RULE_DESCRIPTION, &r_desc);
- std::vector<Json>::iterator vec_end = d_record.end();
-
- for (std::vector<Json>::iterator vec_pos = d_record.begin(); vec_pos != vec_end; ++vec_pos) {
- ctx::Json elem = *vec_pos;
- std::string details;
- ctx::Json d_details;
-
- elem.get(NULL, "details", &details);
- d_details = details;
-
- if (rule_equals(r_details, d_details)) {
- int64_t row_id;
- elem.get(NULL, "row_id", &row_id);
-
- // Description comparison
- std::string d_desc;
- elem.get(NULL, "description", &d_desc);
- if (r_desc.compare(d_desc)) {
- // Only description is changed
- std::string q_update = "UPDATE context_trigger_rule SET description='" + r_desc + "' WHERE row_id = " + int_to_string(row_id);
-
- std::vector<Json> record;
- ret = db_manager::execute_sync(q_update.c_str(), &record);
- if (ret) {
- _D("Rule%lld description is updated", row_id);
- } else {
- _W("Failed to update description of rule%lld", row_id);
- }
- }
-
- return row_id;
- }
- }
-
- return -1;
-}
-
-int ctx::rule_manager::verify_rule(ctx::Json& rule, const char* creator)
-{
- ctx::Json details;
- rule.get(NULL, CT_RULE_DETAILS, &details);
-
- std::string e_name;
- rule.get(CT_RULE_DETAILS "." CT_RULE_EVENT, CT_RULE_EVENT_ITEM, &e_name);
-
- ctx::context_monitor* ctx_monitor = ctx::context_monitor::get_instance();
- IF_FAIL_RETURN_TAG(ctx_monitor, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
-
- IF_FAIL_RETURN_TAG(ctx_monitor->is_supported(e_name), ERR_NOT_SUPPORTED, _I, "Event(%s) is not supported", e_name.c_str());
-
- if (creator) {
- if (!ctx_monitor->is_allowed(creator, e_name.c_str())) {
- _W("Permission denied for '%s'", e_name.c_str());
- return ERR_PERMISSION_DENIED;
- }
- }
-
- ctx::Json it;
- for (int i = 0; rule.getAt(CT_RULE_DETAILS, CT_RULE_CONDITION, i, &it); i++){
- std::string c_name;
- it.get(NULL, CT_RULE_CONDITION_ITEM, &c_name);
-
- IF_FAIL_RETURN_TAG(ctx_monitor->is_supported(c_name), ERR_NOT_SUPPORTED, _I, "Condition(%s) is not supported", c_name.c_str());
-
- if (!ctx_monitor->is_allowed(creator, c_name.c_str())) {
- _W("Permission denied for '%s'", c_name.c_str());
- return ERR_PERMISSION_DENIED;
- }
- }
-
- return ERR_NONE;
-}
-
-int ctx::rule_manager::add_rule(std::string creator, const char* pkg_id, ctx::Json rule, ctx::Json* rule_id)
-{
- bool ret;
- int64_t rid;
-
- // Check if all items are supported && allowed to access
- int err = verify_rule(rule, creator.c_str());
- IF_FAIL_RETURN(err == ERR_NONE, err);
-
- // Check if duplicated rule exits
- if ((rid = get_duplicated_rule_id(pkg_id, rule)) > 0) {
- // Save rule id
- rule_id->set(NULL, CT_RULE_ID, rid);
- _D("Duplicated rule found");
- return ERR_NONE;
- }
-
- // Insert rule to rule table, get rule id
- ctx::Json r_record;
- std::string description;
- ctx::Json details;
- rule.get(NULL, CT_RULE_DESCRIPTION, &description);
- rule.get(NULL, CT_RULE_DETAILS, &details);
- r_record.set(NULL, "creator", creator);
- if (pkg_id) {
- r_record.set(NULL, "package_id", pkg_id);
- }
- r_record.set(NULL, "description", description);
-
- // Handle timer event
- ctx::trigger_timer::handle_timer_event(details);
-
- r_record.set(NULL, "details", details.str());
- ret = db_manager::insert_sync(RULE_TABLE, r_record, &rid);
- IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Insert rule to db failed");
-
- // Save rule id
- rule_id->set(NULL, CT_RULE_ID, rid);
-
- _D("Add rule%d succeeded", (int)rid);
- return ERR_NONE;
-}
-
-
-int ctx::rule_manager::remove_rule(int rule_id)
-{
- bool ret;
-
- // Delete rule from DB
- std::string query = "DELETE FROM 'context_trigger_rule' where row_id = ";
- query += int_to_string(rule_id);
-
- std::vector<Json> record;
- ret = db_manager::execute_sync(query.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Remove rule from db failed");
-
- _D("Remove rule%d succeeded", rule_id);
-
- return ERR_NONE;
-}
-
-int ctx::rule_manager::enable_rule(int rule_id)
-{
- int error;
- std::string query;
- std::vector<Json> rule_record;
- std::vector<Json> record;
- std::string pkg_id;
- ctx::Json jrule;
- std::string tmp;
- std::string id_str = int_to_string(rule_id);
-
- trigger_rule* rule;
-
- // Get rule Json by rule id;
- query = "SELECT details, package_id FROM context_trigger_rule WHERE row_id = ";
- query += id_str;
- error = (db_manager::execute_sync(query.c_str(), &rule_record))? ERR_NONE : ERR_OPERATION_FAILED;
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Query rule by rule id failed");
-
- rule_record[0].get(NULL, "details", &tmp);
- jrule = tmp;
- rule_record[0].get(NULL, "package_id", &pkg_id);
-
- // Create a rule instance
- rule = new(std::nothrow) trigger_rule(rule_id, jrule, pkg_id.c_str(), this);
- IF_FAIL_RETURN_TAG(rule, ERR_OUT_OF_MEMORY, _E, "Failed to create rule instance");
-
- // Start the rule
- error = rule->start();
- IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Failed to start rule%d", rule_id);
-
- // Update db to set 'enabled'
- query = "UPDATE context_trigger_rule SET status = 2 WHERE row_id = ";
- query += id_str;
- error = (db_manager::execute_sync(query.c_str(), &record))? ERR_NONE : ERR_OPERATION_FAILED;
- IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Update db failed");
-
- // Add rule instance to rule_map
- rule_map[rule_id] = rule;
-
- _D(YELLOW("Enable Rule%d succeeded"), rule_id);
- return ERR_NONE;
-
-CATCH:
- delete rule;
- rule = NULL;
-
- return error;
-}
-
-int ctx::rule_manager::disable_rule(int rule_id)
-{
- bool ret;
- int error;
-
- rule_map_t::iterator it = rule_map.find(rule_id);
- bool is_paused = (it == rule_map.end());
-
- // For 'enabled' rule, not 'paused'
- if (!is_paused) {
- // Stop the rule
- trigger_rule* rule = static_cast<trigger_rule*>(it->second);
- error = rule->stop();
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", rule_id);
-
- // Remove rule instance from rule_map
- delete rule;
- rule_map.erase(it);
- }
-
- // Update db to set 'disabled' // TODO skip while clear uninstalled rule
- std::string query = "UPDATE context_trigger_rule SET status = 0 WHERE row_id = ";
- query += int_to_string(rule_id);
- std::vector<Json> record;
- ret = db_manager::execute_sync(query.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed");
-
- _D(YELLOW("Disable Rule%d succeeded"), rule_id);
- return ERR_NONE;
-}
-
-int ctx::rule_manager::pause_rule(int rule_id)
-{
- bool ret;
- int error;
-
- rule_map_t::iterator it = rule_map.find(rule_id);
- IF_FAIL_RETURN_TAG(it != rule_map.end(), ERR_OPERATION_FAILED, _E, "Rule instance not found");
-
- // Stop the rule
- trigger_rule* rule = static_cast<trigger_rule*>(it->second);
- error = rule->stop();
- IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", rule_id);
-
- // Update db to set 'paused'
- std::string query = "UPDATE context_trigger_rule SET status = 1 WHERE row_id = ";
-
- query += int_to_string(rule_id);
- std::vector<Json> record;
- ret = db_manager::execute_sync(query.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed");
-
- // Remove rule instance from rule_map
- delete rule;
- rule_map.erase(it);
-
- _D(YELLOW("Pause Rule%d"), rule_id);
- return ERR_NONE;
-}
-
-int ctx::rule_manager::check_rule(std::string pkg_id, int rule_id)
-{
- // Get package id
- std::string q = "SELECT package_id FROM context_trigger_rule WHERE row_id =";
- q += int_to_string(rule_id);
-
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Query package id by rule id failed");
-
- if (record.size() == 0) {
- return ERR_NO_DATA;
- }
-
- std::string p;
- record[0].get(NULL, "package_id", &p);
-
- if (p.compare(pkg_id) == 0){
- return ERR_NONE;
- }
-
- return ERR_NO_DATA;
-}
-
-bool ctx::rule_manager::is_rule_enabled(int rule_id)
-{
- std::string q = "SELECT status FROM context_trigger_rule WHERE row_id =";
- q += int_to_string(rule_id);
-
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Query enabled by rule id failed");
-
- int status;
- record[0].get(NULL, "status", &status);
-
- return (status != 0);
-}
-
-int ctx::rule_manager::get_rule_by_id(std::string pkg_id, int rule_id, ctx::Json* request_result)
-{
- std::string q = "SELECT description FROM context_trigger_rule WHERE (package_id = '";
- q += pkg_id;
- q += "') and (row_id = ";
- q += int_to_string(rule_id);
- q += ")";
-
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Query rule by rule id failed");
-
- if (record.size() == 0) {
- return ERR_NO_DATA;
- } else if (record.size() != 1) {
- return ERR_OPERATION_FAILED;
- }
-
- std::string description;
- record[0].get(NULL, "description", &description);
-
- (*request_result).set(NULL, CT_RULE_ID, rule_id);
- (*request_result).set(NULL, CT_RULE_DESCRIPTION, description);
-
- return ERR_NONE;
-}
-
-int ctx::rule_manager::get_rule_ids(std::string pkg_id, ctx::Json* request_result)
-{
- (*request_result) = "{ \"" CT_RULE_ARRAY_ENABLED "\" : [ ] , \"" CT_RULE_ARRAY_DISABLED "\" : [ ] }";
-
- std::string q = "SELECT row_id, status FROM context_trigger_rule WHERE (package_id = '";
- q += pkg_id;
- q += "')";
-
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query rules failed");
-
- std::vector<Json>::iterator vec_end = record.end();
- for (std::vector<Json>::iterator vec_pos = record.begin(); vec_pos != vec_end; ++vec_pos) {
- ctx::Json elem = *vec_pos;
- std::string id;
- int status;
-
- elem.get(NULL, "row_id", &id);
- elem.get(NULL, "status", &status);
-
- if (status >= 1) {
- (*request_result).append(NULL, CT_RULE_ARRAY_ENABLED, string_to_int(id));
- } else if (status == 0) {
- (*request_result).append(NULL, CT_RULE_ARRAY_DISABLED, string_to_int(id));
- }
- }
-
- return ERR_NONE;
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __RULE_MANAGER_H__
-#define __RULE_MANAGER_H__
-
-#include <set>
-#include <map>
-
-namespace ctx {
-
- class Json;
- class context_trigger;
- class trigger_rule;
-
- class rule_manager {
- public:
- rule_manager();
- ~rule_manager();
-
- bool init();
- int add_rule(std::string creator, const char* pkg_id, ctx::Json rule, ctx::Json* rule_id);
- int remove_rule(int rule_id);
- int enable_rule(int rule_id);
- int disable_rule(int rule_id);
- int get_rule_by_id(std::string pkg_id, int rule_id, ctx::Json* request_result);
- int get_rule_ids(std::string pkg_id, ctx::Json* request_result);
- int check_rule(std::string pkg_id, int rule_id);
- bool is_rule_enabled(int rule_id);
- int pause_rule_with_item(std::string& subject);
- int pause_rule(int rule_id);
- int resume_rule_with_item(std::string& subject);
- void handle_rule_of_uninstalled_package(std::string pkg_id);
-
- static bool is_uninstalled_package(std::string pkg_id);
-
- private:
- bool reenable_rule(void);
- int verify_rule(ctx::Json& rule, const char* creator);
- int64_t get_duplicated_rule_id(std::string pkg_id, ctx::Json& rule);
- bool rule_data_arr_elem_equals(ctx::Json& lelem, ctx::Json& relem);
- bool rule_item_equals(ctx::Json& litem, ctx::Json& ritem);
- bool rule_equals(ctx::Json& lrule, ctx::Json& rrule);
- int get_uninstalled_app(void);
- int clear_rule_of_uninstalled_package(bool is_init = false);
-
- std::set<std::string> uninstalled_packages;
-
- typedef std::map<int, trigger_rule*> rule_map_t;
- rule_map_t rule_map;
- }; /* class rule_manager */
-
-} /* namespace ctx */
-
-#endif /* End of __RULE_MANAGER_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <sstream>
-#include <types_internal.h>
-#include <context_trigger_types_internal.h>
-#include <db_mgr.h>
-#include "../context_mgr_impl.h"
-#include "rule_manager.h"
-#include "template_manager.h"
-
-ctx::template_manager *ctx::template_manager::_instance = NULL;
-ctx::context_manager_impl *ctx::template_manager::_context_mgr = NULL;
-ctx::rule_manager *ctx::template_manager::_rule_mgr = NULL;
-
-static std::string int_to_string(int i)
-{
- std::ostringstream convert;
- convert << i;
- std::string str = convert.str();
- return str;
-}
-
-ctx::template_manager::template_manager()
-{
-}
-
-ctx::template_manager::~template_manager()
-{
-}
-
-void ctx::template_manager::set_manager(ctx::context_manager_impl* ctx_mgr, ctx::rule_manager* rule_mgr)
-{
- _context_mgr = ctx_mgr;
- _rule_mgr = rule_mgr;
-}
-
-ctx::template_manager* ctx::template_manager::get_instance()
-{
- IF_FAIL_RETURN_TAG(_context_mgr, NULL, _E, "Context manager is needed");
- IF_FAIL_RETURN_TAG(_rule_mgr, NULL, _E, "Rule manager is needed");
-
- IF_FAIL_RETURN(!_instance, _instance);
-
- _instance = new(std::nothrow) template_manager();
- IF_FAIL_RETURN_TAG(_instance, NULL, _E, "Memory alllocation failed");
-
- return _instance;
-}
-
-void ctx::template_manager::destroy()
-{
- _instance->apply_templates();
-
- if (_instance) {
- delete _instance;
- _instance = NULL;
- }
-}
-
-bool ctx::template_manager::init()
-{
- std::string q = std::string("CREATE TABLE IF NOT EXISTS context_trigger_template ")
- + "(name TEXT DEFAULT '' NOT NULL PRIMARY KEY, operation INTEGER DEFAULT 3 NOT NULL, "
- + "attributes TEXT DEFAULT '' NOT NULL, options TEXT DEFAULT '' NOT NULL, owner TEXT DEFAULT '' NOT NULL)";
-
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed");
-
- // Apply templates
- apply_templates();
-
- return true;
-}
-
-void ctx::template_manager::apply_templates()
-{
- std::string subject;
- int operation;
- ctx::Json attributes;
- ctx::Json options;
- std::string owner;
- bool unregister;
- std::string query;
- query.clear();
-
- while(_context_mgr->pop_trigger_item(subject, operation, attributes, options, owner, unregister)) {
- if (unregister) {
- unregister_template(subject);
- } else {
- register_template(subject, operation, attributes, options, owner);
- }
- }
-}
-
-void ctx::template_manager::register_template(std::string subject, int operation, ctx::Json attributes, ctx::Json options, std::string owner)
-{
- _D("[Add template] Subject: %s, Ops: %d, Owner: %s", subject.c_str(), operation, owner.c_str());
- _J("Attr", attributes);
- _J("Opt", options);
-
- std::string query = "UPDATE context_trigger_template SET operation=" + int_to_string(operation)
- + ", attributes='" + attributes.str() + "', options='" + options.str() + "', owner='" + owner
- + "' WHERE name='" + subject + "'; ";
-
- query += "INSERT OR IGNORE INTO context_trigger_template (name, operation, attributes, options, owner) VALUES ('"
- + subject + "', " + int_to_string(operation) + ", '" + attributes.str() + "', '" + options.str() + "', '"
- + owner + "'); ";
-
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(query.c_str(), &record);
- IF_FAIL_VOID_TAG(ret, _E, "Update template db failed");
-
- if (!owner.empty()) {
- _rule_mgr->resume_rule_with_item(subject);
- }
-}
-
-void ctx::template_manager::unregister_template(std::string subject)
-{
- _D("[Remove template] Subject: %s", subject.c_str());
- std::string query = "DELETE FROM context_trigger_template WHERE name = '" + subject + "'; ";
-
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(query.c_str(), &record);
- IF_FAIL_VOID_TAG(ret, _E, "Update template db failed");
-
- _rule_mgr->pause_rule_with_item(subject);
-}
-
-
-std::string ctx::template_manager::add_template(std::string &subject, int &operation, ctx::Json &attributes, ctx::Json &options, std::string &owner)
-{
- _D("[Add template] Subject: %s, Ops: %d, Owner: %s", subject.c_str(), operation, owner.c_str());
- _J("Attr", attributes);
- _J("Opt", options);
-
- std::string query = "UPDATE context_trigger_template SET operation=" + int_to_string(operation)
- + ", attributes='" + attributes.str() + "', options='" + options.str() + "', owner='" + owner
- + "' WHERE name='" + subject + "'; ";
-
- query += "INSERT OR IGNORE INTO context_trigger_template (name, operation, attributes, options, owner) VALUES ('"
- + subject + "', " + int_to_string(operation) + ", '" + attributes.str() + "', '" + options.str() + "', '"
- + owner + "'); ";
-
- return query;
-}
-
-std::string ctx::template_manager::remove_template(std::string &subject)
-{
- _D("[Remove template] Subject: %s", subject.c_str());
- std::string query = "DELETE FROM context_trigger_template WHERE name = '" + subject + "'; ";
-
- return query;
-}
-
-int ctx::template_manager::get_template(std::string &subject, ctx::Json* tmpl)
-{
- // Update latest template information
- std::string q = "SELECT * FROM context_trigger_template WHERE name = '" + subject + "'";
-
- std::vector<Json> record;
- bool ret = db_manager::execute_sync(q.c_str(), &record);
- IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query template failed");
- IF_FAIL_RETURN_TAG(record.size() > 0, ERR_NOT_SUPPORTED, _E, "Template(%s) not found", subject.c_str());
- IF_FAIL_RETURN_TAG(record.size() == 1, ERR_OPERATION_FAILED, _E, "Tepmlate duplicated");
-
- (*tmpl) = *record.begin();
-
- std::string opt_str;
- std::string attr_str;
- tmpl->get(NULL, TYPE_OPTION_STR, &opt_str);
- tmpl->get(NULL, TYPE_ATTR_STR, &attr_str);
-
- ctx::Json opt = opt_str;
- ctx::Json attr = attr_str;
-
- tmpl->set(NULL, TYPE_OPTION_STR, opt);
- tmpl->set(NULL, TYPE_ATTR_STR, attr);
-
- return ERR_NONE;
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __TEMPLATE_MANAGER_H__
-#define __TEMPLATE_MANAGER_H__
-
-#include <Json.h>
-
-namespace ctx {
-
- class context_manager_impl;
- class rule_manager;
- class template_manager {
- public:
- static template_manager* get_instance();
- static void set_manager(ctx::context_manager_impl* ctx_mgr, ctx::rule_manager* rule_mgr);
- static void destroy();
-
- bool init();
- void apply_templates();
- int get_template(std::string &subject, ctx::Json* tmpl);
- void register_template(std::string subject, int operation, ctx::Json attributes, ctx::Json options, std::string owner);
- void unregister_template(std::string subject);
-
- private:
- template_manager();
- template_manager(const template_manager& other);
- ~template_manager();
-
- static template_manager *_instance;
- static context_manager_impl *_context_mgr;
- static rule_manager *_rule_mgr;
-
- std::string add_template(std::string &subject, int &operation, ctx::Json &attributes, ctx::Json &options, std::string &owner);
- std::string remove_template(std::string &subject);
-
- }; /* class template_manager */
-
-} /* namespace ctx */
-
-#endif /* End of __TEMPLATE_MANAGER_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <context_trigger.h>
-#include <context_trigger_types_internal.h>
-#include <types_internal.h>
-#include <TimerManager.h>
-#include "timer.h"
-
-#define TIMER_DAY_OF_WEEK "DayOfWeek"
-#define TIMER_TIME_OF_DAY "TimeOfDay"
-
-static int arrange_day_of_week(ctx::Json day_info)
-{
- int result = 0;
-
- std::string key_op;
- if (!day_info.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &key_op)) {
- result = ctx::TimerManager::dowToInt(DOW_EVERYDAY);
- return result;
- }
-
- if (key_op.compare("and") == 0) {
- result = ctx::TimerManager::dowToInt(DOW_EVERYDAY);
- }
-
- std::string tmp_d;
- for (int i = 0; day_info.getAt(NULL, CT_RULE_DATA_VALUE_ARR, i, &tmp_d); i++) {
- int dow = ctx::TimerManager::dowToInt(tmp_d);
- std::string op;
- day_info.getAt(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, i, &op);
-
- if (op.compare(CONTEXT_TRIGGER_NOT_EQUAL_TO) == 0) {
- dow = ctx::TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
- }
-
- if (key_op.compare("and") == 0) {
- result &= dow;
- } else {
- result |= dow;
- }
- }
- _D("Requested day of week (%#x)", result);
-
- return result;
-}
-
-void ctx::trigger_timer::handle_timer_event(ctx::Json& rule)
-{
- ctx::Json event;
- rule.get(NULL, CT_RULE_EVENT, &event);
-
- std::string e_name;
- event.get(NULL, CT_RULE_EVENT_ITEM, &e_name);
- if (e_name.compare(CT_EVENT_TIME) != 0 ) {
- return;
- }
-
- ctx::Json day_info;
- ctx::Json it;
- int dow;
- for (int i = 0; event.getAt(NULL, CT_RULE_DATA_ARR, i, &it); i++) {
- std::string key;
- it.get(NULL, CT_RULE_DATA_KEY, &key);
-
- if (key.compare(TIMER_DAY_OF_WEEK) == 0) {
- dow = arrange_day_of_week(it);
-
- day_info.set(NULL, CT_RULE_DATA_KEY, TIMER_DAY_OF_WEEK);
- day_info.set(NULL, CT_RULE_DATA_KEY_OPERATOR, "or");
-
- for (int j = 0; j < DAYS_PER_WEEK; j++) {
- int d = 0x01 << j;
- if (dow & d) {
- std::string day = ctx::TimerManager::dowToStr(d);
- day_info.append(NULL, CT_RULE_DATA_VALUE_ARR, day);
- day_info.append(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, CONTEXT_TRIGGER_EQUAL_TO);
-
- // Set option
- event.append(CT_RULE_EVENT_OPTION, TIMER_DAY_OF_WEEK, day);
- }
- }
- event.setAt(NULL, CT_RULE_DATA_ARR, i, day_info);
- } else if (key.compare(TIMER_TIME_OF_DAY) == 0) {
- int time;
- for (int j = 0; it.getAt(NULL, CT_RULE_DATA_VALUE_ARR, j, &time); j++) {
- event.append(CT_RULE_EVENT_OPTION, TIMER_TIME_OF_DAY, time);
- }
- }
- }
-
- rule.set(NULL, CT_RULE_EVENT, event);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_CONTEXT_TRIGGER_TIMER_H__
-#define __CONTEXT_CONTEXT_TRIGGER_TIMER_H__
-
-#include <Json.h>
-
-namespace ctx {
-
- namespace trigger_timer {
-
- void handle_timer_event(ctx::Json& rule);
-
- };
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_CONTEXT_TRIGGER_TIMER_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <types_internal.h>
-#include <context_trigger_types_internal.h>
-#include "trigger.h"
-#include "context_monitor.h"
-#include "template_manager.h"
-#include "rule_manager.h"
-
-ctx::context_trigger::context_trigger()
- : rule_mgr(NULL)
-{
-}
-
-ctx::context_trigger::~context_trigger()
-{
-}
-
-bool ctx::context_trigger::init(ctx::context_manager_impl* ctx_mgr)
-{
- // Do the necessary initialization process.
- // This function is called from the main thread during the service launching process.
- _D("Context Trigger Init");
- process_initialize(ctx_mgr);
-
- return true;
-}
-
-void ctx::context_trigger::release()
-{
- // Release the occupied resources.
- // This function is called from the main thread during the service termination process.
-
- _D("Template Manager Destroy");
- ctx::template_manager::destroy();
-
- _D("Rule Manager Release");
- delete rule_mgr;
- rule_mgr = NULL;
-
- _D("Context Monitor Destroy");
- ctx::context_monitor::destroy();
-}
-
-bool ctx::context_trigger::assign_request(ctx::request_info* request)
-{
- std::string subject = request->get_subject();
- if (subject != CONTEXT_TRIGGER_SUBJECT_ADD && subject != CONTEXT_TRIGGER_SUBJECT_REMOVE &&
- subject != CONTEXT_TRIGGER_SUBJECT_ENABLE && subject != CONTEXT_TRIGGER_SUBJECT_DISABLE &&
- subject != CONTEXT_TRIGGER_SUBJECT_GET && subject != CONTEXT_TRIGGER_SUBJECT_GET_RULE_IDS &&
- subject != CONTEXT_TRIGGER_SUBJECT_GET_TEMPLATE) {
- return false;
- }
-
- process_request(request);
- return true;
-}
-
-void ctx::context_trigger::process_request(ctx::request_info* request)
-{
- // Process the request, and reply to the client if necessary.
- const char* req_sbj = request->get_subject();
- _D("Request is %s", req_sbj);
- std::string subject(req_sbj);
-
- if (subject == CONTEXT_TRIGGER_SUBJECT_ADD) {
- add_rule(request);
- } else if (subject == CONTEXT_TRIGGER_SUBJECT_REMOVE) {
- remove_rule(request);
- } else if (subject == CONTEXT_TRIGGER_SUBJECT_ENABLE) {
- enable_rule(request);
- } else if (subject == CONTEXT_TRIGGER_SUBJECT_DISABLE) {
- disable_rule(request);
- } else if (subject == CONTEXT_TRIGGER_SUBJECT_GET) {
- get_rule_by_id(request);
- } else if (subject == CONTEXT_TRIGGER_SUBJECT_GET_RULE_IDS) {
- get_rule_ids(request);
- } else if (subject == CONTEXT_TRIGGER_SUBJECT_GET_TEMPLATE) {
- get_template(request);
- } else {
- _E("Invalid request");
- }
-}
-
-void ctx::context_trigger::process_initialize(ctx::context_manager_impl* mgr)
-{
- // Context Monitor
- ctx::context_monitor::set_context_manager(mgr);
-
- // Rule Manager
- rule_mgr = new(std::nothrow) rule_manager();
- IF_FAIL_VOID_TAG(rule_mgr, _E, "Memory allocation failed");
-
- // Template Manager
- ctx::template_manager::set_manager(mgr, rule_mgr);
- ctx::template_manager* tmpl_mgr = ctx::template_manager::get_instance();
- IF_FAIL_VOID_TAG(tmpl_mgr, _E, "Memory allocation failed");
-
- // Initialization
- if (!tmpl_mgr->init()) {
- _E("Template manager initialization failed");
- raise(SIGTERM);
- }
-
- if (!rule_mgr->init()) {
- _E("Context trigger initialization failed");
- raise(SIGTERM);
- }
-}
-
-void ctx::context_trigger::add_rule(ctx::request_info* request)
-{
- ctx::Json rule_id;
-
- const char* client = request->get_client();
- if (client == NULL) {
- request->reply(ERR_OPERATION_FAILED);
- return;
- }
-
- const char* pkg_id = request->get_package_id();
-
- int error = rule_mgr->add_rule(client, pkg_id, request->get_description(), &rule_id);
- _I("'%s' adds a rule (Error: %#x)", request->get_client(), error);
-
- request->reply(error, rule_id);
-}
-
-void ctx::context_trigger::remove_rule(ctx::request_info* request)
-{
- int id;
- int error;
-
- const char* pkg_id = request->get_package_id();
-
- ctx::Json rule_id = request->get_description();
- rule_id.get(NULL, CT_RULE_ID, &id);
-
- error = rule_mgr->check_rule((pkg_id)? pkg_id : "", id);
- if (error != ERR_NONE) {
- request->reply(error);
- return;
- }
-
- bool ret = rule_mgr->is_rule_enabled(id);
- if (ret) {
- request->reply(ERR_RULE_ENABLED);
- return;
- }
-
- error = rule_mgr->remove_rule(id);
- _I("'%s' removes rule%d (Error: %#x)", request->get_client(), id, error);
- request->reply(error);
-}
-
-void ctx::context_trigger::enable_rule(ctx::request_info* request)
-{
- int id;
- int error;
-
- const char* pkg_id = request->get_package_id();
-
- ctx::Json rule_id = request->get_description();
- rule_id.get(NULL, CT_RULE_ID, &id);
-
- error = rule_mgr->check_rule((pkg_id)? pkg_id : "", id);
- if (error != ERR_NONE) {
- request->reply(error);
- return;
- }
-
- bool ret = rule_mgr->is_rule_enabled(id);
- if (ret) {
- request->reply(ERR_RULE_ENABLED);
- return;
- }
-
- error = rule_mgr->enable_rule(id);
- _I("'%s' enables rule%d (Error: %#x)", request->get_client(), id, error);
- request->reply(error);
-}
-
-void ctx::context_trigger::disable_rule(ctx::request_info* request)
-{
- int id;
- int error;
-
- const char* pkg_id = request->get_package_id();
-
- ctx::Json rule_id = request->get_description();
- rule_id.get(NULL, CT_RULE_ID, &id);
-
- error = rule_mgr->check_rule((pkg_id)? pkg_id : "", id);
- if (error != ERR_NONE) {
- request->reply(error);
- return;
- }
-
- bool ret = rule_mgr->is_rule_enabled(id);
- if (!ret) {
- request->reply(ERR_RULE_NOT_ENABLED);
- return;
- }
-
- error = rule_mgr->disable_rule(id);
- _I("'%s' disables rule%d (Error: %#x)", request->get_client(), id, error);
- request->reply(error);
-}
-
-void ctx::context_trigger::get_rule_by_id(ctx::request_info* request)
-{
- int error;
-
- ctx::Json option = request->get_description();
- int id;
- option.get(NULL, CT_RULE_ID, &id);
-
- const char* pkg_id = request->get_package_id();
-
- ctx::Json read_data;
- error = rule_mgr->get_rule_by_id((pkg_id)? pkg_id : "", id, &read_data);
-
- ctx::Json dummy;
- request->reply(error, dummy, read_data);
-}
-
-void ctx::context_trigger::get_rule_ids(ctx::request_info* request)
-{
- int error;
-
- const char* pkg_id = request->get_package_id();
-
- ctx::Json read_data;
- error = rule_mgr->get_rule_ids((pkg_id)? pkg_id : "", &read_data);
-
- ctx::Json dummy;
- request->reply(error, dummy, read_data);
-}
-
-void ctx::context_trigger::get_template(ctx::request_info* request)
-{
- int error;
-
- ctx::Json option = request->get_description();
- std::string name;
- option.get(NULL, SUBJECT_STR, &name);
-
- ctx::template_manager* tmpl_mgr = ctx::template_manager::get_instance();
- if (!tmpl_mgr) {
- _E("Memory allocation failed");
- request->reply(ERR_OUT_OF_MEMORY);
- return;
- }
-
- ctx::Json tmpl;
- error = tmpl_mgr->get_template(name, &tmpl);
-
- ctx::Json dummy;
- request->reply(error, dummy, tmpl);
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_CONTEXT_TRIGGER_H__
-#define __CONTEXT_CONTEXT_TRIGGER_H__
-
-#include "../request.h"
-
-namespace ctx {
-
- class rule_manager;
- class client_request;
- class context_manager_impl;
- class context_trigger {
- public:
- context_trigger();
- ~context_trigger();
-
- bool init(ctx::context_manager_impl* ctx_mgr);
- void release();
-
- bool assign_request(ctx::request_info* request);
-
- private:
- void process_request(ctx::request_info* request);
- void process_initialize(ctx::context_manager_impl* mgr);
-
- void add_rule(ctx::request_info* request);
- void remove_rule(ctx::request_info* request);
- void enable_rule(ctx::request_info* request);
- void disable_rule(ctx::request_info* request);
- void get_rule_by_id(ctx::request_info* request);
- void get_rule_ids(ctx::request_info* request);
- void get_template(ctx::request_info* request);
-
- ctx::rule_manager* rule_mgr;
- };
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_CONTEXT_TRIGGER_H__ */
#include <Json.h>
#include "access_control/privilege.h"
#include "server.h"
-#include "request.h"
+#include "Request.h"
#include "provider.h"
ctx::context_provider_handler::context_provider_handler(const char *subj, ctx::context_provider_info &prvd) :
return privilege_manager::is_allowed(creds, provider_info.privilege);
}
-ctx::context_provider_iface* ctx::context_provider_handler::get_provider(ctx::request_info *request)
+ctx::context_provider_iface* ctx::context_provider_handler::get_provider(ctx::RequestInfo *request)
{
context_provider_iface *provider = provider_info.create(provider_info.data);
if (!provider) {
return provider;
}
-void ctx::context_provider_handler::subscribe(ctx::request_info *request)
+void ctx::context_provider_handler::subscribe(ctx::RequestInfo *request)
{
- _I(CYAN("'%s' subscribes '%s' (RID-%d)"), request->get_client(), subject, request->get_id());
+ _I(CYAN("'%s' subscribes '%s' (RID-%d)"), request->getClient(), subject, request->getId());
context_provider_iface *provider = get_provider(request);
IF_FAIL_VOID(provider);
ctx::Json request_result;
- int error = provider->subscribe(subject, request->get_description().str(), &request_result);
+ int error = provider->subscribe(subject, request->getDescription().str(), &request_result);
if (!request->reply(error, request_result) || error != ERR_NONE) {
delete request;
subscribe_requests.push_back(request);
}
-void ctx::context_provider_handler::unsubscribe(ctx::request_info *request)
+void ctx::context_provider_handler::unsubscribe(ctx::RequestInfo *request)
{
- _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->get_client(), subject, request->get_id());
+ _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->getClient(), subject, request->getId());
// Search the subscribe request to be removed
- auto target = find_request(subscribe_requests, request->get_client(), request->get_id());
+ auto target = find_request(subscribe_requests, request->getClient(), request->getId());
if (target == subscribe_requests.end()) {
_W("Unknown request");
delete request;
}
// Keep the pointer to the request found
- request_info *req_found = *target;
+ RequestInfo *req_found = *target;
// Remove the request from the list
subscribe_requests.erase(target);
// Check if there exist the same requests
- if (find_request(subscribe_requests, req_found->get_description()) != subscribe_requests.end()) {
+ if (find_request(subscribe_requests, req_found->getDescription()) != subscribe_requests.end()) {
// Do not stop detecting the subject
- _D("A same request from '%s' exists", req_found->get_client());
+ _D("A same request from '%s' exists", req_found->getClient());
request->reply(ERR_NONE);
delete request;
delete req_found;
IF_FAIL_VOID(provider);
// Stop detecting the subject
- int error = provider->unsubscribe(subject, req_found->get_description());
+ int error = provider->unsubscribe(subject, req_found->getDescription());
request->reply(error);
delete request;
delete req_found;
}
-void ctx::context_provider_handler::read(ctx::request_info *request)
+void ctx::context_provider_handler::read(ctx::RequestInfo *request)
{
- _I(CYAN("'%s' reads '%s' (RID-%d)"), request->get_client(), subject, request->get_id());
+ _I(CYAN("'%s' reads '%s' (RID-%d)"), request->getClient(), subject, request->getId());
context_provider_iface *provider = get_provider(request);
IF_FAIL_VOID(provider);
ctx::Json request_result;
- int error = provider->read(subject, request->get_description().str(), &request_result);
+ int error = provider->read(subject, request->getDescription().str(), &request_result);
if (!request->reply(error, request_result) || error != ERR_NONE) {
delete request;
read_requests.push_back(request);
}
-void ctx::context_provider_handler::write(ctx::request_info *request)
+void ctx::context_provider_handler::write(ctx::RequestInfo *request)
{
- _I(CYAN("'%s' writes '%s' (RID-%d)"), request->get_client(), subject, request->get_id());
+ _I(CYAN("'%s' writes '%s' (RID-%d)"), request->getClient(), subject, request->getId());
context_provider_iface *provider = get_provider(request);
IF_FAIL_VOID(provider);
ctx::Json request_result;
- int error = provider->write(subject, request->get_description(), &request_result);
+ int error = provider->write(subject, request->getDescription(), &request_result);
request->reply(error, request_result);
delete request;
ctx::context_provider_handler::find_request(request_list_t &r_list, std::string client, int req_id)
{
for (auto it = r_list.begin(); it != r_list.end(); ++it) {
- if (client == (*it)->get_client() && req_id == (*it)->get_id()) {
+ if (client == (*it)->getClient() && req_id == (*it)->getId()) {
return it;
}
}
ctx::context_provider_handler::find_request(request_list_t::iterator begin, request_list_t::iterator end, Json &option)
{
for (auto it = begin; it != end; ++it) {
- if (option == (*it)->get_description()) {
+ if (option == (*it)->getDescription()) {
return it;
}
}
class Json;
class credentials;
- class request_info;
+ class RequestInfo;
class context_provider_handler {
public:
- typedef std::list<request_info*> request_list_t;
+ typedef std::list<RequestInfo*> request_list_t;
context_provider_handler(const char *subj, context_provider_info &prvd);
~context_provider_handler();
bool is_allowed(const credentials *creds);
- void subscribe(request_info *request);
- void unsubscribe(request_info *request);
- void read(request_info *request);
- void write(request_info *request);
+ void subscribe(RequestInfo *request);
+ void unsubscribe(RequestInfo *request);
+ void read(RequestInfo *request);
+ void write(RequestInfo *request);
bool publish(ctx::Json &option, int error, ctx::Json &data_updated);
bool reply_to_read(ctx::Json &option, int error, ctx::Json &data_read);
request_list_t subscribe_requests;
request_list_t read_requests;
- context_provider_iface* get_provider(request_info *request);
+ context_provider_iface* get_provider(RequestInfo *request);
request_list_t::iterator find_request(request_list_t &r_list, Json &option);
request_list_t::iterator find_request(request_list_t &r_list, std::string client, int req_id);
request_list_t::iterator find_request(request_list_t::iterator begin, request_list_t::iterator end, Json &option);
+++ /dev/null
-/*
- * Copyright (c) 2015 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 <glib.h>
-#include <types_internal.h>
-#include "request.h"
-
-ctx::request_info::request_info(int type, int req_id, const char* subj, const char* desc)
- : _type(type)
- , _req_id(req_id)
- , _subject(subj)
- , _description(desc)
-{
-}
-
-ctx::request_info::~request_info()
-{
-}
-
-int ctx::request_info::get_type()
-{
- return _type;
-}
-
-int ctx::request_info::get_id()
-{
- return _req_id;
-}
-
-const ctx::credentials* ctx::request_info::get_credentials()
-{
- return NULL;
-}
-
-const char* ctx::request_info::get_package_id()
-{
- return NULL;
-}
-
-const char* ctx::request_info::get_client()
-{
- return NULL;
-}
-
-const char* ctx::request_info::get_subject()
-{
- return _subject.c_str();
-}
-
-ctx::Json& ctx::request_info::get_description()
-{
- return _description;
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 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 __CONTEXT_REQUEST_INFO_H__
-#define __CONTEXT_REQUEST_INFO_H__
-
-#include <string>
-#include <Json.h>
-
-namespace ctx {
-
- /* Forward declaration */
- class credentials;
-
- class request_info {
- public:
- request_info(int type, int req_id, const char *subj, const char *desc);
- virtual ~request_info();
-
- int get_type();
- int get_id();
- const char* get_subject();
- ctx::Json& get_description();
-
- virtual const credentials* get_credentials();
- virtual const char* get_package_id();
- /* TODO: remove this get_client() */
- virtual const char* get_client();
- 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;
- virtual bool publish(int error, ctx::Json &data) = 0;
-
- protected:
- int _type;
- int _req_id;
- std::string _subject;
- ctx::Json _description;
- };
-
-} /* namespace ctx */
-
-#endif /* End of __CONTEXT_REQUEST_INFO_H__ */
#include "DBusServer.h"
#include "db_mgr_impl.h"
#include "context_mgr_impl.h"
-#include "context_trigger/trigger.h"
+#include "trigger/Trigger.h"
#include "server.h"
static GMainLoop *mainloop = NULL;
static ctx::context_manager_impl *context_mgr = NULL;
static ctx::db_manager_impl *database_mgr = NULL;
static ctx::DBusServer *dbus_handle = NULL;
-static ctx::context_trigger *trigger = NULL;
+static ctx::trigger::Trigger *context_trigger = NULL;
/* TODO: re-organize activation & deactivation processes */
void ctx::server::initialize()
IF_FAIL_CATCH_TAG(result, _E, "Initialization Failed");
_I("Init Context Trigger");
- trigger = new(std::nothrow) ctx::context_trigger();
- IF_FAIL_CATCH_TAG(trigger, _E, "Memory allocation failed");
- result = trigger->init(context_mgr);
+ context_trigger = new(std::nothrow) ctx::trigger::Trigger();
+ IF_FAIL_CATCH_TAG(context_trigger, _E, "Memory allocation failed");
+ result = context_trigger->init(context_mgr);
IF_FAIL_CATCH_TAG(result, _E, "Initialization Failed");
started = true;
{
_I(CYAN("Terminating Context-Service"));
_I("Release Context Trigger");
- if (trigger)
- trigger->release();
+ if (context_trigger)
+ context_trigger->release();
_I("Release Analyzer Manager");
if (context_mgr)
g_main_loop_unref(mainloop);
- delete trigger;
+ delete context_trigger;
delete context_mgr;
delete dbus_handle;
delete database_mgr;
static gboolean postpone_request_assignment(gpointer data)
{
- ctx::server::send_request(static_cast<ctx::request_info*>(data));
+ ctx::server::send_request(static_cast<ctx::RequestInfo*>(data));
return FALSE;
}
-void ctx::server::send_request(ctx::request_info* request)
+void ctx::server::send_request(ctx::RequestInfo* request)
{
if (!started) {
_W("Service not ready...");
return;
}
- if (!trigger->assign_request(request)) {
+ if (!context_trigger->assignRequest(request)) {
context_mgr->assign_request(request);
}
}
namespace ctx {
- class request_info;
+ class RequestInfo;
class server {
public:
static void initialize();
static void activate();
static void release();
- static void send_request(request_info* request);
+ static void send_request(RequestInfo* request);
};
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <app_control.h>
+#include <app_control_internal.h>
+#include <bundle.h>
+#include <device/display.h>
+#include <notification.h>
+#include <notification_internal.h>
+#include <runtime_info.h>
+#include <system_settings.h>
+#include <context_trigger_types_internal.h>
+#include <Json.h>
+#include "../DBusServer.h"
+#include "ActionManager.h"
+
+static void __triggerActionAppControl(ctx::Json& action);
+static void __triggerActionNotification(ctx::Json& action, std::string pkgId);
+static void __triggerActionDbusCall(ctx::Json& action);
+
+void ctx::trigger::action_manager::triggerAction(ctx::Json& action, std::string pkgId)
+{
+ std::string type;
+ action.get(NULL, CT_RULE_ACTION_TYPE, &type);
+
+ if (type.compare(CT_RULE_ACTION_TYPE_APP_CONTROL) == 0) {
+ __triggerActionAppControl(action);
+ } else if (type.compare(CT_RULE_ACTION_TYPE_NOTIFICATION) == 0) {
+ __triggerActionNotification(action, pkgId);
+ } else if (type.compare(CT_RULE_ACTION_TYPE_DBUS_CALL) == 0) {
+ __triggerActionDbusCall(action);
+ }
+}
+
+void __triggerActionAppControl(ctx::Json& action)
+{
+ int error;
+ std::string appctlStr;
+ action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctlStr);
+
+ char* str = static_cast<char*>(malloc(appctlStr.length()));
+ if (str == NULL) {
+ _E("Memory allocation failed");
+ return;
+ }
+ appctlStr.copy(str, appctlStr.length(), 0);
+ bundle_raw* encoded = reinterpret_cast<unsigned char*>(str);
+ bundle* appctlBundle = bundle_decode(encoded, appctlStr.length());
+
+ app_control_h app = NULL;
+ app_control_create(&app);
+ app_control_import_from_bundle(app, appctlBundle);
+
+ error = app_control_send_launch_request(app, NULL, NULL);
+ if (error != APP_CONTROL_ERROR_NONE) {
+ _E("Launch request failed(%d)", error);
+ } else {
+ _D("Launch request succeeded");
+ }
+ bundle_free(appctlBundle);
+ free(str);
+ app_control_destroy(app);
+
+ error = device_display_change_state(DISPLAY_STATE_NORMAL);
+ if (error != DEVICE_ERROR_NONE) {
+ _E("Change display state failed(%d)", error);
+ }
+}
+
+void __triggerActionNotification(ctx::Json& action, std::string pkgId)
+{
+ int error;
+ notification_h notification = notification_create(NOTIFICATION_TYPE_NOTI);
+ std::string title;
+ if (action.get(NULL, CT_RULE_ACTION_NOTI_TITLE, &title)) {
+ error = notification_set_text(notification, NOTIFICATION_TEXT_TYPE_TITLE, title.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ if (error != NOTIFICATION_ERROR_NONE) {
+ _E("Set notification title failed(%d)", error);
+ }
+ }
+
+ std::string content;
+ if (action.get(NULL, CT_RULE_ACTION_NOTI_CONTENT, &content)) {
+ error = notification_set_text(notification, NOTIFICATION_TEXT_TYPE_CONTENT, content.c_str(), NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
+ if (error != NOTIFICATION_ERROR_NONE) {
+ _E("Set notification contents failed(%d)", error);
+ }
+ }
+
+ std::string imagePath;
+ if (action.get(NULL, CT_RULE_ACTION_NOTI_ICON_PATH, &imagePath)) {
+ error = notification_set_image(notification, NOTIFICATION_IMAGE_TYPE_ICON, imagePath.c_str());
+ if (error != NOTIFICATION_ERROR_NONE) {
+ _E("Set notification icon image failed(%d)", error);
+ }
+ }
+
+ std::string appctlStr;
+ char* str = NULL;
+ bundle_raw* encoded = NULL;
+ bundle* appctlBundle = NULL;
+ app_control_h app = NULL;
+ if (action.get(NULL, CT_RULE_ACTION_APP_CONTROL, &appctlStr)) {
+ str = static_cast<char*>(malloc(appctlStr.length()));
+ if (str == NULL) {
+ _E("Memory allocation failed");
+ notification_free(notification);
+ return;
+ }
+ appctlStr.copy(str, appctlStr.length(), 0);
+ encoded = reinterpret_cast<unsigned char*>(str);
+ appctlBundle = bundle_decode(encoded, appctlStr.length());
+
+ app_control_create(&app);
+ app_control_import_from_bundle(app, appctlBundle);
+
+ error = notification_set_launch_option(notification, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL, app);
+ if (error != NOTIFICATION_ERROR_NONE) {
+ _E("Set launch option failed(%d)", error);
+ }
+ }
+
+ if (!pkgId.empty()) {
+ error = notification_set_pkgname(notification, pkgId.c_str());
+ if (error != NOTIFICATION_ERROR_NONE) {
+ _E("Set package id(%s) failed(%#x)", pkgId.c_str(), error);
+ }
+ }
+
+ bool silent = true;
+ error = system_settings_get_value_bool(SYSTEM_SETTINGS_KEY_SOUND_SILENT_MODE, &silent);
+ if (error != SYSTEM_SETTINGS_ERROR_NONE) {
+ _E("Get system setting(silent mode) failed(%d)", error);
+ }
+
+ bool vibration = true;
+ error = runtime_info_get_value_bool(RUNTIME_INFO_KEY_VIBRATION_ENABLED, &vibration);
+ if (error != RUNTIME_INFO_ERROR_NONE) {
+ _E("Get runtime info(vibration) failed(%d)", error);
+ }
+
+ if (!silent) {
+ error = notification_set_sound(notification, NOTIFICATION_SOUND_TYPE_DEFAULT, NULL);
+ if (error != NOTIFICATION_ERROR_NONE) {
+ _E("Set notification sound failed(%d)", error);
+ }
+
+ if (vibration) {
+ error = notification_set_vibration(notification, NOTIFICATION_VIBRATION_TYPE_DEFAULT, NULL);
+ if (error != NOTIFICATION_ERROR_NONE) {
+ _E("Set notification vibration failed(%d)", error);
+ }
+ }
+ }
+
+ error = notification_post(notification);
+ if (error != NOTIFICATION_ERROR_NONE) {
+ _E("Post notification failed(%d)", error);
+ } else {
+ _D("Post notification succeeded");
+ }
+
+ bundle_free(appctlBundle);
+ free(str);
+ notification_free(notification);
+ if (app) {
+ app_control_destroy(app);
+ }
+
+ error = device_display_change_state(DISPLAY_STATE_NORMAL);
+ if (error != DEVICE_ERROR_NONE) {
+ _E("Change display state failed(%d)", error);
+ }
+}
+
+void __triggerActionDbusCall(ctx::Json& action)
+{
+ std::string busName, object, iface, method;
+ GVariant *param = NULL;
+
+ action.get(NULL, CT_RULE_ACTION_DBUS_NAME, &busName);
+ IF_FAIL_VOID_TAG(!busName.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");
+
+ action.get(NULL, CT_RULE_ACTION_DBUS_PARAMETER, ¶m);
+
+ ctx::DBusServer::call(busName, object, iface, method, param);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_ACTION_MANAGER_H_
+#define _CONTEXT_TRIGGER_ACTION_MANAGER_H_
+
+namespace ctx {
+ /* Forward Declaration */
+ class Json;
+
+namespace trigger {
+
+ namespace action_manager {
+
+ void triggerAction(Json& action, std::string pkgId);
+
+ } /* namespace action_manager */
+
+} /* namespace trigger*/
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_TRIGGER_ACTION_MANAGER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <types_internal.h>
+#include "../access_control/privilege.h"
+#include "../context_mgr_impl.h"
+#include "ContextMonitor.h"
+#include "IContextListener.h"
+#include "FactRequest.h"
+
+using namespace ctx;
+using namespace trigger;
+
+static int __lastRid;
+static int __lastErr;
+
+ContextMonitor *ContextMonitor::__instance = NULL;
+context_manager_impl *ContextMonitor::__contextMgr = NULL;
+
+static int __generateReqId()
+{
+ static int reqId = 0;
+
+ if (++reqId < 0) {
+ // Overflow handling
+ reqId = 1;
+ }
+
+ return reqId;
+}
+
+ContextMonitor::ContextMonitor()
+{
+}
+
+ContextMonitor::~ContextMonitor()
+{
+}
+
+void ContextMonitor::setContextManager(context_manager_impl* ctx_mgr)
+{
+ __contextMgr = ctx_mgr;
+}
+
+ContextMonitor* ContextMonitor::getInstance()
+{
+ IF_FAIL_RETURN_TAG(__contextMgr, NULL, _E, "Context manager is needed");
+
+ IF_FAIL_RETURN(!__instance, __instance);
+
+ __instance = new(std::nothrow) ContextMonitor();
+ IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory alllocation failed");
+
+ return __instance;
+}
+
+void ContextMonitor::destroy()
+{
+ if (__instance) {
+ delete __instance;
+ __instance = NULL;
+ }
+}
+
+int ContextMonitor::subscribe(int ruleId, std::string subject, Json option, IContextListener* listener)
+{
+ int reqId = __subscribe(subject.c_str(), &option, listener);
+ IF_FAIL_RETURN_TAG(reqId > 0, reqId, _E, "Subscribe event failed");
+ _D(YELLOW("Subscribe event(rule%d). req%d"), ruleId, reqId);
+
+ return ERR_NONE;
+}
+
+int ContextMonitor::__subscribe(const char* subject, Json* option, IContextListener* listener)
+{
+ IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER);
+
+ int rid = __findSub(REQ_SUBSCRIBE, subject, option);
+ if (rid > 0) {
+ __addListener(REQ_SUBSCRIBE, rid, listener);
+ _D("Duplicated request for %s", subject);
+ return rid;
+ }
+
+ rid = __generateReqId();
+
+ FactRequest *req = new(std::nothrow) FactRequest(REQ_SUBSCRIBE,
+ rid, subject, option ? option->str().c_str() : NULL, this);
+ IF_FAIL_RETURN_TAG(req, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+ __contextMgr->assign_request(req);
+ __addSub(REQ_SUBSCRIBE, rid, subject, option, listener);
+
+ if (__lastErr != ERR_NONE) {
+ __removeSub(REQ_SUBSCRIBE, rid);
+ _E("Subscription request failed: %#x", __lastErr);
+ return __lastErr;
+ }
+
+ return rid;
+}
+
+int ContextMonitor::unsubscribe(int ruleId, std::string subject, Json option, IContextListener* listener)
+{
+ int rid = __findSub(REQ_SUBSCRIBE, subject.c_str(), &option);
+ if (rid < 0) {
+ _D("Invalid unsubscribe request");
+ return ERR_INVALID_PARAMETER;
+ }
+
+ if (__removeListener(REQ_SUBSCRIBE, rid, listener) <= 0) {
+ __unsubscribe(subject.c_str(), rid);
+ }
+ _D(YELLOW("Unsubscribe event(rule%d). req%d"), ruleId, rid);
+
+ return ERR_NONE;
+}
+
+void ContextMonitor::__unsubscribe(const char *subject, int subscriptionId)
+{
+ FactRequest *req = new(std::nothrow) FactRequest(REQ_UNSUBSCRIBE, subscriptionId, subject, NULL, NULL);
+ IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed");
+
+ __contextMgr->assign_request(req);
+ __removeSub(REQ_SUBSCRIBE, subscriptionId);
+}
+
+int ContextMonitor::read(std::string subject, Json option, IContextListener* listener)
+{
+ int reqId = __read(subject.c_str(), &option, listener);
+ IF_FAIL_RETURN_TAG(reqId > 0, ERR_OPERATION_FAILED, _E, "Read condition failed");
+ _D(YELLOW("Read condition(%s). req%d"), subject.c_str(), reqId);
+
+ return ERR_NONE;
+}
+
+int ContextMonitor::__read(const char* subject, Json* option, IContextListener* listener)
+{
+ IF_FAIL_RETURN(subject, ERR_INVALID_PARAMETER);
+
+ int rid = __findSub(REQ_READ, subject, option);
+ if (rid > 0) {
+ __addListener(REQ_READ, rid, listener);
+ _D("Duplicated request for %s", subject);
+ return rid;
+ }
+
+ rid = __generateReqId();
+
+ FactRequest *req = new(std::nothrow) FactRequest(REQ_READ,
+ rid, subject, option ? option->str().c_str() : NULL, this);
+ IF_FAIL_RETURN_TAG(req, -1, _E, "Memory allocation failed");
+
+ __contextMgr->assign_request(req);
+ __addSub(REQ_READ, rid, subject, option, listener);
+
+ if (__lastErr != ERR_NONE) {
+ _E("Read request failed: %#x", __lastErr);
+ return -1;
+ }
+
+ return rid;
+}
+
+bool ContextMonitor::isSupported(std::string subject)
+{
+ return __contextMgr->is_supported(subject.c_str());
+}
+
+bool ContextMonitor::isAllowed(const char *client, const char *subject)
+{
+ //TODO: re-implement this in the proper 3.0 style
+ //return __contextMgr->isAllowed(client, subject);
+ return true;
+}
+
+int ContextMonitor::__findSub(request_type type, const char* subject, Json* option)
+{
+ // @return request id
+ std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &___readMap;
+
+ Json jOpt;
+ if (option) {
+ jOpt = *option;
+ }
+
+ for (auto it = map->begin(); it != map->end(); ++it) {
+ if ((*(it->second)).subject == subject && (*(it->second)).option == jOpt) {
+ return it->first;
+ }
+ }
+
+ return -1;
+}
+
+bool ContextMonitor::__addSub(request_type type, int sid, const char* subject, Json* option, IContextListener* listener)
+{
+ std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &___readMap;
+
+ SubscrInfo *info = new(std::nothrow) SubscrInfo(sid, subject, option);
+ IF_FAIL_RETURN_TAG(info, false, _E, "Memory allocation failed");
+ info->listenerList.push_back(listener);
+
+ map->insert(std::pair<int, SubscrInfo*>(sid, info));
+ return true;
+}
+
+void ContextMonitor::__removeSub(request_type type, const char* subject, Json* option)
+{
+ std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &___readMap;
+
+ Json jOpt;
+ if (option) {
+ jOpt = *option;
+ }
+
+ for (auto it = map->begin(); it != map->end(); ++it) {
+ if ((*(it->second)).subject == subject && (*(it->second)).option == jOpt) {
+ delete it->second;
+ map->erase(it);
+ return;
+ }
+ }
+}
+
+void ContextMonitor::__removeSub(request_type type, int sid)
+{
+ std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &___readMap;
+
+ SubscrInfo* info = map->at(sid);
+ info->listenerList.clear();
+
+ delete info;
+ map->erase(sid);
+
+ return;
+}
+
+int ContextMonitor::__addListener(request_type type, int sid, IContextListener* listener)
+{
+ // @return number of listeners for the corresponding sid
+ std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &___readMap;
+
+ auto it = map->find(sid);
+
+ SubscrInfo* info = it->second;
+ info->listenerList.push_back(listener);
+
+ return info->listenerList.size();
+}
+
+int ContextMonitor::__removeListener(request_type type, int sid, IContextListener* listener)
+{
+ // @return number of listeners for the corresponding sid
+ std::map<int, SubscrInfo*>* map = (type == REQ_SUBSCRIBE)? &__subscrMap : &___readMap;
+
+ auto it = map->find(sid);
+
+ SubscrInfo* info = it->second;
+
+ for (auto it2 = info->listenerList.begin(); it2 != info->listenerList.end(); ++it2) {
+ if (*it2 == listener) {
+ info->listenerList.erase(it2);
+ break;
+ }
+ }
+
+ return info->listenerList.size();
+}
+
+void ContextMonitor::replyResult(int reqId, int error, Json* requestResult)
+{
+ _D("Request result received: %d", reqId);
+
+ __lastRid = reqId;
+ __lastErr = error;
+}
+
+void ContextMonitor::replyResult(int reqId, int error, const char* subject, Json* option, Json* fact)
+{
+ _D(YELLOW("Condition received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str());
+
+ auto it = ___readMap.find(reqId);
+ IF_FAIL_VOID_TAG(it != ___readMap.end(), _E, "Request id not found");
+
+ SubscrInfo* info = it->second;
+ for (auto it2 = info->listenerList.begin(); it2 != info->listenerList.end(); ++it2) {
+ (*it2)->onConditionReceived(subject, *option, *fact);
+ }
+
+ __removeSub(REQ_READ, reqId);
+}
+
+void ContextMonitor::publishFact(int reqId, int error, const char* subject, Json* option, Json* fact)
+{
+ _D(YELLOW("Event received: subject(%s), option(%s), fact(%s)"), subject, option->str().c_str(), fact->str().c_str());
+
+ auto it = __subscrMap.find(reqId);
+ IF_FAIL_VOID_TAG(it != __subscrMap.end(), _E, "Request id not found");
+
+ SubscrInfo* info = it->second;
+ for (auto it2 = info->listenerList.begin(); it2 != info->listenerList.end(); ++it2) {
+ (*it2)->onEventReceived(subject, *option, *fact);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_CONTEXT_MONITOR_H_
+#define _CONTEXT_TRIGGER_CONTEXT_MONITOR_H_
+
+#include <list>
+#include <map>
+#include <Json.h>
+
+namespace ctx {
+
+ class context_manager_impl;
+
+namespace trigger {
+
+ class IContextListener;
+ class FactRequest;
+
+ class ContextMonitor {
+ public:
+ static ContextMonitor* getInstance();
+ static void setContextManager(context_manager_impl* ctx_mgr);
+ static void destroy();
+
+ int subscribe(int ruleId, std::string subject, Json option, IContextListener* listener);
+ int unsubscribe(int ruleId, std::string subject, Json option, IContextListener* listener);
+ int read(std::string subject, Json option, IContextListener* listener);
+ bool isSupported(std::string subject);
+ bool isAllowed(const char *client, const char *subject);
+
+ void replyResult(int reqId, int error, Json *requestResult = NULL);
+ void replyResult(int reqId, int error, const char *subject, Json *option, Json *fact);
+ void publishFact(int reqId, int error, const char *subject, Json *option, Json *fact);
+
+ private:
+ ContextMonitor();
+ ContextMonitor(const ContextMonitor& other);
+ ~ContextMonitor();
+
+ static ContextMonitor *__instance;
+ static context_manager_impl *__contextMgr;
+
+ int __subscribe(const char* subject, Json* option, IContextListener* listener);
+ void __unsubscribe(const char *subject, int subscriptionId);
+ int __read(const char *subject, Json *option, IContextListener* listener);
+
+ struct SubscrInfo {
+ int sid;
+ std::string subject;
+ Json option;
+ std::list<IContextListener*> listenerList;
+
+ SubscrInfo(int id, const char *subj, Json *opt) :
+ sid(id),
+ subject(subj)
+ {
+ if (opt)
+ option = *opt;
+ }
+ };
+
+ std::map<int, SubscrInfo*> __subscrMap;
+ std::map<int, SubscrInfo*> ___readMap;
+
+ int __findSub(request_type type, const char *subject, Json *option);
+ bool __addSub(request_type type, int sid, const char *subject, Json *option, IContextListener* listener);
+ void __removeSub(request_type type, const char *subject, Json *option);
+ void __removeSub(request_type type, int sid);
+ int __addListener(request_type type, int sid, IContextListener* listener);
+ int __removeListener(request_type type, int sid, IContextListener* listener);
+
+ }; /* class ContextMonitor */
+
+} /* namespace trigger */
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_TRIGGER_CONTEXT_MONITOR_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <types_internal.h>
+#include "FactRequest.h"
+
+using namespace ctx;
+using namespace ctx::trigger;
+
+FactRequest::FactRequest(int type, int reqId, const char* subj, const char* desc, ContextMonitor* ctxMonitor) :
+ RequestInfo(type, reqId, subj, desc),
+ __ctxMonitor(ctxMonitor),
+ __replied(false)
+{
+}
+
+FactRequest::~FactRequest()
+{
+ reply(ERR_OPERATION_FAILED);
+}
+
+const char* FactRequest::getClient()
+{
+ return "TRIGGER";
+}
+
+bool FactRequest::reply(int error)
+{
+ IF_FAIL_RETURN(!__replied && __ctxMonitor, true);
+ __ctxMonitor->replyResult(_reqId, error);
+ __replied = (error != ERR_NONE);
+ return true;
+}
+
+bool FactRequest::reply(int error, Json& requestResult)
+{
+ IF_FAIL_RETURN(!__replied && __ctxMonitor, true);
+ __ctxMonitor->replyResult(_reqId, error, &requestResult);
+ __replied = (error != ERR_NONE);
+ return true;
+}
+
+bool FactRequest::reply(int error, Json& requestResult, Json& dataRead)
+{
+ IF_FAIL_RETURN(!__replied && __ctxMonitor, true);
+ __ctxMonitor->replyResult(_reqId, error, _subject.c_str(), &getDescription(), &dataRead);
+ return (__replied = true);
+}
+
+bool FactRequest::publish(int error, Json& data)
+{
+ IF_FAIL_RETURN(__ctxMonitor, true);
+ __ctxMonitor->publishFact(_reqId, error, _subject.c_str(), &getDescription(), &data);
+ return true;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_FACT_REQUEST_H_
+#define _CONTEXT_TRIGGER_FACT_REQUEST_H_
+
+#include "ContextMonitor.h"
+#include "../Request.h"
+
+namespace ctx {
+
+namespace trigger {
+
+ class FactRequest : public RequestInfo {
+ public:
+ FactRequest(int type, int reqId, const char* subj, const char* desc, ContextMonitor* ctxMonitor);
+ ~FactRequest();
+
+ const char* getClient();
+ bool reply(int error);
+ bool reply(int error, ctx::Json& requestResult);
+ bool reply(int error, ctx::Json& requestResult, ctx::Json& dataRead);
+ bool publish(int error, ctx::Json& data);
+
+ private:
+ ContextMonitor *__ctxMonitor;
+ bool __replied;
+ };
+
+} /* namespace trigger */
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_TRIGGER_FACT_REQUEST_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_FACT_TYPES_H_
+#define _CONTEXT_TRIGGER_FACT_TYPES_H_
+
+#define CONTEXT_FACT_EVENT "EVENT"
+#define CONTEXT_FACT_CONDITION "CONDITION"
+#define CONTEXT_FACT_NAME "NAME"
+#define CONTEXT_FACT_OPTION "OPTION"
+#define CONTEXT_FACT_DATA "DATA"
+
+#endif /* End of _CONTEXT_TRIGGER_FACT_TYPES_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_I_CONTEXT_LISTENER_H_
+#define _CONTEXT_TRIGGER_I_CONTEXT_LISTENER_H_
+
+namespace ctx {
+ /* Forward Declaration */
+ class Json;
+
+namespace trigger {
+
+ class IContextListener {
+ public:
+ virtual ~IContextListener() {}
+
+ virtual void onEventReceived(std::string name, Json option, Json data) = 0;
+
+ virtual void onConditionReceived(std::string name, Json option, Json data) = 0;
+ };
+
+} /* namespace trigger */
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_TRIGGER_I_CONTEXT_LISTENER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <context_trigger_types_internal.h>
+#include "Rule.h"
+#include "ActionManager.h"
+#include "RuleEvaluator.h"
+#include "ContextMonitor.h"
+#include "FactTypes.h"
+#include "RuleManager.h"
+
+using namespace ctx;
+using namespace ctx::trigger;
+
+RuleManager *Rule::__ruleMgr = NULL;
+
+Rule::Rule(int i, Json& d, const char* p, RuleManager* rm) :
+ __result(EMPTY_JSON_OBJECT),
+ id(i),
+ pkgId(p)
+{
+ // Rule manager
+ if (!__ruleMgr) {
+ __ruleMgr = rm;
+ }
+
+ // Statement
+ __statement = d.str();
+
+ // Event
+ Json e;
+ d.get(NULL, CT_RULE_EVENT, &e);
+ __event = new(std::nothrow) ContextItem(e);
+
+ // Condition
+ int cond_num = d.getSize(NULL, CT_RULE_CONDITION);
+ for (int j = 0; j < cond_num; j++) {
+ Json c;
+ d.getAt(NULL, CT_RULE_CONDITION, j, &c);
+ __condition.push_back(new(std::nothrow) ContextItem(c));
+ }
+
+ // Action
+ Json a;
+ d.get(NULL, CT_RULE_ACTION, &a);
+ __action = a.str();
+}
+
+Rule::~Rule()
+{
+ // Release resources
+ delete __event;
+ for (auto it = __condition.begin(); it != __condition.end(); ++it) {
+ delete *it;
+ }
+}
+
+int Rule::start(void)
+{
+ // Subscribe event
+ int error = ContextMonitor::getInstance()->subscribe(id, __event->name, __event->option, this);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to start rule%d", id);
+
+ return error;
+}
+
+int Rule::stop(void)
+{
+ // Unsubscribe event
+ int error = ContextMonitor::getInstance()->unsubscribe(id, __event->name, __event->option, this);
+ if (error == ERR_NOT_SUPPORTED) {
+ _E("Stop rule%d (event not supported)");
+ return ERR_NONE;
+ }
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", id);
+
+ return error;
+}
+
+bool Rule::__setConditionOptionBasedOnEvent(Json& option)
+{
+ // Set condition option if it references event data
+ std::list<std::string> optionKeys;
+ option.getKeys(&optionKeys);
+
+ for (auto it = optionKeys.begin(); it != optionKeys.end(); ++it) {
+ std::string optKey = (*it);
+
+ std::string optVal;
+ if (option.get(NULL, optKey.c_str(), &optVal)) {
+ if (optVal.find("?") != 0) {
+ continue;
+ }
+
+ std::string eventKey = optVal.substr(1, optVal.length() - 1);
+
+ std::string newStr;
+ int new_val;
+ if (__result.get(CONTEXT_FACT_EVENT "." CONTEXT_FACT_DATA, eventKey.c_str(), &newStr)) {
+ option.set(NULL, optKey.c_str(), newStr);
+ } else if (__result.get(CONTEXT_FACT_EVENT "." CONTEXT_FACT_DATA, eventKey.c_str(), &new_val)) {
+ option.set(NULL, optKey.c_str(), new_val);
+ } else {
+ _W("Failed to find '%s' in event data", eventKey.c_str());
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void Rule::onEventReceived(std::string name, Json option, Json data)
+{
+ if (__result != EMPTY_JSON_OBJECT) {
+ __clearResult();
+ }
+
+ // Check if creator package is uninstalled
+ if (RuleManager::isUninstalledPackage(pkgId)) {
+ _D("Creator(%s) of rule%d is uninstalled.", pkgId.c_str(), id);
+ g_idle_add(__handleUninstalledRule, &pkgId);
+ return;
+ }
+
+ _D("Rule%d received event data", id);
+
+ // Set event data
+ __result.set(CONTEXT_FACT_EVENT, CONTEXT_FACT_NAME, name);
+ __result.set(CONTEXT_FACT_EVENT, CONTEXT_FACT_OPTION, option);
+ __result.set(CONTEXT_FACT_EVENT, CONTEXT_FACT_DATA, data);
+
+ if (__condition.size() == 0) {
+ __onContextDataPrepared();
+ return;
+ }
+
+ IF_FAIL_VOID_TAG(RuleEvaluator::evaluateRule(__statement, __result), _E, "Event not matched");
+
+ // Request read conditions
+ for (auto it = __condition.begin(); it != __condition.end(); ++it) {
+ Json condOption = (*it)->option.str();
+ if (!__setConditionOptionBasedOnEvent(condOption)) { // condOption should be copy of original option.
+ __clearResult();
+ return;
+ }
+
+ int error = ContextMonitor::getInstance()->read((*it)->name.c_str(), condOption, this);
+ IF_FAIL_VOID_TAG(error == ERR_NONE, _E, "Failed to read condition");
+ }
+
+ // TODO timer set
+}
+
+void Rule::onConditionReceived(std::string name, Json option, Json data)
+{
+ _D("Rule%d received condition data", id);
+
+ // Set condition data
+ Json item;
+ item.set(NULL, CONTEXT_FACT_NAME, name);
+ item.set(NULL, CONTEXT_FACT_OPTION, option);
+ item.set(NULL, CONTEXT_FACT_DATA, data);
+ __result.append(NULL, CONTEXT_FACT_CONDITION, item);
+
+ if (__result.getSize(NULL, CONTEXT_FACT_CONDITION) == (int) __condition.size()) {
+ __onContextDataPrepared();
+ }
+}
+
+void Rule::__clearResult()
+{
+ __result = EMPTY_JSON_OBJECT;
+ // TODO timer cancel
+}
+
+void Rule::__onContextDataPrepared(void)
+{
+ if (RuleEvaluator::evaluateRule(__statement, __result)) {
+ action_manager::triggerAction(__action, pkgId);
+ }
+ __clearResult();
+}
+
+gboolean Rule::__handleUninstalledRule(gpointer data)
+{
+ std::string* pkgId = static_cast<std::string*>(data);
+ __ruleMgr->handleRuleOfUninstalledPackage(*pkgId);
+
+ return FALSE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_RULE_H_
+#define _CONTEXT_TRIGGER_RULE_H_
+
+#include <string>
+#include <Json.h>
+#include "IContextListener.h"
+
+namespace ctx {
+
+namespace trigger {
+
+ class RuleManager;
+
+ class Rule : public IContextListener {
+ private:
+ struct ContextItem {
+ std::string name;
+ ctx::Json option;
+ ContextItem(ctx::Json item) {
+ std::string n;
+ item.get(NULL, CT_RULE_EVENT_ITEM, &n);
+ name = n;
+
+ ctx::Json o;
+ if (item.get(NULL, CT_RULE_EVENT_OPTION, &o))
+ option = o.str();
+ }
+ };
+
+ ctx::Json __statement;
+ ContextItem* __event;
+ std::list<ContextItem*> __condition;
+ ctx::Json __action;
+ ctx::Json __result;
+
+ static RuleManager* __ruleMgr;
+
+ void __clearResult(void);
+ bool __setConditionOptionBasedOnEvent(ctx::Json& option);
+ void __onContextDataPrepared(void);
+
+ static gboolean __handleUninstalledRule(gpointer data);
+
+ public:
+ int id;
+ std::string pkgId;
+
+ Rule(int i, ctx::Json& d, const char* p, RuleManager* rm);
+ ~Rule();
+
+ int start(void);
+ int stop(void);
+
+ void onEventReceived(std::string name, ctx::Json option, ctx::Json data);
+ void onConditionReceived(std::string name, ctx::Json option, ctx::Json data);
+
+ };
+
+} /* namespace trigger */
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_TRIGGER_RULE_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <Json.h>
+#include <types_internal.h>
+#include <context_trigger_types_internal.h>
+#include "RuleEvaluator.h"
+#include "FactTypes.h"
+
+#define AND_STRING "and"
+#define OR_STRING "or"
+#define EVENT_REFERENCE "?"
+#define OPERATOR_EQ "=="
+#define OPERATOR_NEQ "!="
+#define OPERATOR_LEQ "<="
+#define OPERATOR_GEQ ">="
+#define OPERATOR_LT "<"
+#define OPERATOR_GT ">"
+
+using namespace ctx;
+using namespace ctx::trigger;
+
+RuleEvaluator::RuleEvaluator()
+{
+}
+
+bool RuleEvaluator::__compareString(std::string op, std::string ruleVar, std::string factVar)
+{
+ if (op == OPERATOR_EQ) {
+ return (ruleVar == factVar);
+ } else if (op == OPERATOR_NEQ) {
+ return (ruleVar != factVar);
+ } else {
+ _E("Operator %s not supported", op.c_str());
+ return false;
+ }
+}
+
+bool RuleEvaluator::__compareInt(std::string op, int ruleVar, int factVar)
+{
+ if (op == OPERATOR_EQ) {
+ return (ruleVar == factVar);
+ } else if (op == OPERATOR_NEQ) {
+ return (ruleVar != factVar);
+ } else if (op == OPERATOR_LEQ) {
+ return (ruleVar <= factVar);
+ } else if (op == OPERATOR_GEQ) {
+ return (ruleVar >= factVar);
+ } else if (op == OPERATOR_LT) {
+ return (ruleVar < factVar);
+ } else if (op == OPERATOR_GT) {
+ return (ruleVar > factVar);
+ } else {
+ _E("Operator %s not supported", op.c_str());
+ return false;
+ }
+}
+
+bool RuleEvaluator::__replaceDataReferences(Json& ruleDataArr, Json eventFactData)
+{
+ // Replace referencing data to actual value
+ std::string refVal;
+ std::string eventRefStr;
+ int eventRefInt;
+
+ for (int i = 0; i < ruleDataArr.getSize(NULL, CT_RULE_DATA_VALUE_ARR); i++) {
+ if (!ruleDataArr.getAt(NULL, CT_RULE_DATA_VALUE_ARR, i, &refVal)) {
+ continue;
+ }
+ if (refVal.substr(0, 1) != EVENT_REFERENCE) {
+ continue;
+ }
+
+ std::string eventKey = refVal.substr(1, refVal.length() - 1);
+ if (eventFactData.get(NULL, eventKey.c_str(), &eventRefStr)) {
+ ruleDataArr.setAt(NULL, CT_RULE_DATA_VALUE_ARR, i, eventRefStr);
+ } else if (eventFactData.get(NULL, eventKey.c_str(), &eventRefInt)) {
+ ruleDataArr.setAt(NULL, CT_RULE_DATA_VALUE_ARR, i, eventRefInt);
+ } else {
+ _W("Option %s not found in event_data", eventKey.c_str());
+ }
+ }
+
+ return true;
+}
+
+bool RuleEvaluator::__replaceOptionReferences(Json& ruleOption, Json eventFactData)
+{
+ // Replace referencing option to actual value
+ std::string refVal;
+ std::string eventRefStr;
+ int eventRefInt;
+
+ std::list<std::string> keyList;
+ ruleOption.getKeys(&keyList);
+
+ for (std::list<std::string>::iterator it = keyList.begin(); it != keyList.end(); ++it) {
+ std::string optionKey = *it;
+
+ if (!ruleOption.get(NULL, (*it).c_str(), &refVal)) {
+ continue;
+ }
+ if (!(refVal.substr(0, 1) == EVENT_REFERENCE)) {
+ continue;
+ }
+
+ std::string eventKey = refVal.substr(1, refVal.length() - 1);
+ if (eventFactData.get(NULL, eventKey.c_str(), &eventRefStr)) {
+ ruleOption.set(NULL, (*it).c_str(), eventRefStr);
+ } else if (eventFactData.get(NULL, eventKey.c_str(), &eventRefInt)) {
+ ruleOption.set(NULL, (*it).c_str(), eventRefInt);
+ } else {
+ _W("Option %s not found in event_data", eventKey.c_str());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool RuleEvaluator::__replaceEventReferences(Json& rule, Json& fact)
+{
+ // Replace referencing data/option to actual value
+ Json eventFactData;
+ if (!fact.get(CONTEXT_FACT_EVENT, CONTEXT_FACT_DATA, &eventFactData)) {
+ _E("No event data found, error");
+ return false;
+ }
+
+ Json ruleCond;
+ for (int i = 0; rule.getAt(NULL, CT_RULE_CONDITION, i, &ruleCond); i++) {
+ Json ruleDataArr;
+ for (int j = 0; ruleCond.getAt(NULL, CT_RULE_DATA_ARR, j, &ruleDataArr); j++) {
+ __replaceDataReferences(ruleDataArr, eventFactData);
+ }
+
+ Json ruleOption;
+ if (ruleCond.get(NULL, CT_RULE_CONDITION_OPTION, &ruleOption)) {
+ __replaceOptionReferences(ruleOption, eventFactData);
+ }
+ }
+
+ return true;
+}
+
+bool RuleEvaluator::__evaluateDataString(Json& ruleDataArr, std::string factValStr)
+{
+ std::string opVal;
+ ruleDataArr.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &opVal);
+ bool conjunction = (AND_STRING == opVal);
+
+ std::string op;
+ for (int i = 0; ruleDataArr.getAt(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, i, &op); i++) {
+ bool result;
+ std::string valStr;
+ ruleDataArr.getAt(NULL, CT_RULE_DATA_VALUE_ARR, i, &valStr);
+ result = __compareString(op, factValStr, valStr);
+
+ if (conjunction && !result) {
+ return false;
+ } else if (!conjunction && result) {
+ return true;
+ }
+ }
+ return conjunction;
+}
+
+bool RuleEvaluator::__evaluateDataInt(Json& ruleDataArr, int factValInt)
+{
+ std::string opVal;
+ ruleDataArr.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &opVal);
+ bool conjunction = (AND_STRING == opVal);
+
+ std::string op;
+ for (int i = 0; ruleDataArr.getAt(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, i, &op); i++) {
+ bool result;
+ int valInt;
+ if (!ruleDataArr.getAt(NULL, CT_RULE_DATA_VALUE_ARR, i, &valInt)) {
+ result = false;
+ }
+ result = __compareInt(op, factValInt, valInt);
+
+ if (conjunction && !result) {
+ return false;
+ } else if (!conjunction && result) {
+ return true;
+ }
+ }
+ return conjunction;
+}
+
+bool RuleEvaluator::__evaluateItem(Json& ruleItem, Json& factItem)
+{
+ Json ruleDataArr;
+ if (ruleItem.getSize(NULL, CT_RULE_DATA_ARR) == 0) {
+ return true;
+ }
+
+ std::string opKey;
+ ruleItem.get(NULL, CT_RULE_CONDITION_OPERATOR, &opKey);
+ bool conjunction = (AND_STRING == opKey);
+
+ for (int i = 0; ruleItem.getAt(NULL, CT_RULE_DATA_ARR, i, &ruleDataArr); i++) {
+ std::string dataKey;
+ ruleDataArr.get(NULL, CT_RULE_DATA_KEY, &dataKey);
+ std::string factValStr;
+ int factValInt;
+
+ bool result;
+ if (factItem.get(CONTEXT_FACT_DATA, dataKey.c_str(), &factValStr)) {
+ result = __evaluateDataString(ruleDataArr, factValStr);
+ } else if (factItem.get(CONTEXT_FACT_DATA, dataKey.c_str(), &factValInt)) {
+ result = __evaluateDataInt(ruleDataArr, factValInt);
+ } else {
+ _W("Could not get value corresponding to data key %s", dataKey.c_str());
+ result = false;
+ }
+
+ if (conjunction && !result) {
+ return false;
+ } else if (!conjunction && result) {
+ return true;
+ }
+ }
+ return conjunction;
+}
+
+bool RuleEvaluator::__evaluateRuleEvent(Json& rule, Json& fact)
+{
+ Json factItem;
+ Json ruleItem;
+ fact.get(NULL, CONTEXT_FACT_EVENT, &factItem);
+ rule.get(NULL, CT_RULE_EVENT, &ruleItem);
+
+ return __evaluateItem(ruleItem, factItem);
+}
+
+Json RuleEvaluator::__getConditionFact(Json& ruleCond, Json& fact)
+{
+ std::string ruleCondName;
+ ruleCond.get(NULL, CT_RULE_CONDITION_ITEM, &ruleCondName);
+
+ Json factCond;
+ for (int i = 0; fact.getAt(NULL, CONTEXT_FACT_CONDITION, i, &factCond); i++) {
+ // Check if fact item name is matched with condition
+ std::string factCondName;
+ factCond.get(NULL, CONTEXT_FACT_NAME, &factCondName);
+ if (factCondName != ruleCondName) {
+ continue;
+ }
+
+ // Check if fact item option is mathced with condition
+ Json ruleCondOption;
+ Json factCondOption;
+ ruleCond.get(NULL, CT_RULE_CONDITION_OPTION, &ruleCondOption);
+ factCond.get(NULL, CONTEXT_FACT_OPTION, &factCondOption);
+ if (factCondOption == ruleCondOption) {
+ return factCond;
+ }
+ }
+
+ _W(YELLOW("find condition failed for condition"));
+ return EMPTY_JSON_OBJECT;
+}
+
+bool RuleEvaluator::__evaluateRuleCondition(Json& rule, Json& fact)
+{
+ Json ruleCond;
+ Json factCond;
+
+ std::string opCond;
+ rule.get(NULL, CT_RULE_OPERATOR, &opCond);
+ bool conjunction = (AND_STRING == opCond);
+
+ for (int i = 0; rule.getAt(NULL, CT_RULE_CONDITION, i, &ruleCond); i++) {
+ factCond = __getConditionFact(ruleCond, fact);
+ bool result;
+ if (factCond == EMPTY_JSON_OBJECT) {
+ result = false;
+ } else {
+ result = __evaluateItem(ruleCond, factCond);
+ }
+
+ if (conjunction && !result) {
+ return false;
+ } else if (!conjunction && result) {
+ return true;
+ }
+ }
+
+ return conjunction;
+}
+
+bool RuleEvaluator::evaluateRule(Json rule, Json fact)
+{
+ _D("Rule is %s ", rule.str().c_str());
+ _D("fact is %s ", fact.str().c_str());
+
+ RuleEvaluator eval;
+ bool ret;
+ Json tempJson;
+ if (fact.get(NULL, CT_RULE_CONDITION, &tempJson)) {
+ Json ruleCopy(rule.str());
+ if (!eval.__replaceEventReferences(ruleCopy, fact)) {
+ _W("Replace failed");
+ }
+ ret = eval.__evaluateRuleCondition(ruleCopy, fact);
+ _D("Checking condition %s", ret ? "true" : "false");
+ } else {
+ ret = eval.__evaluateRuleEvent(rule, fact);
+ _D("Checking event %s", ret ? "true" : "false");
+ }
+
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_RULE_EVALUATOR_H_
+#define _CONTEXT_TRIGGER_RULE_EVALUATOR_H_
+
+namespace ctx {
+
+ class Json;
+
+namespace trigger {
+
+ class RuleEvaluator {
+ private:
+ RuleEvaluator();
+
+ bool __evaluateRuleEvent(ctx::Json& rule, ctx::Json& fact);
+ bool __evaluateRuleCondition(ctx::Json& rule, ctx::Json& fact);
+ bool __evaluateItem(ctx::Json& ruleItem, ctx::Json& factItem);
+ bool __evaluateDataString(ctx::Json& ruleDataArr, std::string factValStr);
+ bool __evaluateDataInt(ctx::Json& ruleDataArr, int factValInt);
+ bool __compareInt(std::string op, int ruleVar, int factVar);
+ bool __compareString(std::string op, std::string ruleVar, std::string factVar);
+
+ ctx::Json __getConditionFact(ctx::Json& ruleCond, ctx::Json& fact);
+
+ bool __replaceEventReferences(ctx::Json& rule, ctx::Json& fact);
+ bool __replaceDataReferences(ctx::Json& ruleDataArr, ctx::Json eventFactData);
+ bool __replaceOptionReferences(ctx::Json& ruleOption, ctx::Json eventFactData);
+
+ public:
+ static bool evaluateRule(ctx::Json rule, ctx::Json data);
+ };
+
+} /* namespace trigger */
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_TRIGGER_RULE_EVALUATOR_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <sstream>
+#include <context_trigger_types_internal.h>
+#include <db_mgr.h>
+#include <package_manager.h>
+#include <Json.h>
+#include "RuleManager.h"
+#include "ContextMonitor.h"
+#include "Rule.h"
+#include "Timer.h"
+
+#define RULE_TABLE "context_trigger_rule"
+
+using namespace ctx;
+using namespace ctx::trigger;
+
+static int __stringToInt(std::string str)
+{
+ int i;
+ std::istringstream convert(str);
+
+ if (!(convert >> i))
+ i = 0;
+
+ return i;
+}
+
+static std::string __intToString(int i)
+{
+ std::ostringstream convert;
+ convert << i;
+ std::string str = convert.str();
+ return str;
+}
+
+RuleManager::RuleManager()
+{
+}
+
+RuleManager::~RuleManager()
+{
+}
+
+bool RuleManager::init()
+{
+ bool ret;
+ int error;
+
+ // Create tables into db (rule, template)
+ std::string q1 = std::string("status INTEGER DEFAULT 0 NOT NULL, creator TEXT DEFAULT '' NOT NULL,")
+ + "package_id TEXT DEFAULT '' NOT NULL, description TEXT DEFAULT '',"
+ + "details TEXT DEFAULT '' NOT NULL";
+ ret = db_manager::create_table(1, RULE_TABLE, q1.c_str(), NULL, NULL);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Create rule table failed");
+
+ // Before re-enable rules, handle uninstalled app's rules
+ if (__getUninstalledApp() > 0) {
+ error = __clearRuleOfUninstalledPackage(true);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, false, _E, "Failed to remove uninstalled apps' rules while initialization");
+ }
+ ret = __reenableRule();
+
+ return ret;
+}
+
+void RuleManager::handleRuleOfUninstalledPackage(std::string pkgId)
+{
+ __uninstalledPackages.insert(pkgId);
+ __clearRuleOfUninstalledPackage();
+}
+
+int RuleManager::__getUninstalledApp(void)
+{
+ // Return number of uninstalled apps
+ std::string q1 = "SELECT DISTINCT package_id FROM context_trigger_rule";
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q1.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, -1, _E, "Query package ids of registered rules failed");
+
+ std::vector<Json>::iterator vecEnd = record.end();
+ for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
+ Json elem = *vecPos;
+ std::string pkgId;
+ elem.get(NULL, "package_id", &pkgId);
+
+ if (isUninstalledPackage(pkgId)) {
+ __uninstalledPackages.insert(pkgId);
+ }
+ }
+
+ return __uninstalledPackages.size();
+}
+
+bool RuleManager::isUninstalledPackage(std::string pkgId)
+{
+ IF_FAIL_RETURN_TAG(!pkgId.empty(), false, _D, "Empty package id");
+
+ package_info_h pkgInfo;
+ int error = package_manager_get_package_info(pkgId.c_str(), &pkgInfo);
+
+ if (error == PACKAGE_MANAGER_ERROR_NONE) {
+ package_info_destroy(pkgInfo);
+ } else if (error == PACKAGE_MANAGER_ERROR_NO_SUCH_PACKAGE) {
+ // Uninstalled package found
+ _D("Uninstalled package found: %s", pkgId.c_str());
+ return true;
+ } else {
+ _E("Failed to get package info(%s): %d", pkgId.c_str(), error);
+ }
+
+ return false;
+}
+
+int RuleManager::__clearRuleOfUninstalledPackage(bool isInit)
+{
+ if (__uninstalledPackages.size() <= 0) {
+ return ERR_NONE;
+ }
+
+ int error;
+ bool ret;
+
+ _D("Clear uninstalled packages' rule started");
+ // Package list
+ std::string pkgList = "(";
+ std::set<std::string>::iterator it = __uninstalledPackages.begin();
+ pkgList += "package_id = '" + *it + "'";
+ it++;
+ for (; it != __uninstalledPackages.end(); ++it) {
+ pkgList += " OR package_id = '" + *it + "'";
+ }
+ pkgList += ")";
+
+ // After event received, disable all the enabled rules of uninstalled apps
+ if (!isInit) {
+ std::string q1 = "SELECT row_id FROM context_trigger_rule WHERE status = 2 and (";
+ q1 += pkgList;
+ q1 += ")";
+
+ std::vector<Json> record;
+ ret = db_manager::execute_sync(q1.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query enabled rules of uninstalled packages");
+
+ std::vector<Json>::iterator vecEnd = record.end();
+ for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
+ Json elem = *vecPos;
+ int ruleId;
+ elem.get(NULL, "row_id", &ruleId);
+ error = disableRule(ruleId);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rule");
+ }
+ _D("Uninstalled packages' rules are disabled");
+ }
+
+ // Delete rules of uninstalled packages from DB
+ std::string q2 = "DELETE FROM context_trigger_rule WHERE " + pkgList;
+ std::vector<Json> dummy;
+ ret = db_manager::execute_sync(q2.c_str(), &dummy);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to remove rules from db");
+ _D("Uninstalled packages' rules are deleted from db");
+
+ __uninstalledPackages.clear();
+
+ return ERR_NONE;
+}
+
+int RuleManager::pauseRuleWithItem(std::string& subject)
+{
+ std::string q = "SELECT row_id FROM context_trigger_rule WHERE (status=2) AND (details LIKE '%\"ITEM_NAME\":\"" + subject + "\"%');";
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Failed to query row_ids to be paused");
+ IF_FAIL_RETURN(record.size() > 0, ERR_NONE);
+
+ _D("Pause rules related to %s", subject.c_str());
+ std::vector<Json>::iterator vecEnd = record.end();
+ for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
+ Json elem = *vecPos;
+ int rowId;
+ elem.get(NULL, "row_id", &rowId);
+
+ int error = pauseRule(rowId);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to disable rules using custom item");
+ }
+
+ return ERR_NONE;
+}
+
+int RuleManager::resumeRuleWithItem(std::string& subject)
+{
+ std::string q = "SELECT row_id FROM context_trigger_rule WHERE (status=1) AND (details LIKE '%\"ITEM_NAME\":\"" + subject + "\"%');";
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query paused rule ids failed");
+ IF_FAIL_RETURN(record.size() > 0, ERR_NONE);
+
+ _D("Resume rules related to %s", subject.c_str());
+ std::string qRowId;
+ std::vector<Json>::iterator vecEnd = record.end();
+ for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
+ Json elem = *vecPos;
+ int rowId;
+ elem.get(NULL, "row_id", &rowId);
+
+ int error = enableRule(rowId);
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to resume rule");
+ }
+
+ return ERR_NONE;
+}
+
+bool RuleManager::__reenableRule(void)
+{
+ int error;
+ std::string q = "SELECT row_id FROM context_trigger_rule WHERE status = 2";
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Query row_ids of enabled rules failed");
+ IF_FAIL_RETURN_TAG(record.size() > 0, true, _D, "No rule to re-enable");
+
+ _D(YELLOW("Re-enable rule started"));
+
+ std::string qRowId;
+ qRowId.clear();
+ std::vector<Json>::iterator vecEnd = record.end();
+ for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
+ Json elem = *vecPos;
+ int rowId;
+ elem.get(NULL, "row_id", &rowId);
+
+ error = enableRule(rowId);
+ if (error == ERR_NOT_SUPPORTED) {
+ qRowId += "(row_id = " + __intToString(rowId) + ") OR ";
+ } else if (error != ERR_NONE) {
+ _E("Re-enable rule%d failed(%d)", rowId, error);
+ }
+ }
+ IF_FAIL_RETURN(!qRowId.empty(), true);
+ qRowId = qRowId.substr(0, qRowId.length() - 4);
+
+ // For rules which is failed to re-enable
+ std::string qUpdate = "UPDATE context_trigger_rule SET status = 1 WHERE " + qRowId;
+ std::vector<Json> record2;
+ ret = db_manager::execute_sync(qUpdate.c_str(), &record2);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Failed to update rules as paused");
+
+ return true;
+}
+
+bool RuleManager::__ruleDataArrElemEquals(Json& lElem, Json& rElem)
+{
+ std::string lKey, rKey;
+ lElem.get(NULL, CT_RULE_DATA_KEY, &lKey);
+ rElem.get(NULL, CT_RULE_DATA_KEY, &rKey);
+ if (lKey.compare(rKey))
+ return false;
+
+ int lValCnt, rValCnt, lValOpCnt, rValOpCnt;
+ lValCnt = lElem.getSize(NULL, CT_RULE_DATA_VALUE_ARR);
+ rValCnt = rElem.getSize(NULL, CT_RULE_DATA_VALUE_ARR);
+ lValOpCnt = lElem.getSize(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR);
+ rValOpCnt = rElem.getSize(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR);
+ if (!((lValCnt == rValCnt) && (lValCnt == lValOpCnt) && (lValCnt && rValOpCnt)))
+ return false;
+
+ if (lValCnt > 1) {
+ std::string lOp, rOp;
+ lElem.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &lOp);
+ rElem.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &rOp);
+ if (lOp.compare(rOp))
+ return false;
+ }
+
+ for (int i = 0; i < lValCnt; i++) {
+ bool found = false;
+ std::string lVal, lValOp;
+ lElem.getAt(NULL, CT_RULE_DATA_VALUE_ARR, i, &lVal);
+ lElem.getAt(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, i, &lValOp);
+
+ for (int j = 0; j < lValCnt; j++) {
+ std::string rVal, rValOp;
+ rElem.getAt(NULL, CT_RULE_DATA_VALUE_ARR, j, &rVal);
+ rElem.getAt(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, j, &rValOp);
+
+ if (!lVal.compare(rVal) && !lValOp.compare(rValOp)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return false;
+ }
+
+ return true;
+}
+
+bool RuleManager::__ruleItemEquals(Json& lItem, Json& rItem)
+{
+ // Compare item name
+ std::string lItemName, rItemName;
+ lItem.get(NULL, CT_RULE_EVENT_ITEM, &lItemName);
+ rItem.get(NULL, CT_RULE_EVENT_ITEM, &rItemName);
+ if (lItemName.compare(rItemName))
+ return false;
+
+ // Compare option
+ Json lOption, rOption;
+ lItem.get(NULL, CT_RULE_EVENT_OPTION, &lOption);
+ rItem.get(NULL, CT_RULE_EVENT_OPTION, &rOption);
+ if (lOption != rOption)
+ return false;
+
+ int lDataArrCnt, rDataArrCnt;
+ lDataArrCnt = lItem.getSize(NULL, CT_RULE_DATA_ARR);
+ rDataArrCnt = rItem.getSize(NULL, CT_RULE_DATA_ARR);
+ if (lDataArrCnt != rDataArrCnt)
+ return false;
+
+ // Compare item operator;
+ if (lDataArrCnt > 1) {
+ std::string lOp, rOp;
+ lItem.get(NULL, CT_RULE_EVENT_OPERATOR, &lOp);
+ rItem.get(NULL, CT_RULE_EVENT_OPERATOR, &rOp);
+ if (lOp.compare(rOp))
+ return false;
+ }
+
+ for (int i = 0; i < lDataArrCnt; i++) {
+ bool found = false;
+ Json lElem;
+ lItem.getAt(NULL, CT_RULE_DATA_ARR, i, &lElem);
+
+ for (int j = 0; j < lDataArrCnt; j++) {
+ Json rElem;
+ rItem.getAt(NULL, CT_RULE_DATA_ARR, j, &rElem);
+
+ if (__ruleDataArrElemEquals(lElem, rElem)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return false;
+ }
+
+ return true;
+}
+
+bool RuleManager::__ruleEquals(Json& lRule, Json& rRule)
+{
+ // Compare event
+ Json lEvent, rEvent;
+ lRule.get(NULL, CT_RULE_EVENT, &lEvent);
+ rRule.get(NULL, CT_RULE_EVENT, &rEvent);
+ if (!__ruleItemEquals(lEvent, rEvent))
+ return false;
+
+ // Compare conditions
+ int lCondCnt, rCondCnt;
+ lCondCnt = lRule.getSize(NULL, CT_RULE_CONDITION);
+ rCondCnt = rRule.getSize(NULL, CT_RULE_CONDITION);
+ if (lCondCnt != rCondCnt)
+ return false;
+
+ if (lCondCnt > 1) {
+ std::string lOp, rOp;
+ lRule.get(NULL, CT_RULE_OPERATOR, &lOp);
+ rRule.get(NULL, CT_RULE_OPERATOR, &rOp);
+ if (lOp.compare(rOp))
+ return false;
+ }
+
+ for (int i = 0; i < lCondCnt; i++) {
+ bool found = false;
+ Json lCond;
+ lRule.getAt(NULL, CT_RULE_CONDITION, i, &lCond);
+
+ for (int j = 0; j < lCondCnt; j++) {
+ Json rCond;
+ rRule.getAt(NULL, CT_RULE_CONDITION, j, &rCond);
+
+ if (__ruleItemEquals(lCond, rCond)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return false;
+ }
+
+ // Compare action
+ Json lAction, rAction;
+ lRule.get(NULL, CT_RULE_ACTION, &lAction);
+ rRule.get(NULL, CT_RULE_ACTION, &rAction);
+ if (lAction != rAction)
+ return false;
+
+ return true;
+}
+
+int64_t RuleManager::__getDuplicatedRuleId(std::string pkgId, Json& rule)
+{
+ std::string q = "SELECT row_id, description, details FROM context_trigger_rule WHERE package_id = '";
+ q += pkgId;
+ q += "'";
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Query row_id, details by package id failed");
+
+ Json rDetails;
+ rule.get(NULL, CT_RULE_DETAILS, &rDetails);
+ std::string rDesc;
+ rule.get(NULL, CT_RULE_DESCRIPTION, &rDesc);
+ std::vector<Json>::iterator vecEnd = record.end();
+
+ for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
+ Json elem = *vecPos;
+ std::string dStr;
+ Json details;
+
+ elem.get(NULL, "details", &dStr);
+ details = dStr;
+
+ if (__ruleEquals(rDetails, details)) {
+ int64_t rowId;
+ elem.get(NULL, "row_id", &rowId);
+
+ // Description comparison
+ std::string desc;
+ elem.get(NULL, "description", &desc);
+ if (rDesc.compare(desc)) {
+ // Only description is changed
+ std::string qUpdate = "UPDATE context_trigger_rule SET description='" + rDesc + "' WHERE row_id = " + __intToString(rowId);
+
+ std::vector<Json> dummy;
+ ret = db_manager::execute_sync(qUpdate.c_str(), &dummy);
+ if (ret) {
+ _D("Rule%lld description is updated", rowId);
+ } else {
+ _W("Failed to update description of rule%lld", rowId);
+ }
+ }
+
+ return rowId;
+ }
+ }
+
+ return -1;
+}
+
+int RuleManager::__verifyRule(Json& rule, const char* creator)
+{
+ Json details;
+ rule.get(NULL, CT_RULE_DETAILS, &details);
+
+ std::string eventName;
+ rule.get(CT_RULE_DETAILS "." CT_RULE_EVENT, CT_RULE_EVENT_ITEM, &eventName);
+
+ ContextMonitor* ctxMonitor = ContextMonitor::getInstance();
+ IF_FAIL_RETURN_TAG(ctxMonitor, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+ IF_FAIL_RETURN_TAG(ctxMonitor->isSupported(eventName), ERR_NOT_SUPPORTED, _I, "Event(%s) is not supported", eventName.c_str());
+
+ if (creator) {
+ if (!ctxMonitor->isAllowed(creator, eventName.c_str())) {
+ _W("Permission denied for '%s'", eventName.c_str());
+ return ERR_PERMISSION_DENIED;
+ }
+ }
+
+ Json it;
+ for (int i = 0; rule.getAt(CT_RULE_DETAILS, CT_RULE_CONDITION, i, &it); i++) {
+ std::string condName;
+ it.get(NULL, CT_RULE_CONDITION_ITEM, &condName);
+
+ IF_FAIL_RETURN_TAG(ctxMonitor->isSupported(condName), ERR_NOT_SUPPORTED, _I, "Condition(%s) is not supported", condName.c_str());
+
+ if (!ctxMonitor->isAllowed(creator, condName.c_str())) {
+ _W("Permission denied for '%s'", condName.c_str());
+ return ERR_PERMISSION_DENIED;
+ }
+ }
+
+ return ERR_NONE;
+}
+
+int RuleManager::addRule(std::string creator, const char* pkgId, Json rule, Json* ruleId)
+{
+ bool ret;
+ int64_t rid;
+
+ // Check if all items are supported && allowed to access
+ int err = __verifyRule(rule, creator.c_str());
+ IF_FAIL_RETURN(err == ERR_NONE, err);
+
+ // Check if duplicated rule exits
+ if ((rid = __getDuplicatedRuleId(pkgId, rule)) > 0) {
+ // Save rule id
+ ruleId->set(NULL, CT_RULE_ID, rid);
+ _D("Duplicated rule found");
+ return ERR_NONE;
+ }
+
+ // Insert rule to rule table, get rule id
+ Json record;
+ std::string description;
+ Json details;
+ rule.get(NULL, CT_RULE_DESCRIPTION, &description);
+ rule.get(NULL, CT_RULE_DETAILS, &details);
+ record.set(NULL, "creator", creator);
+ if (pkgId) {
+ record.set(NULL, "package_id", pkgId);
+ }
+ record.set(NULL, "description", description);
+
+ // Handle timer event
+ trigger::timer::handleTimerEvent(details);
+
+ record.set(NULL, "details", details.str());
+ ret = db_manager::insert_sync(RULE_TABLE, record, &rid);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Insert rule to db failed");
+
+ // Save rule id
+ ruleId->set(NULL, CT_RULE_ID, rid);
+
+ _D("Add rule%d succeeded", (int)rid);
+ return ERR_NONE;
+}
+
+
+int RuleManager::removeRule(int ruleId)
+{
+ bool ret;
+
+ // Delete rule from DB
+ std::string query = "DELETE FROM 'context_trigger_rule' where row_id = ";
+ query += __intToString(ruleId);
+
+ std::vector<Json> record;
+ ret = db_manager::execute_sync(query.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Remove rule from db failed");
+
+ _D("Remove rule%d succeeded", ruleId);
+
+ return ERR_NONE;
+}
+
+int RuleManager::enableRule(int ruleId)
+{
+ int error;
+ std::string query;
+ std::vector<Json> record;
+ std::vector<Json> dummy;
+ std::string pkgId;
+ Json jRule;
+ std::string tmp;
+ std::string idStr = __intToString(ruleId);
+
+ Rule* rule;
+
+ // Get rule Json by rule id;
+ query = "SELECT details, package_id FROM context_trigger_rule WHERE row_id = ";
+ query += idStr;
+ error = (db_manager::execute_sync(query.c_str(), &record))? ERR_NONE : ERR_OPERATION_FAILED;
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Query rule by rule id failed");
+
+ record[0].get(NULL, "details", &tmp);
+ jRule = tmp;
+ record[0].get(NULL, "package_id", &pkgId);
+
+ // Create a rule instance
+ rule = new(std::nothrow) Rule(ruleId, jRule, pkgId.c_str(), this);
+ IF_FAIL_RETURN_TAG(rule, ERR_OUT_OF_MEMORY, _E, "Failed to create rule instance");
+
+ // Start the rule
+ error = rule->start();
+ IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Failed to start rule%d", ruleId);
+
+ // Update db to set 'enabled'
+ query = "UPDATE context_trigger_rule SET status = 2 WHERE row_id = ";
+ query += idStr;
+ error = (db_manager::execute_sync(query.c_str(), &dummy))? ERR_NONE : ERR_OPERATION_FAILED;
+ IF_FAIL_CATCH_TAG(error == ERR_NONE, _E, "Update db failed");
+
+ // Add rule instance to __ruleMap
+ __ruleMap[ruleId] = rule;
+
+ _D(YELLOW("Enable Rule%d succeeded"), ruleId);
+ return ERR_NONE;
+
+CATCH:
+ delete rule;
+ rule = NULL;
+
+ return error;
+}
+
+int RuleManager::disableRule(int ruleId)
+{
+ bool ret;
+ int error;
+
+ auto it = __ruleMap.find(ruleId);
+ bool paused = (it == __ruleMap.end());
+
+ // For 'enabled' rule, not 'paused'
+ if (!paused) {
+ // Stop the rule
+ Rule* rule = static_cast<Rule*>(it->second);
+ error = rule->stop();
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", ruleId);
+
+ // Remove rule instance from __ruleMap
+ delete rule;
+ __ruleMap.erase(it);
+ }
+
+ // Update db to set 'disabled' // TODO skip while clear uninstalled rule
+ std::string query = "UPDATE context_trigger_rule SET status = 0 WHERE row_id = ";
+ query += __intToString(ruleId);
+ std::vector<Json> record;
+ ret = db_manager::execute_sync(query.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed");
+
+ _D(YELLOW("Disable Rule%d succeeded"), ruleId);
+ return ERR_NONE;
+}
+
+int RuleManager::pauseRule(int ruleId)
+{
+ bool ret;
+ int error;
+
+ auto it = __ruleMap.find(ruleId);
+ IF_FAIL_RETURN_TAG(it != __ruleMap.end(), ERR_OPERATION_FAILED, _E, "Rule instance not found");
+
+ // Stop the rule
+ Rule* rule = static_cast<Rule*>(it->second);
+ error = rule->stop();
+ IF_FAIL_RETURN_TAG(error == ERR_NONE, error, _E, "Failed to stop rule%d", ruleId);
+
+ // Update db to set 'paused'
+ std::string query = "UPDATE context_trigger_rule SET status = 1 WHERE row_id = ";
+
+ query += __intToString(ruleId);
+ std::vector<Json> record;
+ ret = db_manager::execute_sync(query.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Update db failed");
+
+ // Remove rule instance from __ruleMap
+ delete rule;
+ __ruleMap.erase(it);
+
+ _D(YELLOW("Pause Rule%d"), ruleId);
+ return ERR_NONE;
+}
+
+int RuleManager::checkRule(std::string pkgId, int ruleId)
+{
+ // Get package id
+ std::string q = "SELECT package_id FROM context_trigger_rule WHERE row_id =";
+ q += __intToString(ruleId);
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Query package id by rule id failed");
+
+ if (record.size() == 0) {
+ return ERR_NO_DATA;
+ }
+
+ std::string p;
+ record[0].get(NULL, "package_id", &p);
+
+ if (p.compare(pkgId) == 0) {
+ return ERR_NONE;
+ }
+
+ return ERR_NO_DATA;
+}
+
+bool RuleManager::isRuleEnabled(int ruleId)
+{
+ std::string q = "SELECT status FROM context_trigger_rule WHERE row_id =";
+ q += __intToString(ruleId);
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Query enabled by rule id failed");
+
+ int status;
+ record[0].get(NULL, "status", &status);
+
+ return (status != 0);
+}
+
+int RuleManager::getRuleById(std::string pkgId, int ruleId, Json* requestResult)
+{
+ std::string q = "SELECT description FROM context_trigger_rule WHERE (package_id = '";
+ q += pkgId;
+ q += "') and (row_id = ";
+ q += __intToString(ruleId);
+ q += ")";
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Query rule by rule id failed");
+
+ if (record.size() == 0) {
+ return ERR_NO_DATA;
+ } else if (record.size() != 1) {
+ return ERR_OPERATION_FAILED;
+ }
+
+ std::string description;
+ record[0].get(NULL, "description", &description);
+
+ (*requestResult).set(NULL, CT_RULE_ID, ruleId);
+ (*requestResult).set(NULL, CT_RULE_DESCRIPTION, description);
+
+ return ERR_NONE;
+}
+
+int RuleManager::getRuleIds(std::string pkgId, Json* requestResult)
+{
+ (*requestResult) = "{ \"" CT_RULE_ARRAY_ENABLED "\" : [ ] , \"" CT_RULE_ARRAY_DISABLED "\" : [ ] }";
+
+ std::string q = "SELECT row_id, status FROM context_trigger_rule WHERE (package_id = '";
+ q += pkgId;
+ q += "')";
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query rules failed");
+
+ std::vector<Json>::iterator vecEnd = record.end();
+ for (std::vector<Json>::iterator vecPos = record.begin(); vecPos != vecEnd; ++vecPos) {
+ Json elem = *vecPos;
+ std::string id;
+ int status;
+
+ elem.get(NULL, "row_id", &id);
+ elem.get(NULL, "status", &status);
+
+ if (status >= 1) {
+ (*requestResult).append(NULL, CT_RULE_ARRAY_ENABLED, __stringToInt(id));
+ } else if (status == 0) {
+ (*requestResult).append(NULL, CT_RULE_ARRAY_DISABLED, __stringToInt(id));
+ }
+ }
+
+ return ERR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_RULE_MANAGER_H_
+#define _CONTEXT_TRIGGER_RULE_MANAGER_H_
+
+#include <set>
+#include <map>
+
+namespace ctx {
+
+ class Json;
+
+namespace trigger {
+
+ class Trigger;
+ class Rule;
+
+ class RuleManager {
+ public:
+ RuleManager();
+ ~RuleManager();
+
+ bool init();
+ int addRule(std::string creator, const char* pkgId, Json rule, Json* ruleId);
+ int removeRule(int ruleId);
+ int enableRule(int ruleId);
+ int disableRule(int ruleId);
+ int getRuleById(std::string pkgId, int ruleId, Json* requestResult);
+ int getRuleIds(std::string pkgId, Json* requestResult);
+ int checkRule(std::string pkgId, int ruleId);
+ bool isRuleEnabled(int ruleId);
+ int pauseRuleWithItem(std::string& subject);
+ int pauseRule(int ruleId);
+ int resumeRuleWithItem(std::string& subject);
+ void handleRuleOfUninstalledPackage(std::string pkgId);
+
+ static bool isUninstalledPackage(std::string pkgId);
+
+ private:
+ bool __reenableRule(void);
+ int __verifyRule(Json& rule, const char* creator);
+ int64_t __getDuplicatedRuleId(std::string pkgId, Json& rule);
+ bool __ruleDataArrElemEquals(Json& lElem, Json& rElem);
+ bool __ruleItemEquals(Json& lItem, Json& rItem);
+ bool __ruleEquals(Json& lRule, Json& rRule);
+ int __getUninstalledApp(void);
+ int __clearRuleOfUninstalledPackage(bool isInit = false);
+ void __applyTemplates(void);
+
+ std::set<std::string> __uninstalledPackages;
+
+ std::map<int, Rule*> __ruleMap;
+ }; /* class RuleManager */
+
+} /* namespace trigger */
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_TRIGGER_RULE_MANAGER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <sstream>
+#include <types_internal.h>
+#include <context_trigger_types_internal.h>
+#include <db_mgr.h>
+#include "../context_mgr_impl.h"
+#include "RuleManager.h"
+#include "TemplateManager.h"
+
+using namespace ctx;
+using namespace ctx::trigger;
+
+TemplateManager *TemplateManager::__instance = NULL;
+context_manager_impl *TemplateManager::__contextMgr = NULL;
+RuleManager *TemplateManager::__ruleMgr = NULL;
+
+static std::string __intToString(int i)
+{
+ std::ostringstream convert;
+ convert << i;
+ std::string str = convert.str();
+ return str;
+}
+
+TemplateManager::TemplateManager()
+{
+}
+
+TemplateManager::~TemplateManager()
+{
+}
+
+void TemplateManager::setManager(context_manager_impl* ctxMgr, RuleManager* ruleMgr)
+{
+ __contextMgr = ctxMgr;
+ __ruleMgr = ruleMgr;
+}
+
+TemplateManager* TemplateManager::getInstance()
+{
+ IF_FAIL_RETURN_TAG(__contextMgr, NULL, _E, "Context manager is needed");
+ IF_FAIL_RETURN_TAG(__ruleMgr, NULL, _E, "Rule manager is needed");
+
+ IF_FAIL_RETURN(!__instance, __instance);
+
+ __instance = new(std::nothrow) TemplateManager();
+ IF_FAIL_RETURN_TAG(__instance, NULL, _E, "Memory alllocation failed");
+
+ return __instance;
+}
+
+void TemplateManager::destroy()
+{
+ __instance->applyTemplates();
+
+ if (__instance) {
+ delete __instance;
+ __instance = NULL;
+ }
+}
+
+bool TemplateManager::init()
+{
+ std::string q = std::string("CREATE TABLE IF NOT EXISTS context_trigger_template ")
+ + "(name TEXT DEFAULT '' NOT NULL PRIMARY KEY, operation INTEGER DEFAULT 3 NOT NULL, "
+ + "attributes TEXT DEFAULT '' NOT NULL, options TEXT DEFAULT '' NOT NULL, owner TEXT DEFAULT '' NOT NULL)";
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, false, _E, "Create template table failed");
+
+ // Apply templates
+ applyTemplates();
+
+ return true;
+}
+
+void TemplateManager::applyTemplates()
+{
+ std::string subject;
+ int operation;
+ Json attributes;
+ Json options;
+ std::string owner;
+ bool unregister;
+ std::string query;
+ query.clear();
+
+ while(__contextMgr->pop_trigger_item(subject, operation, attributes, options, owner, unregister)) {
+ if (unregister) {
+ unregisterTemplate(subject);
+ } else {
+ registerTemplate(subject, operation, attributes, options, owner);
+ }
+ }
+}
+
+void TemplateManager::registerTemplate(std::string subject, int operation, Json attributes, Json options, std::string owner)
+{
+ _D("[Add template] Subject: %s, Ops: %d, Owner: %s", subject.c_str(), operation, owner.c_str());
+ _J("Attr", attributes);
+ _J("Opt", options);
+
+ std::string query = "UPDATE context_trigger_template SET operation=" + __intToString(operation)
+ + ", attributes='" + attributes.str() + "', options='" + options.str() + "', owner='" + owner
+ + "' WHERE name='" + subject + "'; ";
+
+ query += "INSERT OR IGNORE INTO context_trigger_template (name, operation, attributes, options, owner) VALUES ('"
+ + subject + "', " + __intToString(operation) + ", '" + attributes.str() + "', '" + options.str() + "', '"
+ + owner + "'); ";
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(query.c_str(), &record);
+ IF_FAIL_VOID_TAG(ret, _E, "Update template db failed");
+
+ if (!owner.empty()) {
+ __ruleMgr->resumeRuleWithItem(subject);
+ }
+}
+
+void TemplateManager::unregisterTemplate(std::string subject)
+{
+ _D("[Remove template] Subject: %s", subject.c_str());
+ std::string query = "DELETE FROM context_trigger_template WHERE name = '" + subject + "'; ";
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(query.c_str(), &record);
+ IF_FAIL_VOID_TAG(ret, _E, "Update template db failed");
+
+ __ruleMgr->pauseRuleWithItem(subject);
+}
+
+
+std::string TemplateManager::__addTemplate(std::string &subject, int &operation, Json &attributes, Json &options, std::string &owner)
+{
+ _D("[Add template] Subject: %s, Ops: %d, Owner: %s", subject.c_str(), operation, owner.c_str());
+ _J("Attr", attributes);
+ _J("Opt", options);
+
+ std::string query = "UPDATE context_trigger_template SET operation=" + __intToString(operation)
+ + ", attributes='" + attributes.str() + "', options='" + options.str() + "', owner='" + owner
+ + "' WHERE name='" + subject + "'; ";
+
+ query += "INSERT OR IGNORE INTO context_trigger_template (name, operation, attributes, options, owner) VALUES ('"
+ + subject + "', " + __intToString(operation) + ", '" + attributes.str() + "', '" + options.str() + "', '"
+ + owner + "'); ";
+
+ return query;
+}
+
+std::string TemplateManager::__removeTemplate(std::string &subject)
+{
+ _D("[Remove template] Subject: %s", subject.c_str());
+ std::string query = "DELETE FROM context_trigger_template WHERE name = '" + subject + "'; ";
+
+ return query;
+}
+
+int TemplateManager::getTemplate(std::string &subject, Json* tmpl)
+{
+ // Update latest template information
+ std::string q = "SELECT * FROM context_trigger_template WHERE name = '" + subject + "'";
+
+ std::vector<Json> record;
+ bool ret = db_manager::execute_sync(q.c_str(), &record);
+ IF_FAIL_RETURN_TAG(ret, ERR_OPERATION_FAILED, _E, "Query template failed");
+ IF_FAIL_RETURN_TAG(record.size() > 0, ERR_NOT_SUPPORTED, _E, "Template(%s) not found", subject.c_str());
+ IF_FAIL_RETURN_TAG(record.size() == 1, ERR_OPERATION_FAILED, _E, "Tepmlate duplicated");
+
+ (*tmpl) = *record.begin();
+
+ std::string optStr;
+ std::string attrStr;
+ tmpl->get(NULL, TYPE_OPTION_STR, &optStr);
+ tmpl->get(NULL, TYPE_ATTR_STR, &attrStr);
+
+ Json opt = optStr;
+ Json attr = attrStr;
+
+ tmpl->set(NULL, TYPE_OPTION_STR, opt);
+ tmpl->set(NULL, TYPE_ATTR_STR, attr);
+
+ return ERR_NONE;
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_TEMPLATE_MANAGER_H_
+#define _CONTEXT_TRIGGER_TEMPLATE_MANAGER_H_
+
+#include <Json.h>
+
+namespace ctx {
+
+ class context_manager_impl;
+
+namespace trigger {
+
+ class RuleManager;
+
+ class TemplateManager {
+ public:
+ static TemplateManager* getInstance();
+ static void setManager(context_manager_impl* ctxMgr, RuleManager* ruleMgr);
+ static void destroy();
+
+ bool init();
+ void applyTemplates();
+ int getTemplate(std::string &subject, Json* tmpl);
+ void registerTemplate(std::string subject, int operation, Json attributes, Json options, std::string owner);
+ void unregisterTemplate(std::string subject);
+
+ private:
+ TemplateManager();
+ TemplateManager(const TemplateManager& other);
+ ~TemplateManager();
+
+ static TemplateManager *__instance;
+ static context_manager_impl *__contextMgr;
+ static RuleManager *__ruleMgr;
+
+ std::string __addTemplate(std::string &subject, int &operation, Json &attributes, Json &options, std::string &owner);
+ std::string __removeTemplate(std::string &subject);
+
+ }; /* class TemplateManager */
+
+} /* namespace trigger */
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_TRIGGER_TEMPLATE_MANAGER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <context_trigger.h>
+#include <context_trigger_types_internal.h>
+#include <types_internal.h>
+#include <TimerManager.h>
+#include "Timer.h"
+
+#define TIMER_DAY_OF_WEEK "DayOfWeek"
+#define TIMER_TIME_OF_DAY "TimeOfDay"
+
+using namespace ctx;
+using namespace ctx::trigger;
+
+static int __arrangeDayOfWeek(Json dayInfo)
+{
+ int result = 0;
+
+ std::string key_op;
+ if (!dayInfo.get(NULL, CT_RULE_DATA_KEY_OPERATOR, &key_op)) {
+ result = TimerManager::dowToInt(DOW_EVERYDAY);
+ return result;
+ }
+
+ if (key_op.compare("and") == 0) {
+ result = TimerManager::dowToInt(DOW_EVERYDAY);
+ }
+
+ std::string tmp_d;
+ for (int i = 0; dayInfo.getAt(NULL, CT_RULE_DATA_VALUE_ARR, i, &tmp_d); i++) {
+ int dow = TimerManager::dowToInt(tmp_d);
+ std::string op;
+ dayInfo.getAt(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, i, &op);
+
+ if (op.compare(CONTEXT_TRIGGER_NOT_EQUAL_TO) == 0) {
+ dow = TimerManager::dowToInt(DOW_EVERYDAY) & ~dow;
+ }
+
+ if (key_op.compare("and") == 0) {
+ result &= dow;
+ } else {
+ result |= dow;
+ }
+ }
+ _D("Requested day of week (%#x)", result);
+
+ return result;
+}
+
+void timer::handleTimerEvent(Json& rule)
+{
+ Json event;
+ rule.get(NULL, CT_RULE_EVENT, &event);
+
+ std::string eventName;
+ event.get(NULL, CT_RULE_EVENT_ITEM, &eventName);
+ if (eventName.compare(CT_EVENT_TIME) != 0) {
+ return;
+ }
+
+ Json dayInfo;
+ Json it;
+ int dow;
+ for (int i = 0; event.getAt(NULL, CT_RULE_DATA_ARR, i, &it); i++) {
+ std::string key;
+ it.get(NULL, CT_RULE_DATA_KEY, &key);
+
+ if (key.compare(TIMER_DAY_OF_WEEK) == 0) {
+ dow = __arrangeDayOfWeek(it);
+
+ dayInfo.set(NULL, CT_RULE_DATA_KEY, TIMER_DAY_OF_WEEK);
+ dayInfo.set(NULL, CT_RULE_DATA_KEY_OPERATOR, "or");
+
+ for (int j = 0; j < DAYS_PER_WEEK; j++) {
+ int d = 0x01 << j;
+ if (dow & d) {
+ std::string day = TimerManager::dowToStr(d);
+ dayInfo.append(NULL, CT_RULE_DATA_VALUE_ARR, day);
+ dayInfo.append(NULL, CT_RULE_DATA_VALUE_OPERATOR_ARR, CONTEXT_TRIGGER_EQUAL_TO);
+
+ // Set option
+ event.append(CT_RULE_EVENT_OPTION, TIMER_DAY_OF_WEEK, day);
+ }
+ }
+ event.setAt(NULL, CT_RULE_DATA_ARR, i, dayInfo);
+ } else if (key.compare(TIMER_TIME_OF_DAY) == 0) {
+ int time;
+ for (int j = 0; it.getAt(NULL, CT_RULE_DATA_VALUE_ARR, j, &time); j++) {
+ event.append(CT_RULE_EVENT_OPTION, TIMER_TIME_OF_DAY, time);
+ }
+ }
+ }
+
+ rule.set(NULL, CT_RULE_EVENT, event);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_TIMER_H_
+#define _CONTEXT_TRIGGER_TIMER_H_
+
+#include <Json.h>
+
+namespace ctx {
+namespace trigger {
+ namespace timer {
+
+ void handleTimerEvent(ctx::Json& rule);
+
+ } /* namespace timer */
+
+} /* namespace trigger */
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_TRIGGER_TIMER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <types_internal.h>
+#include <context_trigger_types_internal.h>
+#include "Trigger.h"
+#include "ContextMonitor.h"
+#include "TemplateManager.h"
+#include "RuleManager.h"
+
+using namespace ctx;
+using namespace ctx::trigger;
+
+Trigger::Trigger() :
+ __ruleMgr(NULL)
+{
+}
+
+Trigger::~Trigger()
+{
+}
+
+bool Trigger::init(context_manager_impl* ctxMgr)
+{
+ // Do the necessary initialization process.
+ // This function is called from the main thread during the service launching process.
+ _D("Context Trigger Init");
+ __processInitialize(ctxMgr);
+
+ return true;
+}
+
+void Trigger::release()
+{
+ // Release the occupied resources.
+ // This function is called from the main thread during the service termination process.
+
+ _D("Template Manager Destroy");
+ TemplateManager::destroy();
+
+ _D("Rule Manager Release");
+ delete __ruleMgr;
+ __ruleMgr = NULL;
+
+ _D("Context Monitor Destroy");
+ ContextMonitor::destroy();
+}
+
+bool Trigger::assignRequest(RequestInfo* request)
+{
+ std::string subject = request->getSubject();
+ if (subject != CONTEXT_TRIGGER_SUBJECT_ADD && subject != CONTEXT_TRIGGER_SUBJECT_REMOVE &&
+ subject != CONTEXT_TRIGGER_SUBJECT_ENABLE && subject != CONTEXT_TRIGGER_SUBJECT_DISABLE &&
+ subject != CONTEXT_TRIGGER_SUBJECT_GET && subject != CONTEXT_TRIGGER_SUBJECT_GET_RULE_IDS &&
+ subject != CONTEXT_TRIGGER_SUBJECT_GET_TEMPLATE) {
+ return false;
+ }
+
+ __processRequest(request);
+ return true;
+}
+
+void Trigger::__processRequest(RequestInfo* request)
+{
+ // Process the request, and reply to the client if necessary.
+ const char* reqSubj = request->getSubject();
+ _D("Request is %s", reqSubj);
+ std::string subject(reqSubj);
+
+ if (subject == CONTEXT_TRIGGER_SUBJECT_ADD) {
+ __addRule(request);
+ } else if (subject == CONTEXT_TRIGGER_SUBJECT_REMOVE) {
+ __removeRule(request);
+ } else if (subject == CONTEXT_TRIGGER_SUBJECT_ENABLE) {
+ __enableRule(request);
+ } else if (subject == CONTEXT_TRIGGER_SUBJECT_DISABLE) {
+ __disableRule(request);
+ } else if (subject == CONTEXT_TRIGGER_SUBJECT_GET) {
+ __getRuleById(request);
+ } else if (subject == CONTEXT_TRIGGER_SUBJECT_GET_RULE_IDS) {
+ __getRuleIds(request);
+ } else if (subject == CONTEXT_TRIGGER_SUBJECT_GET_TEMPLATE) {
+ __getTemplate(request);
+ } else {
+ _E("Invalid request");
+ }
+}
+
+void Trigger::__processInitialize(context_manager_impl* mgr)
+{
+ // Context Monitor
+ ContextMonitor::setContextManager(mgr);
+
+ // Rule Manager
+ __ruleMgr = new(std::nothrow) RuleManager();
+ IF_FAIL_VOID_TAG(__ruleMgr, _E, "Memory allocation failed");
+
+ // Template Manager
+ TemplateManager::setManager(mgr, __ruleMgr);
+ TemplateManager* tmplMgr = TemplateManager::getInstance();
+ IF_FAIL_VOID_TAG(tmplMgr, _E, "Memory allocation failed");
+
+ // Initialization
+ if (!tmplMgr->init()) {
+ _E("Template manager initialization failed");
+ raise(SIGTERM);
+ }
+
+ if (!__ruleMgr->init()) {
+ _E("Context trigger initialization failed");
+ raise(SIGTERM);
+ }
+}
+
+void Trigger::__addRule(RequestInfo* request)
+{
+ Json ruleId;
+
+ const char* client = request->getClient();
+ if (client == NULL) {
+ request->reply(ERR_OPERATION_FAILED);
+ return;
+ }
+
+ const char* pkgId = request->getPackageId();
+
+ int error = __ruleMgr->addRule(client, pkgId, request->getDescription(), &ruleId);
+ _I("'%s' adds a rule (Error: %#x)", request->getClient(), error);
+
+ request->reply(error, ruleId);
+}
+
+void Trigger::__removeRule(RequestInfo* request)
+{
+ int id;
+ int error;
+
+ const char* pkgId = request->getPackageId();
+
+ Json ruleId = request->getDescription();
+ ruleId.get(NULL, CT_RULE_ID, &id);
+
+ error = __ruleMgr->checkRule((pkgId)? pkgId : "", id);
+ if (error != ERR_NONE) {
+ request->reply(error);
+ return;
+ }
+
+ bool ret = __ruleMgr->isRuleEnabled(id);
+ if (ret) {
+ request->reply(ERR_RULE_ENABLED);
+ return;
+ }
+
+ error = __ruleMgr->removeRule(id);
+ _I("'%s' removes rule%d (Error: %#x)", request->getClient(), id, error);
+ request->reply(error);
+}
+
+void Trigger::__enableRule(RequestInfo* request)
+{
+ int id;
+ int error;
+
+ const char* pkgId = request->getPackageId();
+
+ Json ruleId = request->getDescription();
+ ruleId.get(NULL, CT_RULE_ID, &id);
+
+ error = __ruleMgr->checkRule((pkgId)? pkgId : "", id);
+ if (error != ERR_NONE) {
+ request->reply(error);
+ return;
+ }
+
+ bool ret = __ruleMgr->isRuleEnabled(id);
+ if (ret) {
+ request->reply(ERR_RULE_ENABLED);
+ return;
+ }
+
+ error = __ruleMgr->enableRule(id);
+ _I("'%s' enables rule%d (Error: %#x)", request->getClient(), id, error);
+ request->reply(error);
+}
+
+void Trigger::__disableRule(RequestInfo* request)
+{
+ int id;
+ int error;
+
+ const char* pkgId = request->getPackageId();
+
+ Json ruleId = request->getDescription();
+ ruleId.get(NULL, CT_RULE_ID, &id);
+
+ error = __ruleMgr->checkRule((pkgId)? pkgId : "", id);
+ if (error != ERR_NONE) {
+ request->reply(error);
+ return;
+ }
+
+ bool ret = __ruleMgr->isRuleEnabled(id);
+ if (!ret) {
+ request->reply(ERR_RULE_NOT_ENABLED);
+ return;
+ }
+
+ error = __ruleMgr->disableRule(id);
+ _I("'%s' disables rule%d (Error: %#x)", request->getClient(), id, error);
+ request->reply(error);
+}
+
+void Trigger::__getRuleById(RequestInfo* request)
+{
+ int error;
+
+ Json option = request->getDescription();
+ int id;
+ option.get(NULL, CT_RULE_ID, &id);
+
+ const char* pkgId = request->getPackageId();
+
+ Json readData;
+ error = __ruleMgr->getRuleById((pkgId)? pkgId : "", id, &readData);
+
+ Json dummy;
+ request->reply(error, dummy, readData);
+}
+
+void Trigger::__getRuleIds(RequestInfo* request)
+{
+ int error;
+
+ const char* pkgId = request->getPackageId();
+
+ Json readData;
+ error = __ruleMgr->getRuleIds((pkgId)? pkgId : "", &readData);
+
+ Json dummy;
+ request->reply(error, dummy, readData);
+}
+
+void Trigger::__getTemplate(RequestInfo* request)
+{
+ int error;
+
+ Json option = request->getDescription();
+ std::string name;
+ option.get(NULL, SUBJECT_STR, &name);
+
+ TemplateManager* tmplMgr = TemplateManager::getInstance();
+ if (!tmplMgr) {
+ _E("Memory allocation failed");
+ request->reply(ERR_OUT_OF_MEMORY);
+ return;
+ }
+
+ Json tmpl;
+ error = tmplMgr->getTemplate(name, &tmpl);
+
+ Json dummy;
+ request->reply(error, dummy, tmpl);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 _CONTEXT_TRIGGER_TRIGGER_H_
+#define _CONTEXT_TRIGGER_TRIGGER_H_
+
+#include "../Request.h"
+
+namespace ctx {
+
+ class client_request;
+ class context_manager_impl;
+
+namespace trigger {
+
+ class RuleManager;
+
+ class Trigger {
+ public:
+ Trigger();
+ ~Trigger();
+
+ bool init(context_manager_impl* ctxMgr);
+ void release();
+
+ bool assignRequest(RequestInfo* request);
+
+ private:
+ void __processRequest(RequestInfo* request);
+ void __processInitialize(context_manager_impl* mgr);
+
+ void __addRule(RequestInfo* request);
+ void __removeRule(RequestInfo* request);
+ void __enableRule(RequestInfo* request);
+ void __disableRule(RequestInfo* request);
+ void __getRuleById(RequestInfo* request);
+ void __getRuleIds(RequestInfo* request);
+ void __getTemplate(RequestInfo* request);
+
+ RuleManager* __ruleMgr;
+ };
+
+} /* namespace trigger */
+} /* namespace ctx */
+
+#endif /* End of _CONTEXT_TRIGGER_TRIGGER_H_ */