2 * Copyright (c) 2018 TOYOTA MOTOR CORPORATION
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include <systemd/sd-event.h>
24 #include <json-c/json.h>
25 #include "policy_manager.hpp"
26 #include "hmi-debug.h"
30 #include "dummy_stm.h"
36 typedef std::unordered_map<std::string, std::string> AppAttribute;
37 typedef std::unordered_map<std::string, AppAttribute> AreasState;
38 typedef std::unordered_map<std::string, AreasState> LayoutState;
39 typedef std::unordered_map<std::string, LayoutState> LayersState;
41 struct sd_event* event_loop;
42 std::map<int, struct sd_event_source*> event_source_list;
43 PolicyManager::CallbackTable callback;
44 LayersState g_prv_layers;
45 LayersState g_crr_layers;
46 LayoutState g_default_layout_state;
50 PolicyManager::PolicyManager() :
58 HMI_DEBUG("wm:pm", "Call");
61 int PolicyManager::initialize() {
62 HMI_DEBUG("wm:pm", "Call");
67 for (unsigned int i=0; i<STM_NUM_EVT; i++) {
68 HMI_DEBUG("wm:pm", "event name:%s no:%d", stm::gStmEventName[i], stm::gStmEventNo[i]);
69 this->eventname2no_[stm::gStmEventName[i]] = stm::gStmEventNo[i];
72 for (unsigned int i=0; i<STM_NUM_CTG; i++) {
73 HMI_DEBUG("wm:pm", "category name:%s no:%d", stm::gStmCategoryName[i], stm::gStmCategoryNo[i]);
74 this->categoryname2no_[stm::gStmCategoryName[i]] = stm::gStmCategoryNo[i];
77 for (unsigned int i=0; i<STM_NUM_ARA; i++) {
78 HMI_DEBUG("wm:pm", "area name:%s no:%d", stm::gStmAreaName[i], stm::gStmAreaNo[i]);
79 this->areaname2no_[stm::gStmAreaName[i]] = stm::gStmAreaNo[i];
83 ret = this->loadRoleDb();
85 HMI_ERROR("wm:pm", "Load role.db Error!!");
90 ret = this->loadLayoutDb();
92 HMI_ERROR("wm:pm", "Load layout.db Error!!");
96 // Initialize current/previous state of layers
97 pm::AppAttribute init_app;
98 pm::AreasState init_area;
99 pm::LayoutState init_layout;
100 init_app["role"] = "none";
101 init_area["none"] = init_app;
102 init_layout["none"] = init_area;
104 pm::g_crr_layers["homescreen"] = init_layout;
105 pm::g_crr_layers["apps"] = init_layout;
106 pm::g_crr_layers["restriction"] = init_layout;
107 pm::g_crr_layers["on_screen"] = init_layout;
108 pm::g_prv_layers = pm::g_crr_layers;
110 // Initialize StateTransitioner
111 stm::stmInitialize();
113 // Initialize sd_event loop
114 ret = this->initializeSdEventLoop();
116 HMI_ERROR("wm:pm", "Failed to initializeSdEventLoop!!");
123 int PolicyManager::initializeSdEventLoop() {
124 // Get default event loop object
125 int ret = sd_event_new(&(pm::event_loop));
127 HMI_ERROR("wm:pm", "Faild to sd_event_default: errno:%d", ret);
131 // Create thread for sd_event and detach
132 std::thread sd_event_loop([this]() {
134 sd_event_run(pm::event_loop, 1000);
137 sd_event_loop.detach();
142 static void addStateToJson(
143 const char* key, int is_changed, const char* state, json_object** json_out) {
144 if ((nullptr == key) || (nullptr == state) || (nullptr == json_out)) {
145 HMI_ERROR("wm:pm", "Argument is nullptr!!!");
149 json_object* json_obj = json_object_new_object();
150 json_object_object_add(json_obj, "is_changed", json_object_new_boolean(is_changed));
152 HMI_DEBUG("wm:pm", "%s: state changed (%s)", key, state);
153 json_object_object_add(json_obj, "state", json_object_new_string(state));
155 json_object_object_add(*json_out, key, json_obj);
158 static int checkPolicyEntry(int event, uint64_t delay_ms);
159 static int checkPolicy(sd_event_source *source, void *data) {
160 HMI_DEBUG("wm:pm", "Call");
161 HMI_DEBUG("wm:pm", ">>>>>>>>>> START CHECK POLICY");
163 int event = *((int*)data);
165 int event_no, category_no, area_no;
166 event_no = event & STM_MSK_EVT_NO;
167 category_no = event & STM_MSK_CTG_NO;
168 area_no = event & STM_MSK_ARA_NO;
169 HMI_DEBUG("wm:pm", ">>>>>>>>>> event:%s category:%s area:%s",
170 stm::gStmEventName[event_no - 1],
171 stm::gStmCategoryName[(category_no >> 8) - 1],
172 stm::gStmAreaName[(area_no >> 16) - 1]);
175 stm::stm_state_t crr_state;
176 int ret = stm::stmTransitionState(event, &crr_state);
178 HMI_ERROR("wm:pm", "Error!!");
182 HMI_DEBUG("wm:pm", "parking brake state (is_changed:%d state:%d:%s)",
183 crr_state.parking_brake.is_changed,
184 crr_state.parking_brake.state,
185 stm::gStmParkingBrakeStateNo2Name[crr_state.parking_brake.state]);
186 HMI_DEBUG("wm:pm", "accelerator pedal state (is_changed:%d state:%d:%s)",
187 crr_state.accel_pedal.is_changed,
188 crr_state.accel_pedal.state,
189 stm::gStmAccelPedalStateNo2Name[crr_state.accel_pedal.state]);
190 HMI_DEBUG("wm:pm", "lightstatus brake state (is_changed:%d state:%d:%s)",
191 crr_state.lightstatus_brake.is_changed,
192 crr_state.lightstatus_brake.state,
193 stm::gStmLightstatusBrakeStateNo2Name[crr_state.lightstatus_brake.state]);
194 HMI_DEBUG("wm:pm", "car state (is_changed:%d state:%d:%s)",
195 crr_state.car.is_changed,
197 stm::gStmCarStateNo2Name[crr_state.car.state]);
198 HMI_DEBUG("wm:pm", "lamp state (is_changed:%d state:%d:%s)",
199 crr_state.lamp.is_changed,
200 crr_state.lamp.state,
201 stm::gStmLampStateNo2Name[crr_state.lamp.state]);
202 HMI_DEBUG("wm:pm", "restriction mode state (is_changed:%d state:%d:%s)",
203 crr_state.restriction_mode.is_changed,
204 crr_state.restriction_mode.state,
205 stm::gStmRestrictionModeStateNo2Name[crr_state.restriction_mode.state]);
206 HMI_DEBUG("wm:pm", "homescreen state (is_changed:%d state:%d:%s)",
207 crr_state.layer[stm::gStmLayerNoHomescreen].is_changed,
208 crr_state.layer[stm::gStmLayerNoHomescreen].state,
209 stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoHomescreen].state]);
210 HMI_DEBUG("wm:pm", "apps state (is_changed:%d state:%d:%s)",
211 crr_state.layer[stm::gStmLayerNoApps].is_changed,
212 crr_state.layer[stm::gStmLayerNoApps].state,
213 stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoApps].state]);
214 HMI_DEBUG("wm:pm", "restriction state (is_changed:%d state:%d:%s)",
215 crr_state.layer[stm::gStmLayerNoRestriction].is_changed,
216 crr_state.layer[stm::gStmLayerNoRestriction].state,
217 stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoRestriction].state]);
218 HMI_DEBUG("wm:pm", "on_screen state (is_changed:%d state:%d:%s)",
219 crr_state.layer[stm::gStmLayerNoOnScreen].is_changed,
220 crr_state.layer[stm::gStmLayerNoOnScreen].state,
221 stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoOnScreen].state]);
223 #if 0 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
224 // Store previous layers
225 pm::g_prv_layers = pm::g_crr_layers;
227 std::string layer_name = "homescreen";
230 if (crr_state.layer[stm::gStmLayerNoHomescreen].is_changed) {
231 // Get previous layout name of this layer
232 pm::LayoutState prv_layout_state = pm::g_prv_layers[layer_name];
233 std::string prv_layout_name = prv_homescreen_layout_state.first();
235 // Get current layout name of this layer
236 std::string crr_layout_name = std::string(stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoHomescreen].state]);
238 // Compare layout name
239 pm::LayoutState crr_layout_state;
240 if ("none" == crr_layout_name) {
241 // If current layout is "none",
242 // current areas is set with "none"
243 HMI_DEBUG("wm:pm", "Current layout is \"none\"");
244 HMI_DEBUG("wm:lm", "Current layout is \"none\"");
245 pm::AppAttribute crr_app_attribute;
246 pm::AreasState crr_areas_state;
247 crr_app_attribute["role"] = "none";
248 crr_areas_state["none"] = "none";
249 crr_layout_state["none"] = crr_areas_state;
252 if (prv_layout_name == crr_layout_name) {
253 // If previous layout is same with current,
254 // previous areas are copied to current
255 crr_layout_state[crr_layout_name] = pm::g_prv_layers[layer_name][crr_layout_name];
258 // If previous layout is same with current,
259 // previous areas are copied to current
260 crr_layout_state[crr_layout_name] = this->default_layout_state[crr_layout_name];
263 // Update role in new area
265 if (crr_state.restriction_mode.is_changed) {
266 // Updating role is not necessary
267 // because new_role is not specified
268 // when restriction mode is changed
269 HMI_DEBUG("wm:lm", "Updating role is not necessary because new_role is not specified when restriction mode is changed");
271 if (crr_state.car.is_changed) {
272 // Updating role is not necessary
273 // because new_role is not specified
274 // when car state is changed
275 HMI_DEBUG("wm:lm", "Updating role is not necessary because new_role is not specified when car state is changed");
279 HMI_DEBUG("wm:lm", "Get new_area for new role");
280 // Get new_area for new role
281 std::string new_area = this->getAreaName(this->layout_define_[crr_layout_name],
284 if ("none" == new_area) {
285 HMI_DEBUG("wm:lm", "It is not necessary to update role of areas in this layer, because new_role is not specified for this layer");
288 // Is there new_area?
289 // if there is new_area, set new role there
291 // if NOT, find same category of new_role
292 // pop old role and shift area
293 // push new role and set area
296 // Update role in new area
297 // because new_role is specified for this layer
299 crr_role["role"] = std::string(new_role);
300 crr_layout[crr_layout_name][new_area] = crr_role;
306 // Update current layout of this layer
307 pm::g_crr_layers[layer_name] = crr_layout_state;
310 #endif // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
312 json_object* json_out = json_object_new_object();
316 // "parking_brake": {
317 // "is_changed": <bool>,
318 // "state": <const char*>
320 addStateToJson("parking_brake",
321 crr_state.parking_brake.is_changed,
322 stm::gStmParkingBrakeStateNo2Name[crr_state.parking_brake.state],
326 // "is_changed": <bool>,
327 // "state": <const char*>
329 addStateToJson("accel_pedal",
330 crr_state.accel_pedal.is_changed,
331 stm::gStmAccelPedalStateNo2Name[crr_state.accel_pedal.state],
334 // "lightstatus_brake": {
335 // "is_changed": <bool>,
336 // "state": <const char*>
338 addStateToJson("lightstatus_brake",
339 crr_state.lightstatus_brake.is_changed,
340 stm::gStmLightstatusBrakeStateNo2Name[crr_state.lightstatus_brake.state],
344 // "is_changed": <bool>,
345 // "state": <const char*>
347 addStateToJson("car",
348 crr_state.car.is_changed,
349 stm::gStmCarStateNo2Name[crr_state.car.state],
353 // "is_changed": <bool>,
354 // "state": <const char*>
356 addStateToJson("lamp",
357 crr_state.lamp.is_changed,
358 stm::gStmLampStateNo2Name[crr_state.lamp.state],
361 // "restriction_mode": {
362 // "is_changed": <bool>,
363 // "state": <const char*>
365 addStateToJson("restriction_mode",
366 crr_state.restriction_mode.is_changed,
367 stm::gStmRestrictionModeStateNo2Name[crr_state.restriction_mode.state],
371 json_object* json_layer = json_object_new_array();
372 json_object* json_tmp;
376 // "is_changed": <bool>,
377 // "state": <const char*>
382 json_tmp = json_object_new_object();
383 addStateToJson("homescreen",
384 crr_state.layer[stm::gStmLayerNoHomescreen].is_changed,
385 stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoHomescreen].state],
387 json_object_array_add(json_layer, json_tmp);
391 // "is_changed": <bool>,
392 // "state": <const char*>
395 json_tmp = json_object_new_object();
396 addStateToJson("apps",
397 crr_state.layer[stm::gStmLayerNoApps].is_changed,
398 stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoApps].state],
400 json_object_array_add(json_layer, json_tmp);
404 // "is_changed": <bool>,
405 // "state": <const char*>
408 json_tmp = json_object_new_object();
409 addStateToJson("restriction",
410 crr_state.layer[stm::gStmLayerNoRestriction].is_changed,
411 stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoRestriction].state],
413 json_object_array_add(json_layer, json_tmp);
417 // "is_changed": <bool>,
418 // "state": <const char*>
421 json_tmp = json_object_new_object();
422 addStateToJson("on_screen",
423 crr_state.layer[stm::gStmLayerNoOnScreen].is_changed,
424 stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoOnScreen].state],
426 json_object_array_add(json_layer, json_tmp);
428 // Add json array of layer
429 json_object_object_add(json_out, "layers", json_layer);
431 // Notify state is changed
432 if (nullptr != pm::callback.onStateTransitioned) {
433 pm::callback.onStateTransitioned(json_out);
436 if (crr_state.car.is_changed) {
437 if (stm::gStmCarStateNoRun == crr_state.car.state) {
438 // Set delay event(restriction mode on)
439 checkPolicyEntry(STM_EVT_NO_RESTRICTION_MODE_ON, 3000);
441 else if (stm::gStmCarStateNoStop == crr_state.car.state) {
442 // Set event(restriction mode off)
443 checkPolicyEntry(STM_EVT_NO_RESTRICTION_MODE_OFF, 0);
445 // Stop timer for restriction on event
446 if (pm::event_source_list.find(STM_EVT_NO_RESTRICTION_MODE_ON)
447 != pm::event_source_list.end()) {
448 HMI_DEBUG("wm:pm", "Stop timer for restriction on");
449 sd_event_source *event_source
450 = pm::event_source_list[STM_EVT_NO_RESTRICTION_MODE_ON];
451 int ret = sd_event_source_set_enabled(event_source, SD_EVENT_OFF);
453 HMI_ERROR("wm:pm", "Failed to stop timer");
459 // Release json_object
460 json_object_put(json_out);
465 // Destroy sd_event_source object
466 sd_event_source_unref(source);
468 // Remove event source from list
469 if (pm::event_source_list.find(event) != pm::event_source_list.end()) {
470 pm::event_source_list.erase(event);
473 HMI_DEBUG("wm:pm", ">>>>>>>>>> FINISH CHECK POLICY");
477 static int timerEvent(sd_event_source *source, uint64_t usec, void *data) {
478 checkPolicy(source, data);
481 static int checkPolicyEntry(int event, uint64_t delay_ms)
483 HMI_DEBUG("wm:pm", "Call");
484 HMI_DEBUG("wm:pm", "event:0x%x", event);
487 int ret = sd_event_add_defer(pm::event_loop, NULL,
488 &checkPolicy, new int(event));
490 HMI_ERROR("wm:pm", "Faild to sd_event_add_defer: errno:%d", ret);
496 struct timespec time_spec;
497 clock_gettime(CLOCK_MONOTONIC, &time_spec);
499 // Calculate timer fired time
500 uint64_t usec = (time_spec.tv_sec * 1000000)
501 + (time_spec.tv_nsec / 1000)
505 struct sd_event_source* event_source;
506 int ret = sd_event_add_time(pm::event_loop, &event_source, CLOCK_MONOTONIC, usec, 1,
507 &timerEvent, new int(event));
509 HMI_ERROR("wm:pm", "Faild to sd_event_add_time: errno:%d", ret);
513 // Store event source
514 pm::event_source_list[event] = event_source;
520 void PolicyManager::registerCallback(CallbackTable callback) {
521 pm::callback.onStateTransitioned = callback.onStateTransitioned;
522 pm::callback.onError = callback.onError;
525 int PolicyManager::inputEvent(json_object* json_in) {
526 HMI_DEBUG("wm:pm", "Call");
529 if (nullptr == json_in) {
530 HMI_ERROR("wm:pm", "Argument is NULL!!");
534 // Get event from json_object
535 const char* event = this->getStringFromJson(json_in, "event");
537 if (nullptr != event) {
538 // Convert name to number
539 event_no = this->eventname2no_[event];
540 HMI_DEBUG("wm:pm", "event(%s:%d)", event, event_no);
543 // Get role from json_object
544 const char* role = this->getStringFromJson(json_in, "role");
546 if (nullptr != role) {
547 HMI_DEBUG("wm:pm", "role(%s)", role);
549 // Convert role to category
550 const char* category = this->role2category_[role].c_str();
551 if (0 == strcmp("", category)) {
552 HMI_ERROR("wm:pm", "Error!!");
555 HMI_DEBUG("wm:pm", "category(%s)", category);
557 // Convert name to number
558 category_no = categoryname2no_[category];
559 HMI_DEBUG("wm:pm", "role(%s), category(%s:%d)", role, category, category_no);
562 // Get areat from json_object
563 const char* area = this->getStringFromJson(json_in, "area");
565 if (nullptr != area) {
566 // Convert name to number
567 area_no = areaname2no_[area];
568 HMI_DEBUG("wm:pm", "area(%s:%d)", area, area_no);
572 checkPolicyEntry((event_no | category_no | area_no), 0);
577 std::string PolicyManager::roleToCategory(const char* role) {
578 return this->role2category_[role];
581 extern const char* kDefaultRoleDb;
582 int PolicyManager::loadRoleDb() {
583 HMI_DEBUG("wm:pm", "Call");
585 std::string file_name;
587 // Get afm application installed dir
588 char const *afm_app_install_dir = getenv("AFM_APP_INSTALL_DIR");
589 HMI_DEBUG("wm:pm", "afm_app_install_dir:%s", afm_app_install_dir);
591 if (!afm_app_install_dir) {
592 HMI_ERROR("wm:pm", "AFM_APP_INSTALL_DIR is not defined");
595 file_name = std::string(afm_app_install_dir) + std::string("/etc/role.db");
599 json_object* json_obj;
600 int ret = this->inputJsonFilie(file_name.c_str(), &json_obj);
602 HMI_ERROR("wm:pm", "Could not open role.db, so use default role information");
603 json_obj = json_tokener_parse(kDefaultRoleDb);
605 HMI_DEBUG("wm:pm", "json_obj dump:%s", json_object_get_string(json_obj));
607 json_object* json_roles;
608 if (!json_object_object_get_ex(json_obj, "roles", &json_roles)) {
609 HMI_ERROR("wm:pm", "Parse Error!!");
613 int len = json_object_array_length(json_roles);
614 HMI_DEBUG("wm:pm", "json_cfg len:%d", len);
615 HMI_DEBUG("wm:pm", "json_cfg dump:%s", json_object_get_string(json_roles));
617 json_object* json_tmp;
618 const char* category;
621 for (int i=0; i<len; i++) {
622 json_tmp = json_object_array_get_idx(json_roles, i);
624 category = this->getStringFromJson(json_tmp, "category");
625 roles = this->getStringFromJson(json_tmp, "role");
626 areas = this->getStringFromJson(json_tmp, "area");
628 if ((nullptr == category) || (nullptr == roles) || (nullptr == areas)) {
629 HMI_ERROR("wm:pm", "Parse Error!!");
633 // Parse roles by '|'
634 std::vector<std::string> vct_roles;
635 vct_roles = this->parseString(std::string(roles), '|');
637 // Parse areas by '|'
638 std::vector<std::string> vct_areas;
639 vct_areas = this->parseString(std::string(areas), '|');
641 // Set role, category, default area
642 for (auto itr = vct_roles.begin(); itr != vct_roles.end(); ++itr) {
643 // Delete space from role and area name
644 std::string role = this->deleteSpace(*itr);
645 std::string area = this->deleteSpace(vct_areas[0]);
647 this->role2category_[role] = std::string(category);
648 this->role2defaultarea_[role] = area;
651 this->category2role_[std::string(category)] = std::string(roles);
655 HMI_DEBUG("wm:pm", "Check role2category_");
656 for (auto& x:this->role2category_){
657 HMI_DEBUG("wm:pm", "key:%s, val:%s", x.first.c_str(), x.second.c_str());
660 HMI_DEBUG("wm:pm", "Check role2defaultarea_");
661 for (auto& x:this->role2defaultarea_){
662 HMI_DEBUG("wm:pm", "key:%s, val:%s", x.first.c_str(), x.second.c_str());
665 HMI_DEBUG("wm:pm", "Check category2role_");
666 for (auto& x:this->category2role_){
667 HMI_DEBUG("wm:pm", "key:%s, val:%s", x.first.c_str(), x.second.c_str());
673 extern const char* kDefaultLayoutDb;
674 int PolicyManager::loadLayoutDb() {
675 HMI_DEBUG("wm:lm", "Call");
677 // Get afm application installed dir
678 char const *afm_app_install_dir = getenv("AFM_APP_INSTALL_DIR");
679 HMI_DEBUG("wm:pm", "afm_app_install_dir:%s", afm_app_install_dir);
681 std::string file_name;
682 if (!afm_app_install_dir) {
683 HMI_ERROR("wm:pm", "AFM_APP_INSTALL_DIR is not defined");
686 file_name = std::string(afm_app_install_dir) + std::string("/etc/layout.db");
690 json_object* json_obj;
691 int ret = this->inputJsonFilie(file_name.c_str(), &json_obj);
693 HMI_DEBUG("wm:pm", "Could not open layout.db, so use default layout information");
694 json_obj = json_tokener_parse(kDefaultLayoutDb);
696 HMI_DEBUG("wm:pm", "json_obj dump:%s", json_object_get_string(json_obj));
699 HMI_DEBUG("wm:pm", "Perse layouts");
700 json_object* json_cfg;
701 if (!json_object_object_get_ex(json_obj, "layouts", &json_cfg)) {
702 HMI_ERROR("wm:pm", "Parse Error!!");
706 int len = json_object_array_length(json_cfg);
707 HMI_DEBUG("wm:pm", "json_cfg len:%d", len);
708 HMI_DEBUG("wm:pm", "json_cfg dump:%s", json_object_get_string(json_cfg));
712 const char* category;
713 for (int i=0; i<len; i++) {
714 json_object* json_tmp = json_object_array_get_idx(json_cfg, i);
716 layout = this->getStringFromJson(json_tmp, "name");
717 if (nullptr == layout) {
718 HMI_ERROR("wm:pm", "Parse Error!!");
721 HMI_DEBUG("wm:pm", "> layout:%s", layout);
723 json_object* json_area_array;
724 if (!json_object_object_get_ex(json_tmp, "areas", &json_area_array)) {
725 HMI_ERROR("wm:pm", "Parse Error!!");
729 int len_area = json_object_array_length(json_area_array);
730 HMI_DEBUG("wm:pm", "json_area_array len:%d", len_area);
731 HMI_DEBUG("wm:pm", "json_area_array dump:%s", json_object_get_string(json_area_array));
733 pm::AreasState areas_state;
734 for (int j=0; j<len_area; j++) {
735 json_object* json_area = json_object_array_get_idx(json_area_array, j);
738 const char* area = this->getStringFromJson(json_area, "name");
739 if (nullptr == area) {
740 HMI_ERROR("wm:pm", "Parse Error!!");
743 HMI_DEBUG("wm:pm", ">> area:%s", area);
745 // Get app attribute of the area
746 pm::AppAttribute app_attribute;
747 category = this->getStringFromJson(json_area, "category");
748 if (nullptr == category) {
749 HMI_ERROR("wm:pm", "Parse Error!!");
752 app_attribute["category"] = std::string(category);
753 HMI_DEBUG("wm:pm", ">>> category:%s", category);
755 role = this->getStringFromJson(json_area, "role");
756 if (nullptr != role) {
757 // Role is NOT essential here
758 app_attribute["role"] = std::string(role);
759 HMI_DEBUG("wm:pm", ">>> role:%s", role);
762 areas_state[area] = app_attribute;
765 pm::g_default_layout_state[layout] = areas_state;
769 for(auto itr_layout = pm::g_default_layout_state.begin();
770 itr_layout != pm::g_default_layout_state.end(); ++itr_layout) {
771 HMI_DEBUG("wm:pm", ">>> layout:%s", itr_layout->first.c_str());
773 for (auto itr_area = itr_layout->second.begin();
774 itr_area != itr_layout->second.end(); ++itr_area) {
775 HMI_DEBUG("wm:pm", ">>> >>> area:%s", itr_area->first.c_str());
777 for (auto itr_role = itr_area->second.begin();
778 itr_role != itr_area->second.end(); ++itr_role) {
779 HMI_DEBUG("wm:pm", ">>> >>> >>> attribute:%s, name:%s",
780 itr_role->first.c_str(), itr_role->second.c_str());
785 // Release json_object
786 json_object_put(json_obj);
792 // This function will be removed because json_helper has same function.
793 // json_helper should be library.
794 const char* PolicyManager::getStringFromJson(json_object* obj, const char* key) {
795 if ((nullptr == obj) || (nullptr == key)) {
796 HMI_ERROR("wm:pm", "Argument is nullptr!!!");
801 if (!json_object_object_get_ex(obj, key, &tmp)) {
802 HMI_DEBUG("wm:pm", "Not found key \"%s\"", key);
806 return json_object_get_string(tmp);
810 // This function will be removed because json_helper has same function.
811 // json_helper should be library.
812 int PolicyManager::inputJsonFilie(const char* file, json_object** obj) {
813 const int input_size = 128;
816 if ((nullptr == file) || (nullptr == obj)) {
817 HMI_ERROR("wm:jh", "Argument is nullptr!!!");
821 HMI_DEBUG("wm:jh", "Input file: %s", file);
824 FILE *fp = fopen(file, "rb");
826 HMI_ERROR("wm:jh", "Could not open file");
831 struct json_tokener *tokener = json_tokener_new();
832 enum json_tokener_error json_error;
833 char buffer[input_size];
836 size_t len = fread(buffer, sizeof(char), input_size, fp);
837 *obj = json_tokener_parse_ex(tokener, buffer, len);
838 if (nullptr != *obj) {
839 HMI_DEBUG("wm:jh", "File input is success");
844 json_error = json_tokener_get_error(tokener);
845 if ((json_tokener_continue != json_error)
846 || (input_size > len)) {
847 HMI_ERROR("wm:jh", "Failed to parse file (byte:%d err:%s)",
848 (input_size * block_cnt), json_tokener_error_desc(json_error));
849 HMI_ERROR("wm:jh", "\n%s", buffer);
860 json_tokener_free(tokener);
865 std::vector<std::string> PolicyManager::parseString(std::string str, char delimiter) {
866 // Parse string by delimiter
867 std::vector<std::string> vct;
868 std::stringstream ss{str};
870 while (std::getline(ss, buf, delimiter)) {
878 std::string PolicyManager::deleteSpace(std::string str) {
879 std::string ret = str;
881 while ((pos = ret.find_first_of(" ")) != std::string::npos) {
887 const char* kDefaultRoleDb = "{ \
890 \"category\": \"homescreen\", \
891 \"role\": \"homescreen\", \
892 \"area\": \"full\", \
895 \"category\": \"map\", \
897 \"area\": \"full | normal | split.main\", \
900 \"category\": \"general\", \
901 \"role\": \"poi | music | video | browser | sdl | settings | mixer | radio | hvac | dashboard | debug\", \
902 \"area\": \"normal\", \
905 \"category\": \"phone\", \
906 \"role\": \"phone\", \
907 \"area\": \"normal\", \
910 \"category\": \"splitable\", \
911 \"role\": \"splitable1 | splitable2\", \
912 \"area\": \"normal | split.main | split.sub\", \
915 \"category\": \"popup\", \
916 \"role\": \"popup\", \
917 \"area\": \"on_screen\", \
920 \"category\": \"system_alert\", \
921 \"role\": \"system_alert\", \
922 \"area\": \"on_screen\", \
925 \"category\": \"tbt\", \
933 const char* kDefaultLayoutDb = "{ \
937 \"layer\": \"on_screen\", \
940 \"name\": \"pop_up\", \
941 \"role\": \"incomming_call\" \
947 \"layer\": \"on_screen\", \
950 \"name\": \"system_alert\", \
951 \"role\": \"system_alert\" \
957 \"layer\": \"apps\", \
960 \"name\": \"normal\", \
967 \"layer\": \"apps\", \
970 \"name\": \"split.main\", \
974 \"name\": \"split.sub\", \
975 \"category\": \"hvac\" \
981 \"layer\": \"apps\", \
984 \"name\": \"full\", \
991 \"layer\": \"apps\", \
994 \"name\": \"normal\", \
995 \"category\": \"splitable\" \
1001 \"layer\": \"apps\", \
1004 \"name\": \"split.main\", \
1005 \"category\": \"splitable\" \
1008 \"name\": \"split.sub\", \
1009 \"category\": \"splitable\" \
1015 \"layer\": \"apps\", \
1018 \"name\": \"normal\", \
1019 \"category\": \"general\" \
1025 \"layer\": \"homescreen\", \
1028 \"name\": \"full\", \
1029 \"role\": \"homescreen\" \
1036 \"name\": \"normal\", \
1045 \"name\": \"split.main\", \
1054 \"name\": \"split.sub\", \
1063 \"name\": \"full\", \
1072 \"name\": \"pop_up\", \
1081 \"name\": \"system_alert\", \