Modify struct stm_state_t
[apps/agl-service-windowmanager.git] / src / policy_manager / policy_manager.cpp
1 /*
2  * Copyright (c) 2018 TOYOTA MOTOR CORPORATION
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17
18 #include <fstream>
19 #include <sstream>
20 #include <istream>
21 #include <thread>
22 #include <map>
23 #include <systemd/sd-event.h>
24 #include <json-c/json.h>
25 #include "policy_manager.hpp"
26 #include "hmi-debug.h"
27
28 namespace stm {
29 extern "C" {
30 #include "dummy_stm.h"
31 }
32 } // namespace stm
33
34
35 namespace pm {
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;
40
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 }  // namespace pm
47
48
49 PolicyManager::PolicyManager() :
50   eventname2no_(),
51   categoryname2no_(),
52   areaname2no_(),
53   role2category_(),
54   category2role_(),
55   role2defaultarea_()
56 {
57     HMI_DEBUG("wm:pm", "Call");
58 }
59
60 int PolicyManager::initialize() {
61     HMI_DEBUG("wm:pm", "Call");
62
63     int ret = 0;
64
65     // Create convert map
66     for (unsigned int i=0; i<STM_NUM_EVT; i++) {
67         HMI_DEBUG("wm:pm", "event name:%s no:%d", stm::gStmEventName[i], stm::gStmEventNo[i]);
68         this->eventname2no_[stm::gStmEventName[i]] = stm::gStmEventNo[i];
69     }
70
71     for (unsigned int i=0; i<STM_NUM_CTG; i++) {
72         HMI_DEBUG("wm:pm", "category name:%s no:%d", stm::gStmCategoryName[i], stm::gStmCategoryNo[i]);
73         this->categoryname2no_[stm::gStmCategoryName[i]] = stm::gStmCategoryNo[i];
74     }
75
76     for (unsigned int i=0; i<STM_NUM_ARA; i++) {
77         HMI_DEBUG("wm:pm", "area name:%s no:%d", stm::gStmAreaName[i], stm::gStmAreaNo[i]);
78         this->areaname2no_[stm::gStmAreaName[i]] = stm::gStmAreaNo[i];
79     }
80
81     // Load role.db
82     ret = this->loadRoleDb();
83     if (0 > ret) {
84         HMI_ERROR("wm:pm", "Load role.db Error!!");
85         return ret;
86     }
87
88     // Initialize current/previous state of layers
89     pm::AppAttribute init_app;
90     pm::AreasState init_area;
91     pm::LayoutState init_layout;
92     init_app["role"] = "none";
93     init_area["none"] = init_app;
94     init_layout["none"] = init_area;
95
96     pm::g_crr_layers["homescreen"]  = init_layout;
97     pm::g_crr_layers["apps"]        = init_layout;
98     pm::g_crr_layers["restriction"] = init_layout;
99     pm::g_crr_layers["on_screen"]   = init_layout;
100     pm::g_prv_layers = pm::g_crr_layers;
101
102     // Initialize StateTransitioner
103     stm::stmInitialize();
104
105     // Initialize sd_event loop
106     ret = this->initializeSdEventLoop();
107     if (0 > ret) {
108         HMI_ERROR("wm:pm", "Failed to initializeSdEventLoop!!");
109         return ret;
110     }
111
112     return ret;
113 }
114
115 int PolicyManager::initializeSdEventLoop() {
116     // Get default event loop object
117     int ret = sd_event_new(&(pm::event_loop));
118     if (0 > ret) {
119         HMI_ERROR("wm:pm", "Faild to sd_event_default: errno:%d", ret);
120         return -1;
121     }
122
123     // Create thread for sd_event and detach
124     std::thread sd_event_loop([this]() {
125         while (1) {
126             sd_event_run(pm::event_loop, 1000);
127         }
128     });
129     sd_event_loop.detach();
130
131     return 0;
132 }
133
134 static void addStateToJson(
135   const char* key, int is_changed, const char* state, json_object** json_out) {
136     if ((nullptr == key) || (nullptr == state) || (nullptr == json_out)) {
137         HMI_ERROR("wm:pm", "Argument is nullptr!!!");
138         return;
139     }
140
141     json_object* json_obj = json_object_new_object();
142     json_object_object_add(json_obj, "is_changed", json_object_new_boolean(is_changed));
143     if (is_changed) {
144         HMI_DEBUG("wm:pm", "%s: state changed (%s)", key, state);
145         json_object_object_add(json_obj, "state", json_object_new_string(state));
146     }
147     json_object_object_add(*json_out, key, json_obj);
148 }
149
150 static int checkPolicyEntry(int event, uint64_t delay_ms);
151 static int checkPolicy(sd_event_source *source, void *data) {
152     HMI_DEBUG("wm:pm", "Call");
153     HMI_DEBUG("wm:pm", ">>>>>>>>>> START CHECK POLICY");
154
155     int event = *((int*)data);
156
157     int event_no, category_no, area_no;
158     event_no    = event & STM_MSK_EVT_NO;
159     category_no = event & STM_MSK_CTG_NO;
160     area_no     = event & STM_MSK_ARA_NO;
161     HMI_DEBUG("wm:pm", ">>>>>>>>>> event:%s category:%s area:%s",
162               stm::gStmEventName[event_no - 1],
163               stm::gStmCategoryName[(category_no >> 8) - 1],
164               stm::gStmAreaName[(area_no >> 16) - 1]);
165
166     // Transition state
167     stm::stm_state_t crr_state;
168     int ret = stm::stmTransitionState(event, &crr_state);
169     if (0 > ret) {
170         HMI_ERROR("wm:pm", "Error!!");
171         return -1;
172     }
173
174     HMI_DEBUG("wm:pm", "parking brake state     (is_changed:%d state:%d:%s)",
175               crr_state.parking_brake.is_changed,
176               crr_state.parking_brake.state,
177               stm::gStmParkingBrakeStateNo2Name[crr_state.parking_brake.state]);
178     HMI_DEBUG("wm:pm", "accelerator pedal state (is_changed:%d state:%d:%s)",
179               crr_state.accel_pedal.is_changed,
180               crr_state.accel_pedal.state,
181               stm::gStmAccelPedalStateNo2Name[crr_state.accel_pedal.state]);
182     HMI_DEBUG("wm:pm", "lightstatus brake state (is_changed:%d state:%d:%s)",
183               crr_state.lightstatus_brake.is_changed,
184               crr_state.lightstatus_brake.state,
185               stm::gStmLightstatusBrakeStateNo2Name[crr_state.lightstatus_brake.state]);
186     HMI_DEBUG("wm:pm", "car state               (is_changed:%d state:%d:%s)",
187               crr_state.car.is_changed,
188               crr_state.car.state,
189               stm::gStmCarStateNo2Name[crr_state.car.state]);
190     HMI_DEBUG("wm:pm", "lamp state              (is_changed:%d state:%d:%s)",
191               crr_state.lamp.is_changed,
192               crr_state.lamp.state,
193               stm::gStmLampStateNo2Name[crr_state.lamp.state]);
194     HMI_DEBUG("wm:pm", "restriction mode state  (is_changed:%d state:%d:%s)",
195               crr_state.restriction_mode.is_changed,
196               crr_state.restriction_mode.state,
197               stm::gStmRestrictionModeStateNo2Name[crr_state.restriction_mode.state]);
198     HMI_DEBUG("wm:pm", "homescreen state        (is_changed:%d state:%d:%s)",
199               crr_state.layer[stm::gStmLayerNoHomescreen].is_changed,
200               crr_state.layer[stm::gStmLayerNoHomescreen].state,
201               stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoHomescreen].state]);
202     HMI_DEBUG("wm:pm", "apps state              (is_changed:%d state:%d:%s)",
203               crr_state.layer[stm::gStmLayerNoApps].is_changed,
204               crr_state.layer[stm::gStmLayerNoApps].state,
205               stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoApps].state]);
206     HMI_DEBUG("wm:pm", "restriction state       (is_changed:%d state:%d:%s)",
207               crr_state.layer[stm::gStmLayerNoRestriction].is_changed,
208               crr_state.layer[stm::gStmLayerNoRestriction].state,
209               stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoRestriction].state]);
210     HMI_DEBUG("wm:pm", "on_screen state         (is_changed:%d state:%d:%s)",
211               crr_state.layer[stm::gStmLayerNoOnScreen].is_changed,
212               crr_state.layer[stm::gStmLayerNoOnScreen].state,
213               stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoOnScreen].state]);
214
215 #if 0 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
216     // Store previous layers
217     pm::g_prv_layers = pm::g_crr_layers;
218
219     std::string layer_name = "homescreen";
220
221     // changed?
222     if (crr_state.layer[stm::gStmLayerNoHomescreen].is_changed) {
223         // Get previous layout name of this layer
224         pm::LayoutState prv_layout_state =  pm::g_prv_layers[layer_name];
225         std::string prv_layout_name = prv_homescreen_layout_state.first();
226
227         // Get current layout name of this layer
228         std::string crr_layout_name = std::string(stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoHomescreen].state]);
229
230         // Compare layout name
231         pm::LayoutState crr_layout_state;
232         if ("none" == crr_layout_name) {
233             // If current layout is "none",
234             // current areas is set with "none"
235             HMI_DEBUG("wm:pm", "Current layout is \"none\"");
236                 HMI_DEBUG("wm:lm", "Current layout is \"none\"");
237                 pm::AppAttribute crr_app_attribute;
238                 pm::AreasState crr_areas_state;
239                 crr_app_attribute["role"] = "none";
240                 crr_areas_state["none"] = "none";
241                 crr_layout_state["none"] = crr_areas_state;
242         }
243         else {
244             if (prv_layout_name == crr_layout_name) {
245                 // If previous layout is same with current,
246                 // previous areas are copied to current
247                 crr_layout_state[crr_layout_name] = pm::g_prv_layers[layer_name][crr_layout_name];
248             }
249             else {
250                 // If previous layout is same with current,
251                 // previous areas are copied to current
252                 crr_layout_state[crr_layout_name] = this->default_layout_state[crr_layout_name];
253             }
254
255             // Update role in new area
256 #if 1
257             if (crr_state.restriction_mode.is_changed) {
258                 // Updating role is not necessary
259                 // because new_role is not specified
260                 // when restriction mode is changed
261                 HMI_DEBUG("wm:lm", "Updating role is not necessary because new_role is not specified when restriction mode is changed");
262 #else
263                 if (crr_state.car.is_changed) {
264                     // Updating role is not necessary
265                     // because new_role is not specified
266                     // when car state is changed
267                     HMI_DEBUG("wm:lm", "Updating role is not necessary because new_role is not specified when car state is changed");
268 #endif
269                 }
270                 else {
271                     HMI_DEBUG("wm:lm", "Get new_area for new role");
272                     // Get new_area for new role
273                     std::string new_area = this->getAreaName(this->layout_define_[crr_layout_name],
274                                                              new_role, category);
275
276                     if ("none" == new_area) {
277                         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");
278                     }
279                     else {
280                         // Is there new_area?
281                         // if there is new_area, set new role there
282
283                         // if NOT, find same category of new_role
284                             // pop old role and shift area
285                             // push new role and set area
286
287
288                         // Update role in new area
289                         // because new_role is specified for this layer
290                         TypeRolCtg crr_role;
291                         crr_role["role"] = std::string(new_role);
292                         crr_layout[crr_layout_name][new_area] = crr_role;
293                     }
294                 }
295             }
296         }
297
298         // Update current layout of this layer
299         pm::g_crr_layers[layer_name] = crr_layout_state;
300
301     }
302 #endif // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
303
304     json_object* json_out = json_object_new_object();
305
306     // Create result
307     // {
308     //     "parking_brake": {
309     //         "is_changed": <bool>,
310     //         "state": <const char*>
311     //     },
312     addStateToJson("parking_brake",
313                    crr_state.parking_brake.is_changed,
314                    stm::gStmParkingBrakeStateNo2Name[crr_state.parking_brake.state],
315                    &json_out);
316
317     //     "accel_pedal": {
318     //         "is_changed": <bool>,
319     //         "state": <const char*>
320     //     },
321     addStateToJson("accel_pedal",
322                    crr_state.accel_pedal.is_changed,
323                    stm::gStmAccelPedalStateNo2Name[crr_state.accel_pedal.state],
324                    &json_out);
325
326     //     "lightstatus_brake": {
327     //         "is_changed": <bool>,
328     //         "state": <const char*>
329     //     },
330     addStateToJson("lightstatus_brake",
331                    crr_state.lightstatus_brake.is_changed,
332                    stm::gStmLightstatusBrakeStateNo2Name[crr_state.lightstatus_brake.state],
333                    &json_out);
334
335     //     "car": {
336     //         "is_changed": <bool>,
337     //         "state": <const char*>
338     //     },
339     addStateToJson("car",
340                    crr_state.car.is_changed,
341                    stm::gStmCarStateNo2Name[crr_state.car.state],
342                    &json_out);
343
344     //     "lamp": {
345     //         "is_changed": <bool>,
346     //         "state": <const char*>
347     //     },
348     addStateToJson("lamp",
349                    crr_state.lamp.is_changed,
350                    stm::gStmLampStateNo2Name[crr_state.lamp.state],
351                    &json_out);
352
353     //     "restriction_mode": {
354     //         "is_changed": <bool>,
355     //         "state": <const char*>
356     //     },
357     addStateToJson("restriction_mode",
358                    crr_state.restriction_mode.is_changed,
359                    stm::gStmRestrictionModeStateNo2Name[crr_state.restriction_mode.state],
360                    &json_out);
361
362     //     "layers": [
363     json_object* json_layer = json_object_new_array();
364     json_object* json_tmp;
365
366     //         {
367     //             "homescreen": {
368     //                 "is_changed": <bool>,
369     //                 "state": <const char*>
370     //             }
371     //         },
372     //     ]
373     // }
374     json_tmp = json_object_new_object();
375     addStateToJson("homescreen",
376                    crr_state.layer[stm::gStmLayerNoHomescreen].is_changed,
377                    stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoHomescreen].state],
378                    &json_tmp);
379     json_object_array_add(json_layer, json_tmp);
380
381     //         {
382     //             "apps": {
383     //                 "is_changed": <bool>,
384     //                 "state": <const char*>
385     //             }
386     //         },
387     json_tmp = json_object_new_object();
388     addStateToJson("apps",
389                    crr_state.layer[stm::gStmLayerNoApps].is_changed,
390                    stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoApps].state],
391                    &json_tmp);
392     json_object_array_add(json_layer, json_tmp);
393
394     //         {
395     //             "restriction": {
396     //                 "is_changed": <bool>,
397     //                 "state": <const char*>
398     //             }
399     //         },
400     json_tmp = json_object_new_object();
401     addStateToJson("restriction",
402                    crr_state.layer[stm::gStmLayerNoRestriction].is_changed,
403                    stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoRestriction].state],
404                    &json_tmp);
405     json_object_array_add(json_layer, json_tmp);
406
407     //         {
408     //             "on_screen": {
409     //                 "is_changed": <bool>,
410     //                 "state": <const char*>
411     //             }
412     //         },
413     json_tmp = json_object_new_object();
414     addStateToJson("on_screen",
415                    crr_state.layer[stm::gStmLayerNoOnScreen].is_changed,
416                    stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoOnScreen].state],
417                    &json_tmp);
418     json_object_array_add(json_layer, json_tmp);
419
420     // Add json array of layer
421     json_object_object_add(json_out, "layers", json_layer);
422
423     // Notify state is changed
424     if (nullptr != pm::callback.onStateTransitioned) {
425         pm::callback.onStateTransitioned(json_out);
426     }
427
428     if (crr_state.car.is_changed) {
429         if (stm::gStmCarStateNoRun == crr_state.car.state) {
430             // Set delay event(restriction mode on)
431             checkPolicyEntry(STM_EVT_NO_RESTRICTION_MODE_ON, 3000);
432         }
433         else if (stm::gStmCarStateNoStop == crr_state.car.state) {
434             // Set event(restriction mode off)
435             checkPolicyEntry(STM_EVT_NO_RESTRICTION_MODE_OFF, 0);
436
437             // Stop timer for restriction on event
438             if (pm::event_source_list.find(STM_EVT_NO_RESTRICTION_MODE_ON)
439               != pm::event_source_list.end()) {
440                 HMI_DEBUG("wm:pm", "Stop timer for restriction on");
441                 sd_event_source *event_source
442                     = pm::event_source_list[STM_EVT_NO_RESTRICTION_MODE_ON];
443                 int ret = sd_event_source_set_enabled(event_source, SD_EVENT_OFF);
444                 if (0 > ret) {
445                     HMI_ERROR("wm:pm", "Failed to stop timer");
446                 }
447             }
448         }
449     }
450
451     // Release json_object
452     json_object_put(json_out);
453
454     // Release data
455     delete (int*)data;
456
457     // Destroy sd_event_source object
458     sd_event_source_unref(source);
459
460     // Remove event source from list
461     if (pm::event_source_list.find(event) != pm::event_source_list.end()) {
462         pm::event_source_list.erase(event);
463     }
464
465     HMI_DEBUG("wm:pm", ">>>>>>>>>> FINISH CHECK POLICY");
466     return 0;
467 }
468
469 static int timerEvent(sd_event_source *source, uint64_t usec, void *data) {
470     checkPolicy(source, data);
471 };
472
473 static int checkPolicyEntry(int event, uint64_t delay_ms)
474 {
475     HMI_DEBUG("wm:pm", "Call");
476     HMI_DEBUG("wm:pm", "event:0x%x", event);
477
478     if (0 == delay_ms) {
479         int ret = sd_event_add_defer(pm::event_loop, NULL,
480                                      &checkPolicy, new int(event));
481         if (0 > ret) {
482             HMI_ERROR("wm:pm", "Faild to sd_event_add_defer: errno:%d", ret);
483             return -1;
484         }
485     }
486     else {
487         // Get current time
488         struct timespec time_spec;
489         clock_gettime(CLOCK_MONOTONIC, &time_spec);
490
491         // Calculate timer fired time
492         uint64_t usec = (time_spec.tv_sec * 1000000)
493             + (time_spec.tv_nsec / 1000)
494             + (delay_ms * 1000);
495
496         // Set timer
497         struct sd_event_source* event_source;
498         int ret = sd_event_add_time(pm::event_loop, &event_source, CLOCK_MONOTONIC, usec, 1,
499                                     &timerEvent, new int(event));
500         if (0 > ret) {
501             HMI_ERROR("wm:pm", "Faild to sd_event_add_time: errno:%d", ret);
502             return -1;
503         }
504
505         // Store event source
506         pm::event_source_list[event] = event_source;
507     }
508
509     return 0;
510 }
511
512 void PolicyManager::registerCallback(CallbackTable callback) {
513     pm::callback.onStateTransitioned = callback.onStateTransitioned;
514     pm::callback.onError             = callback.onError;
515 }
516
517 int PolicyManager::inputEvent(json_object* json_in) {
518     HMI_DEBUG("wm:pm", "Call");
519
520     // Check arguments
521     if (nullptr == json_in) {
522         HMI_ERROR("wm:pm", "Argument is NULL!!");
523         return -1;
524     }
525
526     // Get event from json_object
527     const char* event = this->getStringFromJson(json_in, "event");
528     int event_no = 0;
529     if (nullptr != event) {
530         // Convert name to number
531         event_no = this->eventname2no_[event];
532         HMI_DEBUG("wm:pm", "event(%s:%d)", event, event_no);
533     }
534
535     // Get role from json_object
536     const char* role = this->getStringFromJson(json_in, "role");
537     int category_no = 0;
538     if (nullptr != role) {
539         HMI_DEBUG("wm:pm", "role(%s)", role);
540
541         // Convert role to category
542         const char* category = this->role2category_[role].c_str();
543         if (0 == strcmp("", category)) {
544             HMI_ERROR("wm:pm", "Error!!");
545             return -1;
546         }
547         HMI_DEBUG("wm:pm", "category(%s)", category);
548
549         // Convert name to number
550         category_no = categoryname2no_[category];
551         HMI_DEBUG("wm:pm", "role(%s), category(%s:%d)", role, category, category_no);
552     }
553
554     // Get areat from json_object
555     const char* area = this->getStringFromJson(json_in, "area");
556     int area_no = 0;
557     if (nullptr != area) {
558         // Convert name to number
559         area_no = areaname2no_[area];
560         HMI_DEBUG("wm:pm", "area(%s:%d)", area, area_no);
561     }
562
563     // Check policy
564     checkPolicyEntry((event_no | category_no | area_no), 0);
565
566     return 0;
567 }
568
569 std::string PolicyManager::roleToCategory(const char* role) {
570     return this->role2category_[role];
571 }
572
573 extern const char* kDefaultRoleDb;
574 int PolicyManager::loadRoleDb() {
575     HMI_DEBUG("wm:pm", "Call");
576
577     std::string file_name;
578
579     // Get afm application installed dir
580     char const *afm_app_install_dir = getenv("AFM_APP_INSTALL_DIR");
581     HMI_DEBUG("wm:pm", "afm_app_install_dir:%s", afm_app_install_dir);
582
583     if (!afm_app_install_dir) {
584         HMI_ERROR("wm:pm", "AFM_APP_INSTALL_DIR is not defined");
585     }
586     else {
587         file_name = std::string(afm_app_install_dir) + std::string("/etc/role.db");
588     }
589
590     // Load role.db
591     json_object* json_obj;
592     int ret = this->inputJsonFilie(file_name.c_str(), &json_obj);
593     if (0 > ret) {
594         HMI_ERROR("wm:pm", "Could not open role.db, so use default role information");
595         json_obj = json_tokener_parse(kDefaultRoleDb);
596     }
597     HMI_DEBUG("wm:pm", "json_obj dump:%s", json_object_get_string(json_obj));
598
599     json_object* json_roles;
600     if (!json_object_object_get_ex(json_obj, "roles", &json_roles)) {
601         HMI_ERROR("wm:pm", "Parse Error!!");
602         return -1;
603     }
604
605     int len = json_object_array_length(json_roles);
606     HMI_DEBUG("wm:pm", "json_cfg len:%d", len);
607     HMI_DEBUG("wm:pm", "json_cfg dump:%s", json_object_get_string(json_roles));
608
609     json_object* json_tmp;
610     const char* category;
611     const char* roles;
612     const char* areas;
613     for (int i=0; i<len; i++) {
614         json_tmp = json_object_array_get_idx(json_roles, i);
615
616         category = this->getStringFromJson(json_tmp, "category");
617         roles =  this->getStringFromJson(json_tmp, "role");
618         areas =  this->getStringFromJson(json_tmp, "area");
619
620         if ((nullptr == category) || (nullptr == roles) || (nullptr == areas)) {
621             HMI_ERROR("wm:pm", "Parse Error!!");
622             return -1;
623         }
624
625         // Parse roles by '|'
626         std::vector<std::string> vct_roles;
627         vct_roles = this->parseString(std::string(roles), '|');
628
629         // Parse areas by '|'
630         std::vector<std::string> vct_areas;
631         vct_areas = this->parseString(std::string(areas), '|');
632
633         // Set role, category, default area
634         for (auto itr = vct_roles.begin(); itr != vct_roles.end(); ++itr) {
635             // Delete space from role and area name
636             std::string role = this->deleteSpace(*itr);
637             std::string area = this->deleteSpace(vct_areas[0]);
638
639             this->role2category_[role] = std::string(category);
640             this->role2defaultarea_[role] = area;
641         }
642
643         this->category2role_[std::string(category)] = std::string(roles);
644     }
645
646     // Check
647     HMI_DEBUG("wm:pm", "Check role2category_");
648     for (auto& x:this->role2category_){
649         HMI_DEBUG("wm:pm", "key:%s, val:%s", x.first.c_str(), x.second.c_str());
650     }
651
652     HMI_DEBUG("wm:pm", "Check role2defaultarea_");
653     for (auto& x:this->role2defaultarea_){
654         HMI_DEBUG("wm:pm", "key:%s, val:%s", x.first.c_str(), x.second.c_str());
655     }
656
657     HMI_DEBUG("wm:pm", "Check category2role_");
658     for (auto& x:this->category2role_){
659         HMI_DEBUG("wm:pm", "key:%s, val:%s", x.first.c_str(), x.second.c_str());
660     }
661
662     return 0;
663 }
664
665 // TODO:
666 // This function will be removed because json_helper has same function.
667 // json_helper should be library.
668 const char* PolicyManager::getStringFromJson(json_object* obj, const char* key) {
669     if ((nullptr == obj) || (nullptr == key)) {
670         HMI_ERROR("wm:pm", "Argument is nullptr!!!");
671         return nullptr;
672     }
673
674     json_object* tmp;
675     if (!json_object_object_get_ex(obj, key, &tmp)) {
676         HMI_DEBUG("wm:pm", "Not found key \"%s\"", key);
677         return nullptr;
678     }
679
680     return json_object_get_string(tmp);
681 }
682
683 // TODO:
684 // This function will be removed because json_helper has same function.
685 // json_helper should be library.
686 int PolicyManager::inputJsonFilie(const char* file, json_object** obj) {
687     const int input_size = 128;
688     int ret = -1;
689
690     if ((nullptr == file) || (nullptr == obj)) {
691         HMI_ERROR("wm:jh", "Argument is nullptr!!!");
692         return ret;
693     }
694
695     HMI_DEBUG("wm:jh", "Input file: %s", file);
696
697     // Open json file
698     FILE *fp = fopen(file, "rb");
699     if (nullptr == fp) {
700         HMI_ERROR("wm:jh", "Could not open file");
701         return ret;
702     }
703
704     // Parse file data
705     struct json_tokener *tokener = json_tokener_new();
706     enum json_tokener_error json_error;
707     char buffer[input_size];
708     int block_cnt = 1;
709     while (1) {
710         size_t len = fread(buffer, sizeof(char), input_size, fp);
711         *obj = json_tokener_parse_ex(tokener, buffer, len);
712         if (nullptr != *obj) {
713             HMI_DEBUG("wm:jh", "File input is success");
714             ret = 0;
715             break;
716         }
717
718         json_error = json_tokener_get_error(tokener);
719         if ((json_tokener_continue != json_error)
720             || (input_size > len)) {
721             HMI_ERROR("wm:jh", "Failed to parse file (byte:%d err:%s)",
722                       (input_size * block_cnt), json_tokener_error_desc(json_error));
723             HMI_ERROR("wm:jh", "\n%s", buffer);
724             *obj = nullptr;
725             break;
726         }
727         block_cnt++;
728     }
729
730     // Close json file
731     fclose(fp);
732
733     // Free json_tokener
734     json_tokener_free(tokener);
735
736     return ret;
737 }
738
739 std::vector<std::string> PolicyManager::parseString(std::string str, char delimiter) {
740     // Parse string by delimiter
741     std::vector<std::string> vct;
742     std::stringstream ss{str};
743     std::string buf;
744     while (std::getline(ss, buf, delimiter)) {
745       if (!buf.empty()) {
746         vct.push_back(buf);
747       }
748     }
749     return vct;
750 }
751
752 std::string PolicyManager::deleteSpace(std::string str) {
753     std::string ret = str;
754     size_t pos;
755     while ((pos = ret.find_first_of(" ")) != std::string::npos) {
756       ret.erase(pos, 1);
757     }
758     return ret;
759 }
760
761 const char* kDefaultRoleDb = "{ \
762     \"roles\":[ \
763     { \
764         \"category\": \"homescreen\", \
765         \"role\": \"homescreen\", \
766         \"area\": \"full\", \
767     }, \
768     { \
769         \"category\": \"map\", \
770         \"role\": \"map\", \
771         \"area\": \"full | normal | split.main\", \
772     }, \
773     { \
774         \"category\": \"general\", \
775         \"role\": \"poi | music | video | browser | sdl | settings | mixer | radio | hvac | dashboard | debug\", \
776         \"area\": \"normal\", \
777     }, \
778     { \
779         \"category\": \"phone\", \
780         \"role\": \"phone\", \
781         \"area\": \"normal\", \
782     }, \
783     { \
784         \"category\": \"splitable\", \
785         \"role\": \"splitable1 | splitable2\", \
786         \"area\": \"normal | split.main | split.sub\", \
787     }, \
788     { \
789         \"category\": \"popup\", \
790         \"role\": \"popup\", \
791         \"area\": \"on_screen\", \
792     }, \
793     { \
794         \"category\": \"system_alert\", \
795         \"role\": \"system_alert\", \
796         \"area\": \"on_screen\", \
797     }, \
798     { \
799         \"category\": \"tbt\", \
800         \"role\": \"tbt\", \
801         \"area\": \"hud\", \
802     } \
803     ] \
804 }";