PolicyManager uses layout information
[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 LayoutState g_default_layout_state;
47 }  // namespace pm
48
49
50 PolicyManager::PolicyManager() :
51   eventname2no_(),
52   categoryname2no_(),
53   areaname2no_(),
54   role2category_(),
55   category2role_(),
56   role2defaultarea_()
57 {
58     HMI_DEBUG("wm:pm", "Call");
59 }
60
61 int PolicyManager::initialize() {
62     HMI_DEBUG("wm:pm", "Call");
63
64     int ret = 0;
65
66     // Create convert map
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];
70     }
71
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];
75     }
76
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];
80     }
81
82     // Load role.db
83     ret = this->loadRoleDb();
84     if (0 > ret) {
85         HMI_ERROR("wm:pm", "Load role.db Error!!");
86         return ret;
87     }
88
89     // Load layout.db
90     ret = this->loadLayoutDb();
91     if (0 > ret) {
92         HMI_ERROR("wm:pm", "Load layout.db Error!!");
93         return ret;
94     }
95
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;
103
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;
109
110     // Initialize StateTransitioner
111     stm::stmInitialize();
112
113     // Initialize sd_event loop
114     ret = this->initializeSdEventLoop();
115     if (0 > ret) {
116         HMI_ERROR("wm:pm", "Failed to initializeSdEventLoop!!");
117         return ret;
118     }
119
120     return ret;
121 }
122
123 int PolicyManager::initializeSdEventLoop() {
124     // Get default event loop object
125     int ret = sd_event_new(&(pm::event_loop));
126     if (0 > ret) {
127         HMI_ERROR("wm:pm", "Faild to sd_event_default: errno:%d", ret);
128         return -1;
129     }
130
131     // Create thread for sd_event and detach
132     std::thread sd_event_loop([this]() {
133         while (1) {
134             sd_event_run(pm::event_loop, 1000);
135         }
136     });
137     sd_event_loop.detach();
138
139     return 0;
140 }
141
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!!!");
146         return;
147     }
148
149     json_object* json_obj = json_object_new_object();
150     json_object_object_add(json_obj, "is_changed", json_object_new_boolean(is_changed));
151     if (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));
154     }
155     json_object_object_add(*json_out, key, json_obj);
156 }
157
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");
162
163     int event = *((int*)data);
164
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]);
173
174     // Transition state
175     stm::stm_state_t crr_state;
176     int ret = stm::stmTransitionState(event, &crr_state);
177     if (0 > ret) {
178         HMI_ERROR("wm:pm", "Error!!");
179         return -1;
180     }
181
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,
196               crr_state.car.state,
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]);
222
223 #if 0 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
224     // Store previous layers
225     pm::g_prv_layers = pm::g_crr_layers;
226
227     std::string layer_name = "homescreen";
228
229     // changed?
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();
234
235         // Get current layout name of this layer
236         std::string crr_layout_name = std::string(stm::gStmLayoutNo2Name[crr_state.layer[stm::gStmLayerNoHomescreen].state]);
237
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;
250         }
251         else {
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];
256             }
257             else {
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];
261             }
262
263             // Update role in new area
264 #if 1
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");
270 #else
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");
276 #endif
277                 }
278                 else {
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],
282                                                              new_role, category);
283
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");
286                     }
287                     else {
288                         // Is there new_area?
289                         // if there is new_area, set new role there
290
291                         // if NOT, find same category of new_role
292                             // pop old role and shift area
293                             // push new role and set area
294
295
296                         // Update role in new area
297                         // because new_role is specified for this layer
298                         TypeRolCtg crr_role;
299                         crr_role["role"] = std::string(new_role);
300                         crr_layout[crr_layout_name][new_area] = crr_role;
301                     }
302                 }
303             }
304         }
305
306         // Update current layout of this layer
307         pm::g_crr_layers[layer_name] = crr_layout_state;
308
309     }
310 #endif // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
311
312     json_object* json_out = json_object_new_object();
313
314     // Create result
315     // {
316     //     "parking_brake": {
317     //         "is_changed": <bool>,
318     //         "state": <const char*>
319     //     },
320     addStateToJson("parking_brake",
321                    crr_state.parking_brake.is_changed,
322                    stm::gStmParkingBrakeStateNo2Name[crr_state.parking_brake.state],
323                    &json_out);
324
325     //     "accel_pedal": {
326     //         "is_changed": <bool>,
327     //         "state": <const char*>
328     //     },
329     addStateToJson("accel_pedal",
330                    crr_state.accel_pedal.is_changed,
331                    stm::gStmAccelPedalStateNo2Name[crr_state.accel_pedal.state],
332                    &json_out);
333
334     //     "lightstatus_brake": {
335     //         "is_changed": <bool>,
336     //         "state": <const char*>
337     //     },
338     addStateToJson("lightstatus_brake",
339                    crr_state.lightstatus_brake.is_changed,
340                    stm::gStmLightstatusBrakeStateNo2Name[crr_state.lightstatus_brake.state],
341                    &json_out);
342
343     //     "car": {
344     //         "is_changed": <bool>,
345     //         "state": <const char*>
346     //     },
347     addStateToJson("car",
348                    crr_state.car.is_changed,
349                    stm::gStmCarStateNo2Name[crr_state.car.state],
350                    &json_out);
351
352     //     "lamp": {
353     //         "is_changed": <bool>,
354     //         "state": <const char*>
355     //     },
356     addStateToJson("lamp",
357                    crr_state.lamp.is_changed,
358                    stm::gStmLampStateNo2Name[crr_state.lamp.state],
359                    &json_out);
360
361     //     "restriction_mode": {
362     //         "is_changed": <bool>,
363     //         "state": <const char*>
364     //     },
365     addStateToJson("restriction_mode",
366                    crr_state.restriction_mode.is_changed,
367                    stm::gStmRestrictionModeStateNo2Name[crr_state.restriction_mode.state],
368                    &json_out);
369
370     //     "layers": [
371     json_object* json_layer = json_object_new_array();
372     json_object* json_tmp;
373
374     //         {
375     //             "homescreen": {
376     //                 "is_changed": <bool>,
377     //                 "state": <const char*>
378     //             }
379     //         },
380     //     ]
381     // }
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],
386                    &json_tmp);
387     json_object_array_add(json_layer, json_tmp);
388
389     //         {
390     //             "apps": {
391     //                 "is_changed": <bool>,
392     //                 "state": <const char*>
393     //             }
394     //         },
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],
399                    &json_tmp);
400     json_object_array_add(json_layer, json_tmp);
401
402     //         {
403     //             "restriction": {
404     //                 "is_changed": <bool>,
405     //                 "state": <const char*>
406     //             }
407     //         },
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],
412                    &json_tmp);
413     json_object_array_add(json_layer, json_tmp);
414
415     //         {
416     //             "on_screen": {
417     //                 "is_changed": <bool>,
418     //                 "state": <const char*>
419     //             }
420     //         },
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],
425                    &json_tmp);
426     json_object_array_add(json_layer, json_tmp);
427
428     // Add json array of layer
429     json_object_object_add(json_out, "layers", json_layer);
430
431     // Notify state is changed
432     if (nullptr != pm::callback.onStateTransitioned) {
433         pm::callback.onStateTransitioned(json_out);
434     }
435
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);
440         }
441         else if (stm::gStmCarStateNoStop == crr_state.car.state) {
442             // Set event(restriction mode off)
443             checkPolicyEntry(STM_EVT_NO_RESTRICTION_MODE_OFF, 0);
444
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);
452                 if (0 > ret) {
453                     HMI_ERROR("wm:pm", "Failed to stop timer");
454                 }
455             }
456         }
457     }
458
459     // Release json_object
460     json_object_put(json_out);
461
462     // Release data
463     delete (int*)data;
464
465     // Destroy sd_event_source object
466     sd_event_source_unref(source);
467
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);
471     }
472
473     HMI_DEBUG("wm:pm", ">>>>>>>>>> FINISH CHECK POLICY");
474     return 0;
475 }
476
477 static int timerEvent(sd_event_source *source, uint64_t usec, void *data) {
478     checkPolicy(source, data);
479 };
480
481 static int checkPolicyEntry(int event, uint64_t delay_ms)
482 {
483     HMI_DEBUG("wm:pm", "Call");
484     HMI_DEBUG("wm:pm", "event:0x%x", event);
485
486     if (0 == delay_ms) {
487         int ret = sd_event_add_defer(pm::event_loop, NULL,
488                                      &checkPolicy, new int(event));
489         if (0 > ret) {
490             HMI_ERROR("wm:pm", "Faild to sd_event_add_defer: errno:%d", ret);
491             return -1;
492         }
493     }
494     else {
495         // Get current time
496         struct timespec time_spec;
497         clock_gettime(CLOCK_MONOTONIC, &time_spec);
498
499         // Calculate timer fired time
500         uint64_t usec = (time_spec.tv_sec * 1000000)
501             + (time_spec.tv_nsec / 1000)
502             + (delay_ms * 1000);
503
504         // Set timer
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));
508         if (0 > ret) {
509             HMI_ERROR("wm:pm", "Faild to sd_event_add_time: errno:%d", ret);
510             return -1;
511         }
512
513         // Store event source
514         pm::event_source_list[event] = event_source;
515     }
516
517     return 0;
518 }
519
520 void PolicyManager::registerCallback(CallbackTable callback) {
521     pm::callback.onStateTransitioned = callback.onStateTransitioned;
522     pm::callback.onError             = callback.onError;
523 }
524
525 int PolicyManager::inputEvent(json_object* json_in) {
526     HMI_DEBUG("wm:pm", "Call");
527
528     // Check arguments
529     if (nullptr == json_in) {
530         HMI_ERROR("wm:pm", "Argument is NULL!!");
531         return -1;
532     }
533
534     // Get event from json_object
535     const char* event = this->getStringFromJson(json_in, "event");
536     int event_no = 0;
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);
541     }
542
543     // Get role from json_object
544     const char* role = this->getStringFromJson(json_in, "role");
545     int category_no = 0;
546     if (nullptr != role) {
547         HMI_DEBUG("wm:pm", "role(%s)", role);
548
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!!");
553             return -1;
554         }
555         HMI_DEBUG("wm:pm", "category(%s)", category);
556
557         // Convert name to number
558         category_no = categoryname2no_[category];
559         HMI_DEBUG("wm:pm", "role(%s), category(%s:%d)", role, category, category_no);
560     }
561
562     // Get areat from json_object
563     const char* area = this->getStringFromJson(json_in, "area");
564     int area_no = 0;
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);
569     }
570
571     // Check policy
572     checkPolicyEntry((event_no | category_no | area_no), 0);
573
574     return 0;
575 }
576
577 std::string PolicyManager::roleToCategory(const char* role) {
578     return this->role2category_[role];
579 }
580
581 extern const char* kDefaultRoleDb;
582 int PolicyManager::loadRoleDb() {
583     HMI_DEBUG("wm:pm", "Call");
584
585     std::string file_name;
586
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);
590
591     if (!afm_app_install_dir) {
592         HMI_ERROR("wm:pm", "AFM_APP_INSTALL_DIR is not defined");
593     }
594     else {
595         file_name = std::string(afm_app_install_dir) + std::string("/etc/role.db");
596     }
597
598     // Load role.db
599     json_object* json_obj;
600     int ret = this->inputJsonFilie(file_name.c_str(), &json_obj);
601     if (0 > ret) {
602         HMI_ERROR("wm:pm", "Could not open role.db, so use default role information");
603         json_obj = json_tokener_parse(kDefaultRoleDb);
604     }
605     HMI_DEBUG("wm:pm", "json_obj dump:%s", json_object_get_string(json_obj));
606
607     json_object* json_roles;
608     if (!json_object_object_get_ex(json_obj, "roles", &json_roles)) {
609         HMI_ERROR("wm:pm", "Parse Error!!");
610         return -1;
611     }
612
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));
616
617     json_object* json_tmp;
618     const char* category;
619     const char* roles;
620     const char* areas;
621     for (int i=0; i<len; i++) {
622         json_tmp = json_object_array_get_idx(json_roles, i);
623
624         category = this->getStringFromJson(json_tmp, "category");
625         roles =  this->getStringFromJson(json_tmp, "role");
626         areas =  this->getStringFromJson(json_tmp, "area");
627
628         if ((nullptr == category) || (nullptr == roles) || (nullptr == areas)) {
629             HMI_ERROR("wm:pm", "Parse Error!!");
630             return -1;
631         }
632
633         // Parse roles by '|'
634         std::vector<std::string> vct_roles;
635         vct_roles = this->parseString(std::string(roles), '|');
636
637         // Parse areas by '|'
638         std::vector<std::string> vct_areas;
639         vct_areas = this->parseString(std::string(areas), '|');
640
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]);
646
647             this->role2category_[role] = std::string(category);
648             this->role2defaultarea_[role] = area;
649         }
650
651         this->category2role_[std::string(category)] = std::string(roles);
652     }
653
654     // Check
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());
658     }
659
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());
663     }
664
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());
668     }
669
670     return 0;
671 }
672
673 extern const char* kDefaultLayoutDb;
674 int PolicyManager::loadLayoutDb() {
675     HMI_DEBUG("wm:lm", "Call");
676
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);
680
681     std::string file_name;
682     if (!afm_app_install_dir) {
683         HMI_ERROR("wm:pm", "AFM_APP_INSTALL_DIR is not defined");
684     }
685     else {
686         file_name = std::string(afm_app_install_dir) + std::string("/etc/layout.db");
687     }
688
689     // Load layout.db
690     json_object* json_obj;
691     int ret = this->inputJsonFilie(file_name.c_str(), &json_obj);
692     if (0 > ret) {
693         HMI_DEBUG("wm:pm", "Could not open layout.db, so use default layout information");
694         json_obj = json_tokener_parse(kDefaultLayoutDb);
695     }
696     HMI_DEBUG("wm:pm", "json_obj dump:%s", json_object_get_string(json_obj));
697
698     // Perse layouts
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!!");
703         return -1;
704     }
705
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));
709
710     const char* layout;
711     const char* role;
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);
715
716         layout = this->getStringFromJson(json_tmp, "name");
717         if (nullptr == layout) {
718             HMI_ERROR("wm:pm", "Parse Error!!");
719             return -1;
720         }
721         HMI_DEBUG("wm:pm", "> layout:%s", layout);
722
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!!");
726           return -1;
727         }
728
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));
732
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);
736
737             // Get area name
738             const char* area = this->getStringFromJson(json_area, "name");
739             if (nullptr == area) {
740               HMI_ERROR("wm:pm", "Parse Error!!");
741               return -1;
742             }
743             HMI_DEBUG("wm:pm", ">> area:%s", area);
744
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!!");
750                 return -1;
751             }
752             app_attribute["category"] = std::string(category);
753             HMI_DEBUG("wm:pm", ">>> category:%s", category);
754
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);
760             }
761
762             areas_state[area] = app_attribute;
763         }
764
765         pm::g_default_layout_state[layout] = areas_state;
766     }
767
768     // Check
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());
772
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());
776
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());
781             }
782         }
783     }
784
785     // Release json_object
786     json_object_put(json_obj);
787
788     return 0;
789 }
790
791 // TODO:
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!!!");
797         return nullptr;
798     }
799
800     json_object* tmp;
801     if (!json_object_object_get_ex(obj, key, &tmp)) {
802         HMI_DEBUG("wm:pm", "Not found key \"%s\"", key);
803         return nullptr;
804     }
805
806     return json_object_get_string(tmp);
807 }
808
809 // TODO:
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;
814     int ret = -1;
815
816     if ((nullptr == file) || (nullptr == obj)) {
817         HMI_ERROR("wm:jh", "Argument is nullptr!!!");
818         return ret;
819     }
820
821     HMI_DEBUG("wm:jh", "Input file: %s", file);
822
823     // Open json file
824     FILE *fp = fopen(file, "rb");
825     if (nullptr == fp) {
826         HMI_ERROR("wm:jh", "Could not open file");
827         return ret;
828     }
829
830     // Parse file data
831     struct json_tokener *tokener = json_tokener_new();
832     enum json_tokener_error json_error;
833     char buffer[input_size];
834     int block_cnt = 1;
835     while (1) {
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");
840             ret = 0;
841             break;
842         }
843
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);
850             *obj = nullptr;
851             break;
852         }
853         block_cnt++;
854     }
855
856     // Close json file
857     fclose(fp);
858
859     // Free json_tokener
860     json_tokener_free(tokener);
861
862     return ret;
863 }
864
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};
869     std::string buf;
870     while (std::getline(ss, buf, delimiter)) {
871       if (!buf.empty()) {
872         vct.push_back(buf);
873       }
874     }
875     return vct;
876 }
877
878 std::string PolicyManager::deleteSpace(std::string str) {
879     std::string ret = str;
880     size_t pos;
881     while ((pos = ret.find_first_of(" ")) != std::string::npos) {
882       ret.erase(pos, 1);
883     }
884     return ret;
885 }
886
887 const char* kDefaultRoleDb = "{ \
888     \"roles\":[ \
889     { \
890         \"category\": \"homescreen\", \
891         \"role\": \"homescreen\", \
892         \"area\": \"full\", \
893     }, \
894     { \
895         \"category\": \"map\", \
896         \"role\": \"map\", \
897         \"area\": \"full | normal | split.main\", \
898     }, \
899     { \
900         \"category\": \"general\", \
901         \"role\": \"poi | music | video | browser | sdl | settings | mixer | radio | hvac | dashboard | debug\", \
902         \"area\": \"normal\", \
903     }, \
904     { \
905         \"category\": \"phone\", \
906         \"role\": \"phone\", \
907         \"area\": \"normal\", \
908     }, \
909     { \
910         \"category\": \"splitable\", \
911         \"role\": \"splitable1 | splitable2\", \
912         \"area\": \"normal | split.main | split.sub\", \
913     }, \
914     { \
915         \"category\": \"popup\", \
916         \"role\": \"popup\", \
917         \"area\": \"on_screen\", \
918     }, \
919     { \
920         \"category\": \"system_alert\", \
921         \"role\": \"system_alert\", \
922         \"area\": \"on_screen\", \
923     }, \
924     { \
925         \"category\": \"tbt\", \
926         \"role\": \"tbt\", \
927         \"area\": \"hud\", \
928     } \
929     ] \
930 }";
931
932
933 const char* kDefaultLayoutDb = "{ \
934     \"layouts\": [ \
935         { \
936             \"name\": \"pu\", \
937             \"layer\": \"on_screen\", \
938             \"areas\": [ \
939                 { \
940                     \"name\": \"pop_up\", \
941                     \"role\": \"incomming_call\" \
942                 } \
943             ] \
944         }, \
945         { \
946             \"name\": \"sa\", \
947             \"layer\": \"on_screen\", \
948             \"areas\": [ \
949                 { \
950                     \"name\": \"system_alert\", \
951                     \"role\": \"system_alert\" \
952                 } \
953             ] \
954         }, \
955         { \
956             \"name\": \"m1\", \
957             \"layer\": \"apps\", \
958             \"areas\": [ \
959                 { \
960                     \"name\": \"normal\", \
961                     \"role\": \"map\" \
962                 } \
963             ] \
964         }, \
965         { \
966             \"name\": \"m2\", \
967             \"layer\": \"apps\", \
968             \"areas\": [ \
969                 { \
970                     \"name\": \"split.main\", \
971                     \"role\": \"map\" \
972                 }, \
973                 { \
974                     \"name\": \"split.sub\", \
975                     \"category\": \"hvac\" \
976                 } \
977             ] \
978         }, \
979         { \
980             \"name\": \"mf\", \
981             \"layer\": \"apps\", \
982             \"areas\": [ \
983                 { \
984                     \"name\": \"full\", \
985                     \"role\": \"map\" \
986                 } \
987             ] \
988         }, \
989         { \
990             \"name\": \"s1\", \
991             \"layer\": \"apps\", \
992             \"areas\": [ \
993                 { \
994                     \"name\": \"normal\", \
995                     \"category\": \"splitable\" \
996                 } \
997             ] \
998         }, \
999         { \
1000             \"name\": \"s2\", \
1001             \"layer\": \"apps\", \
1002             \"areas\": [ \
1003                 { \
1004                     \"name\": \"split.main\", \
1005                     \"category\": \"splitable\" \
1006                 }, \
1007                 { \
1008                     \"name\": \"split.sub\", \
1009                     \"category\": \"splitable\" \
1010                 } \
1011             ] \
1012         }, \
1013         { \
1014             \"name\": \"g\", \
1015             \"layer\": \"apps\", \
1016             \"areas\": [ \
1017                 { \
1018                     \"name\": \"normal\", \
1019                     \"category\": \"general\" \
1020                 } \
1021             ] \
1022         }, \
1023         { \
1024             \"name\": \"hs\", \
1025             \"layer\": \"homescreen\", \
1026             \"areas\": [ \
1027                 { \
1028                     \"name\": \"full\", \
1029                     \"role\": \"homescreen\" \
1030                 } \
1031             ] \
1032         } \
1033     ], \
1034     \"areas\": [ \
1035         { \
1036             \"name\": \"normal\", \
1037             \"rect\": { \
1038                 \"x\": 0, \
1039                 \"y\": 218, \
1040                 \"w\": 1080, \
1041                 \"h\": 1488 \
1042             } \
1043         }, \
1044         { \
1045             \"name\": \"split.main\", \
1046             \"rect\": { \
1047                 \"x\": 0, \
1048                 \"y\": 218, \
1049                 \"w\": 1080, \
1050                 \"h\": 744 \
1051             } \
1052         }, \
1053         { \
1054             \"name\": \"split.sub\", \
1055             \"rect\": { \
1056                 \"x\": 0, \
1057                 \"y\": 962, \
1058                 \"w\": 1080, \
1059                 \"h\": 744 \
1060             } \
1061         }, \
1062         { \
1063             \"name\": \"full\", \
1064             \"rect\": { \
1065                 \"x\": 0, \
1066                 \"y\": 0, \
1067                 \"w\": 1080, \
1068                 \"h\": 1920 \
1069             } \
1070         }, \
1071         { \
1072             \"name\": \"pop_up\", \
1073             \"rect\": { \
1074                 \"x\": 0, \
1075                 \"y\": 640, \
1076                 \"w\": 1080, \
1077                 \"h\": 640 \
1078             } \
1079         }, \
1080         { \
1081             \"name\": \"system_alert\", \
1082             \"rect\": { \
1083                 \"x\": 0, \
1084                 \"y\": 640, \
1085                 \"w\": 1080, \
1086                 \"h\": 640 \
1087             } \
1088         } \
1089     ] \
1090 }";