diff options
-rw-r--r-- | src/app.cpp | 19 | ||||
-rw-r--r-- | src/policy_manager/policy_manager.cpp | 233 | ||||
-rw-r--r-- | src/policy_manager/policy_manager.hpp | 14 |
3 files changed, 180 insertions, 86 deletions
diff --git a/src/app.cpp b/src/app.cpp index 0d727b6..a117848 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -338,7 +338,6 @@ void App::allocateWindowResource(char const *event, char const *drawing_name, // Check Policy json_object* json_in = json_object_new_object(); - json_object* json_out = json_object_new_object(); json_object_object_add(json_in, "event", json_object_new_string(event)); if (nullptr != new_role) { @@ -348,17 +347,10 @@ void App::allocateWindowResource(char const *event, char const *drawing_name, json_object_object_add(json_in, "area", json_object_new_string(new_area)); } - int ret = this->pm_.checkPolicy(json_in, &json_out); - if (0 > ret) { - reply("Error checkPolicy()"); - return; - } - else { - HMI_DEBUG("wm", "result: %s", json_object_get_string(json_out)); - } - - // Release json_object - json_object_put(json_in); + // Input event to PolicyManager + this->pm_.inputEvent(json_in, + [this, new_role, reply] (json_object* json_out) { + HMI_DEBUG("wm", "role:%s", new_role); // Check parking brake state json_object* json_parking_brake; @@ -517,9 +509,10 @@ void App::allocateWindowResource(char const *event, char const *drawing_name, else { HMI_DEBUG("wm", "All layer is NOT changed!!"); } +}); // Release json_object - json_object_put(json_out); + json_object_put(json_in); return; } diff --git a/src/policy_manager/policy_manager.cpp b/src/policy_manager/policy_manager.cpp index 648c681..351c7ce 100644 --- a/src/policy_manager/policy_manager.cpp +++ b/src/policy_manager/policy_manager.cpp @@ -18,6 +18,8 @@ #include <fstream> #include <sstream> #include <istream> +#include <thread> +#include <systemd/sd-event.h> #include <json-c/json.h> #include "policy_manager.hpp" #include "hmi-debug.h" @@ -29,6 +31,19 @@ extern "C" { } // namespace stm +namespace pm { +struct EventData { + explicit EventData(int event, PolicyManager::Handler handler) { + this->event = event; + this->handler = handler; + }; + ~EventData() = default; + + int event; + PolicyManager::Handler handler; +}; +} // namespace pm + PolicyManager::PolicyManager() : eventname2no_(), categoryname2no_(), @@ -62,7 +77,7 @@ int PolicyManager::initialize() { } // Load role.db - ret = loadRoleDb(); + ret = this->loadRoleDb(); if (0 > ret) { HMI_ERROR("wm:pm", "Load role.db Error!!"); return ret; @@ -71,65 +86,66 @@ int PolicyManager::initialize() { // Initialize StateTransitioner stm::stmInitialize(); + // Initialize sd_event loop + ret = this->initializeSdEventLoop(); + if (0 > ret) { + HMI_ERROR("wm:pm", "Failed to initializeSdEventLoop!!"); + return ret; + } + return ret; } -int PolicyManager::checkPolicy(json_object* json_in, json_object** json_out) { - HMI_DEBUG("wm:pm", "Call"); - - // Check arguments - if ((nullptr == json_in) || (nullptr == json_out)) { - HMI_ERROR("wm:pm", "Argument is NULL!!"); +int PolicyManager::initializeSdEventLoop() { + // Get default event loop object + int ret = sd_event_new(&(this->sd_event_)); + if (0 > ret) { + HMI_ERROR("wm:pm", "Faild to sd_event_default: errno:%d", ret); return -1; } - // Get event from json_object - const char* event = this->getStringFromJson(json_in, "event"); - int event_no = 0; - if (nullptr != event) { - // Convert name to number - event_no = this->eventname2no_[event]; - HMI_DEBUG("wm:pm", "event(%s:%d)", event, event_no); - } - - // Get role from json_object - const char* role = this->getStringFromJson(json_in, "role"); - int category_no = 0; - if (nullptr != role) { - HMI_DEBUG("wm:pm", "role(%s)", role); - - // Convert role to category - const char* category = this->role2category_[role].c_str(); - if (0 == strcmp("", category)) { - HMI_ERROR("wm:pm", "Error!!"); - return -1; + // Create thread for sd_event and detach + std::thread sd_event_loop([this]() { + while (1) { + sd_event_run(this->sd_event_, 1000); } - HMI_DEBUG("wm:pm", "category(%s)", category); + }); + sd_event_loop.detach(); - // Convert name to number - category_no = categoryname2no_[category]; - HMI_DEBUG("wm:pm", "role(%s), category(%s:%d)", role, category, category_no); + return 0; +} + +static void addStateToJson( + const char* key, int is_changed, const char* state, json_object** json_out) { + if ((nullptr == key) || (nullptr == state) || (nullptr == json_out)) { + HMI_ERROR("wm:pm", "Argument is nullptr!!!"); + return; } - // Get areat from json_object - const char* area = this->getStringFromJson(json_in, "area"); - int area_no = 0; - if (nullptr != area) { - // Convert name to number - area_no = areaname2no_[area]; - HMI_DEBUG("wm:pm", "area(%s:%d)", area, area_no); + json_object* json_obj = json_object_new_object(); + json_object_object_add(json_obj, "is_changed", json_object_new_boolean(is_changed)); + if (is_changed) { + HMI_DEBUG("wm:pm", "%s: state changed (%s)", key, state); + json_object_object_add(json_obj, "state", json_object_new_string(state)); } + json_object_object_add(*json_out, key, json_obj); +} - HMI_DEBUG("wm:pm", "set event:0x%x", (event_no | category_no | area_no)); +static int checkPolicy(sd_event_source *source, uint64_t usec, void *data) { + HMI_DEBUG("wm:pm", "Call"); + + pm::EventData *event_data = (pm::EventData*)data; // Transition state stm::stm_state_t crr_state; - int ret = stm::stmTransitionState((event_no | category_no | area_no), &crr_state); + int ret = stm::stmTransitionState(event_data->event, &crr_state); if (0 > ret) { HMI_ERROR("wm:pm", "Error!!"); return -1; } + json_object* json_out = json_object_new_object(); + // Create result // { // "parking_brake": { @@ -140,10 +156,10 @@ int PolicyManager::checkPolicy(json_object* json_in, json_object** json_out) { crr_state.parking_brake.is_changed, crr_state.parking_brake.state, stm::gStmParkingBrakeStateNo2Name[crr_state.parking_brake.state]); - this->addStateToJson("parking_brake", + addStateToJson("parking_brake", crr_state.parking_brake.is_changed, stm::gStmParkingBrakeStateNo2Name[crr_state.parking_brake.state], - json_out); + &json_out); // "accel_pedal": { // "is_changed": <bool>, @@ -153,10 +169,10 @@ int PolicyManager::checkPolicy(json_object* json_in, json_object** json_out) { crr_state.accel_pedal.is_changed, crr_state.accel_pedal.state, stm::gStmAccelPedalStateNo2Name[crr_state.accel_pedal.state]); - this->addStateToJson("accel_pedal", + addStateToJson("accel_pedal", crr_state.accel_pedal.is_changed, stm::gStmAccelPedalStateNo2Name[crr_state.accel_pedal.state], - json_out); + &json_out); // "lightstatus_brake": { // "is_changed": <bool>, @@ -166,10 +182,10 @@ int PolicyManager::checkPolicy(json_object* json_in, json_object** json_out) { crr_state.lightstatus_brake.is_changed, crr_state.lightstatus_brake.state, stm::gStmLightstatusBrakeStateNo2Name[crr_state.lightstatus_brake.state]); - this->addStateToJson("lightstatus_brake", + addStateToJson("lightstatus_brake", crr_state.lightstatus_brake.is_changed, stm::gStmLightstatusBrakeStateNo2Name[crr_state.lightstatus_brake.state], - json_out); + &json_out); // "car": { // "is_changed": <bool>, @@ -179,10 +195,10 @@ int PolicyManager::checkPolicy(json_object* json_in, json_object** json_out) { crr_state.car.is_changed, crr_state.car.state, stm::gStmCarStateNo2Name[crr_state.car.state]); - this->addStateToJson("car", + addStateToJson("car", crr_state.car.is_changed, stm::gStmCarStateNo2Name[crr_state.car.state], - json_out); + &json_out); // "lamp": { // "is_changed": <bool>, @@ -192,10 +208,10 @@ int PolicyManager::checkPolicy(json_object* json_in, json_object** json_out) { crr_state.lamp.is_changed, crr_state.lamp.state, stm::gStmLampStateNo2Name[crr_state.lamp.state]); - this->addStateToJson("lamp", + addStateToJson("lamp", crr_state.lamp.is_changed, stm::gStmLampStateNo2Name[crr_state.lamp.state], - json_out); + &json_out); // "layers": [ json_object* json_layer = json_object_new_array(); @@ -214,7 +230,7 @@ int PolicyManager::checkPolicy(json_object* json_in, json_object** json_out) { crr_state.layer.homescreen.state, stm::gStmLayoutNo2Name[crr_state.layer.homescreen.state]); json_tmp = json_object_new_object(); - this->addStateToJson("homescreen", + addStateToJson("homescreen", crr_state.layer.homescreen.is_changed, stm::gStmLayoutNo2Name[crr_state.layer.homescreen.state], &json_tmp); @@ -231,7 +247,7 @@ int PolicyManager::checkPolicy(json_object* json_in, json_object** json_out) { crr_state.layer.apps.state, stm::gStmLayoutNo2Name[crr_state.layer.apps.state]); json_tmp = json_object_new_object(); - this->addStateToJson("apps", + addStateToJson("apps", crr_state.layer.apps.is_changed, stm::gStmLayoutNo2Name[crr_state.layer.apps.state], &json_tmp); @@ -248,7 +264,7 @@ int PolicyManager::checkPolicy(json_object* json_in, json_object** json_out) { crr_state.layer.restriction.state, stm::gStmLayoutNo2Name[crr_state.layer.restriction.state]); json_tmp = json_object_new_object(); - this->addStateToJson("restriction", + addStateToJson("restriction", crr_state.layer.restriction.is_changed, stm::gStmLayoutNo2Name[crr_state.layer.restriction.state], &json_tmp); @@ -265,14 +281,105 @@ int PolicyManager::checkPolicy(json_object* json_in, json_object** json_out) { crr_state.layer.on_screen.state, stm::gStmLayoutNo2Name[crr_state.layer.on_screen.state]); json_tmp = json_object_new_object(); - this->addStateToJson("on_screen", + addStateToJson("on_screen", crr_state.layer.on_screen.is_changed, stm::gStmLayoutNo2Name[crr_state.layer.on_screen.state], &json_tmp); json_object_array_add(json_layer, json_tmp); // Add json array of layer - json_object_object_add(*json_out, "layers", json_layer); + json_object_object_add(json_out, "layers", json_layer); + + // Call event handler + event_data->handler(json_out); + + // Release json_object + json_object_put(json_out); + + // Release data + delete (pm::EventData*)data; + + // Destroy sd_event_soutce object + sd_event_source_unref(source); + + return 0; +} + +void PolicyManager::checkPolicyEntry(int event, int delay_ms, PolicyManager::Handler handler) +{ + HMI_DEBUG("wm:pm", "Call"); + + // Create event data + pm::EventData *event_data = new pm::EventData(event, handler); + + // Get current time + struct timespec time_spec; + clock_gettime(CLOCK_MONOTONIC, &time_spec); + + // Calculate timer fired time + uint64_t usec = (time_spec.tv_sec * 1000000) + + (time_spec.tv_nsec / 1000) + + (delay_ms * 1000); + + // Set timer + int ret = sd_event_add_time(this->sd_event_, NULL, CLOCK_MONOTONIC, usec, 1, + &checkPolicy, event_data); + if (0 > ret) { + HMI_ERROR("wm:pm", "Faild to sd_event_add_time: errno:%d", ret); + return; + } +} + +int PolicyManager::inputEvent(json_object* json_in, PolicyManager::Handler notify_state) { + HMI_DEBUG("wm:pm", "Call"); + + // Check arguments + if (nullptr == json_in) { + HMI_ERROR("wm:pm", "Argument is NULL!!"); + return -1; + } + + // Get event from json_object + const char* event = this->getStringFromJson(json_in, "event"); + int event_no = 0; + if (nullptr != event) { + // Convert name to number + event_no = this->eventname2no_[event]; + HMI_DEBUG("wm:pm", "event(%s:%d)", event, event_no); + } + + // Get role from json_object + const char* role = this->getStringFromJson(json_in, "role"); + int category_no = 0; + if (nullptr != role) { + HMI_DEBUG("wm:pm", "role(%s)", role); + + // Convert role to category + const char* category = this->role2category_[role].c_str(); + if (0 == strcmp("", category)) { + HMI_ERROR("wm:pm", "Error!!"); + return -1; + } + HMI_DEBUG("wm:pm", "category(%s)", category); + + // Convert name to number + category_no = categoryname2no_[category]; + HMI_DEBUG("wm:pm", "role(%s), category(%s:%d)", role, category, category_no); + } + + // Get areat from json_object + const char* area = this->getStringFromJson(json_in, "area"); + int area_no = 0; + if (nullptr != area) { + // Convert name to number + area_no = areaname2no_[area]; + HMI_DEBUG("wm:pm", "area(%s:%d)", area, area_no); + } + + HMI_DEBUG("wm:pm", "set event:0x%x", (event_no | category_no | area_no)); + + // Check policy + this->checkPolicyEntry((event_no | category_no | area_no), 0, notify_state); return 0; } @@ -447,22 +554,6 @@ int PolicyManager::inputJsonFilie(const char* file, json_object** obj) { return ret; } -void PolicyManager::addStateToJson( - const char* key, int is_changed, const char* state, json_object** json_out) { - if ((nullptr == key) || (nullptr == state) || (nullptr == json_out)) { - HMI_ERROR("wm:pm", "Argument is nullptr!!!"); - return; - } - - json_object* json_obj = json_object_new_object(); - json_object_object_add(json_obj, "is_changed", json_object_new_boolean(is_changed)); - if (is_changed) { - HMI_DEBUG("wm:pm", "%s: state changed (%s)", key, state); - json_object_object_add(json_obj, "state", json_object_new_string(state)); - } - json_object_object_add(*json_out, key, json_obj); -} - std::vector<std::string> PolicyManager::parseString(std::string str, char delimiter) { // Parse string by delimiter std::vector<std::string> vct; diff --git a/src/policy_manager/policy_manager.hpp b/src/policy_manager/policy_manager.hpp index 787a3ec..57856dc 100644 --- a/src/policy_manager/policy_manager.hpp +++ b/src/policy_manager/policy_manager.hpp @@ -23,6 +23,7 @@ struct json_object; +struct sd_event; class PolicyManager { @@ -30,9 +31,13 @@ public: explicit PolicyManager(); ~PolicyManager() = default; + using Handler = std::function<void(json_object *)>; + int initialize(); - int checkPolicy(json_object* json_in, json_object** json_out); + void setEventHandler(PolicyManager::Handler handler); + int inputEvent(json_object* json_in, PolicyManager::Handler notify_state); std::string roleToCategory(const char* role); + private: // Disable copy and move PolicyManager(PolicyManager const &) = delete; @@ -49,14 +54,19 @@ private: std::unordered_map<std::string, std::string> category2role_; std::unordered_map<std::string, std::string> role2defaultarea_; + struct sd_event* sd_event_; + + int initializeSdEventLoop(); + void checkPolicyEntry(int event, int delay_ms, PolicyManager::Handler handler); + // Load role.db int loadRoleDb(); const char* getStringFromJson(json_object* obj, const char* key); int inputJsonFilie(const char* file, json_object** obj); - void addStateToJson(const char* key, int is_changed, const char* state, json_object** json_out); std::vector<std::string> parseString(std::string str, char delimiter); std::string deleteSpace(std::string str); + }; |