Add gitlab issue/merge request templates
[apps/agl-service-windowmanager.git] / policy_manager / policy_manager.cpp
1 /*
2  * Copyright (c) 2018 TOYOTA MOTOR CORPORATION
3  * Copyright (c) 2018 Konsulko Group
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <fstream>
19 #include <sstream>
20 #include <istream>
21 #include <thread>
22 #include <map>
23 #include <algorithm>
24 #include <json-c/json.h>
25 #include "policy_manager.hpp"
26 #include "util.hpp"
27
28 extern "C"
29 {
30 #define AFB_BINDING_VERSION 3
31 #include <afb/afb-binding.h>
32 #include <systemd/sd-event.h>
33 #include "stm.h"
34 }
35
36 namespace pm
37 {
38 static const int kInvisibleRoleHistoryNum = 5;
39
40 static PolicyManager *g_context;
41
42 static int transitionStateWrapper(sd_event_source *source, void *data)
43 {
44     int ret = g_context->transitionState(source, data);
45     return ret;
46 }
47
48 static int timerEventWrapper(sd_event_source *source, uint64_t usec, void *data)
49 {
50     int ret = g_context->timerEvent(source, usec, data);
51     return ret;
52 }
53
54 } // namespace pm
55
56 PolicyManager::PolicyManager()
57     : eventname2no(),
58       categoryname2no(),
59       areaname2no(),
60       role2category(),
61       category2role(),
62       category2areas()
63 {}
64
65 int PolicyManager::initialize()
66 {
67     int ret = 0;
68
69     // Create convert map
70     for (int i = StmEvtNoMin; i <= StmEvtNoMax; i++)
71     {
72         HMI_DEBUG("event name:%s no:%d", kStmEventName[i], i);
73         this->eventname2no[kStmEventName[i]] = i;
74     }
75
76     for (int i = StmCtgNoMin; i <= StmCtgNoMax; i++)
77     {
78         HMI_DEBUG("category name:%s no:%d", kStmCategoryName[i], i);
79         this->categoryname2no[kStmCategoryName[i]] = i;
80     }
81
82     for (int i = StmAreaNoMin; i <= StmAreaNoMax; i++)
83     {
84         HMI_DEBUG("area name:%s no:%d", kStmAreaName[i], i);
85         this->areaname2no[kStmAreaName[i]] = i;
86     }
87
88     // Load roles.db
89     ret = this->loadRoleDb();
90     if (0 > ret)
91     {
92         HMI_ERROR("Load roles.db Error!!");
93         return ret;
94     }
95
96     // Load states.db
97     ret = this->loadStateDb();
98     if (0 > ret)
99     {
100         HMI_ERROR("Load states.db Error!!");
101         return ret;
102     }
103
104     // Initialize state which is managed by PolicyManager
105     this->initializeState();
106
107     // Initialize StateTransitioner
108     stmInitialize();
109
110     // Store instance
111     pm::g_context = this;
112
113     return ret;
114 }
115
116 void PolicyManager::registerCallback(CallbackTable callback)
117 {
118     this->callback.onStateTransitioned = callback.onStateTransitioned;
119     this->callback.onError = callback.onError;
120 }
121
122 int PolicyManager::setInputEventData(json_object *json_in)
123 {
124     // Check arguments
125     if (nullptr == json_in)
126     {
127         HMI_ERROR("Argument is NULL!!");
128         return -1;
129     }
130
131     // Get event from json_object
132     const char *event = this->getStringFromJson(json_in, "event");
133     int event_no = StmEvtNoNone;
134     if (nullptr != event)
135     {
136         // Convert name to number
137         auto itr = this->eventname2no.find(event);
138         if (this->eventname2no.end() != itr)
139         {
140             event_no = this->eventname2no[event];
141             HMI_DEBUG("event(%s:%d)", event, event_no);
142         }
143         else
144         {
145             HMI_ERROR("Invalid event name!!");
146             return -1;
147         }
148     }
149     else
150     {
151         HMI_ERROR("Event is not set!!");
152         return -1;
153     }
154
155     // Get role from json_object
156     const char *role = this->getStringFromJson(json_in, "role");
157     std::string category = "";
158     int category_no = StmCtgNoNone;
159     if (nullptr != role)
160     {
161         HMI_DEBUG("role(%s)", role);
162
163         // Convert role to category
164         auto itr = this->role2category.find(role);
165         if (this->role2category.end() != itr)
166         {
167             category = this->role2category[role];
168         }
169         else
170         {
171             itr = this->role2category.find("fallback");
172             if (this->role2category.end() != itr)
173             {
174                 HMI_DEBUG("Role:%s is not registered in roles.db, fallback as normal app", role);
175                 category = this->role2category["fallback"];
176             }
177         }
178
179         if ("" != category)
180         {
181             // Convert name to number
182             category_no = categoryname2no[category];
183             HMI_DEBUG("category(%s:%d)", category.c_str(), category_no);
184         }
185     }
186     if (StmCtgNoNone == category_no)
187     {
188         role = "";
189     }
190
191     // Get area from json_object
192     const char *area = this->getStringFromJson(json_in, "area");
193     int area_no = StmAreaNoNone;
194     if ((nullptr != area) && (StmCtgNoNone != category_no))
195     {
196         for (const auto &x : this->category2areas[category])
197         {
198             if (x == std::string(area))
199             {
200                 area_no = this->areaname2no[area];
201                 break;
202             }
203         }
204         if (StmAreaNoNone == area_no)
205         {
206             area = this->category2areas[category].front().c_str();
207             area_no = this->areaname2no[area];
208         }
209         HMI_DEBUG("area(%s:%d)", area, area_no);
210     }
211
212     // Set event info to the queue
213     EventInfo event_info;
214     int event_id = STM_CREATE_EVENT_ID(event_no, category_no, area_no);
215     event_info.event = event_id;
216     event_info.role = std::string(role);
217     event_info.delay = 0;
218     this->event_info_queue.push(event_info);
219
220     return 0;
221 }
222
223 int PolicyManager::executeStateTransition()
224 {
225     int ret;
226     EventInfo event_info;
227
228     // Get event info from queue and delete
229     event_info = this->event_info_queue.front();
230     this->event_info_queue.pop();
231
232     // Set event info to check policy
233     ret = this->setStateTransitionProcessToSystemd(event_info.event,
234                                                    event_info.delay,
235                                                    event_info.role);
236     return ret;
237 }
238
239 void PolicyManager::undoState()
240 {
241     HMI_DEBUG("Undo State !!!");
242
243     // Undo state of STM
244     stmUndoState();
245
246     HMI_DEBUG(">>>>>>>>>> BEFORE UNDO");
247     this->dumpLayerState(this->crr_layers);
248
249     this->crr_layers = this->prv_layers;
250
251     HMI_DEBUG(">>>>>>>>>> AFTER UNDO");
252     this->dumpLayerState(this->crr_layers);
253 }
254
255 void PolicyManager::initializeState()
256 {
257     this->initializeLayerState();
258 }
259
260 void PolicyManager::initializeLayerState()
261 {
262     AreaState init_area;
263     LayoutState init_layout;
264     init_area.name = kStmAreaName[StmAreaNoNone];
265     init_area.category = kStmCategoryName[StmCtgNoNone];
266     init_area.role = "";
267     init_layout.name = kStmLayoutName[StmLayoutNoNone];
268     init_layout.area_list.push_back(init_area);
269
270     for (int i = StmLayerNoMin; i <= StmLayerNoMax; i++)
271     {
272         const char *layer_name = kStmLayerName[i];
273         this->crr_layers[layer_name].name = layer_name;
274         this->crr_layers[layer_name].layout_state = init_layout;
275         this->crr_layers[layer_name].changed = false;
276     }
277
278     this->prv_layers = this->crr_layers;
279 }
280
281 void PolicyManager::addStateToJson(const char *name, bool changed,
282                                    std::string state, json_object **json_out)
283 {
284     if ((nullptr == name) || (nullptr == json_out))
285     {
286         HMI_ERROR("Invalid argument!!!");
287         return;
288     }
289
290     json_object_object_add(*json_out, "name", json_object_new_string(name));
291     json_object_object_add(*json_out, "state", json_object_new_string(state.c_str()));
292     json_object_object_add(*json_out, "changed", json_object_new_boolean(changed));
293 }
294
295 void PolicyManager::addStateToJson(const char *layer_name, bool changed,
296                                    AreaList area_list, json_object **json_out)
297 {
298     if ((nullptr == layer_name) || (nullptr == json_out))
299     {
300         HMI_ERROR("Invalid argument!!!");
301         return;
302     }
303
304     json_object *json_areas = json_object_new_array();
305     json_object *json_tmp;
306     for (const auto &as : area_list)
307     {
308         json_tmp = json_object_new_object();
309         json_object_object_add(json_tmp, "name", json_object_new_string(as.name.c_str()));
310         json_object_object_add(json_tmp, "role", json_object_new_string(as.role.c_str()));
311         json_object_array_add(json_areas, json_tmp);
312     }
313
314     json_object_object_add(*json_out, "name", json_object_new_string(layer_name));
315     json_object_object_add(*json_out, "changed", json_object_new_boolean(changed));
316     json_object_object_add(*json_out, "areas", json_areas);
317 }
318
319 void PolicyManager::updateState(int event_id, StmState crr_state)
320 {
321     this->updateLayer(event_id, crr_state);
322 }
323
324 void PolicyManager::updateLayer(int event_id, StmState crr_state)
325 {
326     for (int layer_no = StmLayerNoMin;
327          layer_no <= StmLayerNoMax; layer_no++)
328     {
329         HMI_DEBUG(">>> LAYER:%s CHANGED:%d LAYOUT:%s",
330                   kStmLayerName[layer_no], crr_state.layer[layer_no].changed,
331                   kStmLayoutName[crr_state.layer[layer_no].state]);
332     }
333
334     // Store previous layers
335     this->prv_layers = this->crr_layers;
336
337     // Update layers
338     for (int layer_no = StmLayerNoMin;
339          layer_no <= StmLayerNoMax; layer_no++)
340     {
341         const char *layer_name = kStmLayerName[layer_no];
342
343         // This layer is changed?
344         int changed = crr_state.layer[layer_no].changed;
345         if (changed)
346         {
347             HMI_DEBUG(">>>>>>>>>> Update layout of layer:%s", layer_name);
348
349             // Get current layout name of this layer
350             int crr_layout_state_no = crr_state.layer[layer_no].state;
351             std::string crr_layout_name = std::string(kStmLayoutName[crr_layout_state_no]);
352
353             LayoutState crr_layout_state;
354             this->updateLayout(event_id, layer_no,
355                                crr_layout_name, crr_layout_state);
356
357             // Update current layout of this layer
358             this->crr_layers[layer_name].layout_state = crr_layout_state;
359         }
360         // Update changed flag
361         this->crr_layers[layer_name].changed = (changed) ? true : false;
362     }
363
364     // Erase role for the event_id from list
365     this->req_role_list.erase(event_id);
366
367     HMI_DEBUG(">>>>>>>>>> DUMP LAYERS (BEFORE)");
368     this->dumpLayerState(this->prv_layers);
369
370     HMI_DEBUG(">>>>>>>>>> DUMP LAYERS (AFTER)");
371     this->dumpLayerState(this->crr_layers);
372
373     this->dumpInvisibleRoleHistory();
374 }
375
376 int PolicyManager::updateLayout(int event_id, int layer_no,
377                                 std::string crr_layout_name, LayoutState &crr_layout_state)
378 {
379     int changed;
380
381     int event_no = STM_GET_EVENT_FROM_ID(event_id);
382     int category_no = STM_GET_CATEGORY_FROM_ID(event_id);
383     int area_no = STM_GET_AREA_FROM_ID(event_id);
384
385     std::string req_evt = kStmEventName[event_no];
386     std::string req_ctg = kStmCategoryName[category_no];
387     std::string req_area = kStmAreaName[area_no];
388     std::string req_role = this->req_role_list[event_id];
389
390     const char *layer_name = kStmLayerName[layer_no];
391
392     // Get previous layout name of this layer
393     LayoutState prv_layout_state = this->prv_layers[layer_name].layout_state;
394     std::string prv_layout_name = prv_layout_state.name;
395
396     if ((prv_layout_name == crr_layout_name) &&
397         (kStmLayoutName[StmLayoutNoNone] == crr_layout_name))
398     {
399         // If previous and current layout are none
400         // Copy previous layout state for current
401         crr_layout_state = prv_layout_state;
402         changed = 0;
403     }
404     else
405     {
406         crr_layout_state = prv_layout_state;
407         changed = 1;
408
409         HMI_DEBUG("-- layout name previous:%s current:%s",
410                   prv_layout_name.c_str(), crr_layout_name.c_str());
411         if (prv_layout_name == crr_layout_name)
412         {
413             HMI_DEBUG("---- Previous layout is same with current");
414         }
415         else
416         {
417             // If previous layout is NOT same with current,
418             // current areas is set with default value
419             HMI_DEBUG("---- Previous layout is NOT same with current");
420             crr_layout_state.name = this->default_layouts[crr_layout_name].name;
421             crr_layout_state.category_num = this->default_layouts[crr_layout_name].category_num;
422             crr_layout_state.area_list = this->default_layouts[crr_layout_name].area_list;
423         }
424
425         // Create candidate list
426         std::map<std::string, AreaList> cand_list;
427         // for (int ctg_no = StmCtgNoMin;
428         //      ctg_no <= StmCtgNoMax; ctg_no++)
429         // {
430         for (const auto &ctg : this->layer2categories[layer_name])
431         {
432             // if (ctg_no == StmCtgNoNone)
433             // {
434             //     continue;
435             // }
436
437             // const char *ctg = kStmCategoryName[ctg_no];
438             HMI_DEBUG("-- Create candidate list for ctg:%s", ctg.c_str());
439
440             AreaList tmp_cand_list;
441             int candidate_num = 0;
442             int blank_num = crr_layout_state.category_num[ctg];
443
444             // If requested event is "activate"
445             // and there are requested category and area,
446             // update area with requested role in current layout.
447             bool request_for_this_layer = false;
448             std::string used_role = "";
449             if ((ctg == req_ctg) && ("activate" == req_evt))
450             {
451                 HMI_DEBUG("---- Requested event is activate");
452                 for (AreaState &as : crr_layout_state.area_list)
453                 {
454                     if (as.category == req_ctg)
455                     {
456                         request_for_this_layer = true;
457
458                         if (as.name == req_area)
459                         {
460                             as.role = req_role;
461                             used_role = req_role;
462                             blank_num--;
463                             HMI_DEBUG("------ Update current layout: area:%s category:%s role:%s",
464                                       as.name.c_str(), as.category.c_str(), as.role.c_str());
465                             break;
466                         }
467                     }
468                 }
469             }
470
471             // Create candidate list for category from the previous displayed categories
472             for (AreaState area_state : prv_layout_state.area_list)
473             {
474                 if ((ctg == area_state.category) &&
475                     (used_role != area_state.role))
476                 {
477                     // If there is the category
478                     // which is same with new category and not used for updating yet,
479                     // push it to list
480                     HMI_DEBUG("---- Push previous(category:%s role:%s) to candidate list",
481                               area_state.category.c_str(), area_state.role.c_str());
482                     tmp_cand_list.push_back(area_state);
483                     candidate_num++;
484                 }
485             }
486
487             // If NOT updated by requested area:
488             // there is not requested area in new layout,
489             // so push requested role to candidate list
490             if (request_for_this_layer && ("" == used_role))
491             {
492                 HMI_DEBUG("---- Push request(area:%s category:%s role:%s) to candidate list",
493                           req_area.c_str(), req_ctg.c_str(), req_role.c_str());
494                 AreaState area_state;
495                 area_state.name = req_area;
496                 area_state.category = req_ctg;
497                 area_state.role = req_role;
498                 tmp_cand_list.push_back(area_state);
499                 candidate_num++;
500             }
501
502             HMI_DEBUG("---- blank_num:%d candidate_num:%d", blank_num, candidate_num);
503
504             // Compare number of candidate/blank,
505             // And remove role in order of the oldest as necessary
506             if (candidate_num < blank_num)
507             {
508                 // Refer history stack
509                 // and add to the top of tmp_cand_list in order to the newest
510                 while (candidate_num != blank_num)
511                 {
512                     AreaState area_state;
513                     area_state.name = kStmAreaName[StmAreaNoNone];
514                     area_state.category = ctg;
515                     area_state.role = this->popInvisibleRoleHistory(ctg);
516                     if ("" == area_state.role)
517                     {
518                         HMI_ERROR("There is no role in history stack!!");
519                     }
520                     tmp_cand_list.push_back(area_state);
521                     HMI_DEBUG("------ Add role:%s to candidate list",
522                               area_state.role.c_str());
523                     candidate_num++;
524                 }
525             }
526             else if (candidate_num > blank_num)
527             {
528                 // Remove the oldest role from candidate list
529                 while (candidate_num != blank_num)
530                 {
531                     std::string removed_role = tmp_cand_list.begin()->role;
532                     HMI_DEBUG("------ Remove the oldest role:%s from candidate list",
533                               removed_role.c_str());
534                     tmp_cand_list.erase(tmp_cand_list.begin());
535                     candidate_num--;
536
537                     // Push removed data to history stack
538                     this->pushInvisibleRoleHistory(ctg, removed_role);
539
540                     // Remove from current layout
541                     for (AreaState &as : crr_layout_state.area_list)
542                     {
543                         if (as.role == removed_role)
544                         {
545                             as.role = "";
546                         }
547                     }
548                 }
549             }
550             else
551             { // (candidate_num == blank_num)
552                 // nop
553             }
554
555             cand_list[ctg] = tmp_cand_list;
556         }
557
558         // Update areas
559         HMI_DEBUG("-- Update areas by using candidate list");
560         for (AreaState &as : crr_layout_state.area_list)
561         {
562             HMI_DEBUG("---- Check area:%s category:%s role:%s",
563                       as.name.c_str(), as.category.c_str(), as.role.c_str());
564             if ("" == as.role)
565             {
566                 HMI_DEBUG("------ Update this area with role:%s",
567                           cand_list[as.category].begin()->role.c_str());
568                 as.role = cand_list[as.category].begin()->role;
569                 cand_list[as.category].erase(cand_list[as.category].begin());
570             }
571         }
572     }
573     return changed;
574 }
575
576 void PolicyManager::createOutputInformation(StmState crr_state, json_object **json_out)
577 {
578     json_object *json_tmp;
579
580     // Create layout information
581     //
582     //     "layers": [
583     //     {
584     //         "homescreen": {
585     //             "changed": <bool>,
586     //             "areas": [
587     //             {
588     //                 "name":<const char*>,
589     //                 "role":<const char*>
590     //             }.
591     //             ...
592     //             ]
593     //         }
594     //     },
595     //     ...
596     json_object *json_layer = json_object_new_array();
597     const char *layer_name;
598     for (int layer_no = StmLayerNoMin;
599          layer_no <= StmLayerNoMax; layer_no++)
600     {
601         layer_name = kStmLayerName[layer_no];
602         json_tmp = json_object_new_object();
603         this->addStateToJson(layer_name,
604                              this->crr_layers[layer_name].changed,
605                              this->crr_layers[layer_name].layout_state.area_list,
606                              &json_tmp);
607         json_object_array_add(json_layer, json_tmp);
608     }
609     json_object_object_add(*json_out, "layers", json_layer);
610 }
611
612 int PolicyManager::transitionState(sd_event_source *source, void *data)
613 {
614     HMI_DEBUG(">>>>>>>>>> START STATE TRANSITION");
615
616     int event_id = *((int *)data);
617
618     int event_no, category_no, area_no;
619     event_no = STM_GET_EVENT_FROM_ID(event_id);
620     category_no = STM_GET_CATEGORY_FROM_ID(event_id);
621     area_no = STM_GET_AREA_FROM_ID(event_id);
622     HMI_DEBUG(">>>>>>>>>> EVENT:%s CATEGORY:%s AREA:%s",
623               kStmEventName[event_no],
624               kStmCategoryName[category_no],
625               kStmAreaName[area_no]);
626
627     // Transition state
628     StmState crr_state;
629     int ret = stmTransitionState(event_id, &crr_state);
630     if (0 > ret)
631     {
632         HMI_ERROR("Failed transition state");
633         if (nullptr != this->callback.onError)
634         {
635             json_object *json_out = json_object_new_object();
636             json_object_object_add(json_out, "message",
637                                    json_object_new_string("Failed to transition state"));
638             json_object_object_add(json_out, "event",
639                                    json_object_new_string(kStmEventName[event_no]));
640             json_object_object_add(json_out, "role",
641                                    json_object_new_string(this->req_role_list[event_id].c_str()));
642             json_object_object_add(json_out, "area",
643                                    json_object_new_string(kStmAreaName[area_no]));
644             this->callback.onError(json_out);
645             json_object_put(json_out);
646         }
647         return -1;
648     }
649
650     // Update state which is managed by PolicyManager
651     this->updateState(event_id, crr_state);
652
653     // Create output information for ResourceManager
654     json_object *json_out = json_object_new_object();
655     this->createOutputInformation(crr_state, &json_out);
656
657     // Notify changed state
658     if (nullptr != this->callback.onStateTransitioned)
659     {
660         this->callback.onStateTransitioned(json_out);
661     }
662
663     // Release json_object
664     json_object_put(json_out);
665
666     // Release data
667     delete (int *)data;
668
669     // Destroy sd_event_source object
670     sd_event_source_unref(source);
671
672     // Remove event source from list
673     if (this->event_source_list.find(event_id) != this->event_source_list.end())
674     {
675         this->event_source_list.erase(event_id);
676     }
677
678     HMI_DEBUG(">>>>>>>>>> FINISH STATE TRANSITION");
679     return 0;
680 }
681
682 int PolicyManager::timerEvent(sd_event_source *source, uint64_t usec, void *data)
683 {
684     HMI_DEBUG("Call");
685
686     int ret = this->transitionState(source, data);
687     return ret;
688 }
689
690 int PolicyManager::setStateTransitionProcessToSystemd(int event_id, uint64_t delay_ms, std::string role)
691 {
692     struct sd_event_source *event_source;
693     HMI_DEBUG("wm:pm event_id:0x%x delay:%d role:%s", event_id, delay_ms, role.c_str());
694
695     if (0 == delay_ms)
696     {
697         int ret = sd_event_add_defer(afb_api_get_event_loop(afbBindingV3root), &event_source,
698                                      &pm::transitionStateWrapper, new int(event_id));
699         if (0 > ret)
700         {
701             HMI_ERROR("wm:pm Failed to sd_event_add_defer: errno:%d", ret);
702             return -1;
703         }
704     }
705     else
706     {
707         // Get current time
708         struct timespec time_spec;
709         clock_gettime(CLOCK_BOOTTIME, &time_spec);
710
711         // Calculate timer fired time
712         uint64_t usec = (time_spec.tv_sec * 1000000) + (time_spec.tv_nsec / 1000) + (delay_ms * 1000);
713
714         // Set timer
715         int ret = sd_event_add_time(afb_api_get_event_loop(afbBindingV3root), &event_source,
716                                     CLOCK_BOOTTIME, usec, 1,
717                                     &pm::timerEventWrapper, new int(event_id));
718         if (0 > ret)
719         {
720             HMI_ERROR("wm:pm Failed to sd_event_add_time: errno:%d", ret);
721             return -1;
722         }
723     }
724     // Store event source
725     this->event_source_list[event_id] = event_source;
726     // Store requested role
727     this->req_role_list[event_id] = role;
728     return 0;
729 }
730
731 int PolicyManager::loadRoleDb()
732 {
733     std::string file_name(get_file_path("roles.db"));
734
735     // Load roles.db
736     json_object *json_obj;
737     int ret = this->inputJsonFilie(file_name.c_str(), &json_obj);
738     if (0 > ret)
739     {
740         HMI_ERROR("Could not open roles.db, so use default role information");
741         json_obj = json_tokener_parse(kDefaultRoleDb);
742     }
743     HMI_DEBUG("json_obj dump:%s", json_object_get_string(json_obj));
744
745     json_object *json_roles;
746     if (!json_object_object_get_ex(json_obj, "roles", &json_roles))
747     {
748         HMI_ERROR("Parse Error!!");
749         return -1;
750     }
751
752     int len = json_object_array_length(json_roles);
753     HMI_DEBUG("json_cfg len:%d", len);
754     HMI_DEBUG("json_cfg dump:%s", json_object_get_string(json_roles));
755
756     json_object *json_tmp;
757     const char *category;
758     const char *roles;
759     const char *areas;
760     const char *layer;
761     for (int i = 0; i < len; i++)
762     {
763         json_tmp = json_object_array_get_idx(json_roles, i);
764
765         category = this->getStringFromJson(json_tmp, "category");
766         roles = this->getStringFromJson(json_tmp, "role");
767         areas = this->getStringFromJson(json_tmp, "area");
768         layer = this->getStringFromJson(json_tmp, "layer");
769
770         if ((nullptr == category) || (nullptr == roles) ||
771             (nullptr == areas) || (nullptr == layer))
772         {
773             HMI_ERROR("Parse Error!!");
774             return -1;
775         }
776
777         // Parse roles by '|'
778         std::vector<std::string> vct_roles;
779         vct_roles = this->parseString(std::string(roles), '|');
780
781         // Parse areas by '|'
782         Areas vct_areas;
783         vct_areas = this->parseString(std::string(areas), '|');
784
785         // Set role, category, areas
786         for (auto itr = vct_roles.begin(); itr != vct_roles.end(); ++itr)
787         {
788             this->role2category[*itr] = std::string(category);
789         }
790         this->category2role[category] = std::string(roles);
791         this->category2areas[category] = vct_areas;
792         this->layer2categories[layer].push_back(category);
793     }
794
795     // Check
796     HMI_DEBUG("Check role2category");
797     for (const auto &x : this->role2category)
798     {
799         HMI_DEBUG("key:%s, val:%s", x.first.c_str(), x.second.c_str());
800     }
801
802     HMI_DEBUG("Check category2role");
803     for (const auto &x : this->category2role)
804     {
805         HMI_DEBUG("key:%s, val:%s", x.first.c_str(), x.second.c_str());
806     }
807
808     HMI_DEBUG("Check category2areas");
809     for (const auto &x : this->category2areas)
810     {
811         for (const auto &y : x.second)
812         {
813             HMI_DEBUG("key:%s, val:%s", x.first.c_str(), y.c_str());
814         }
815     }
816     return 0;
817 }
818
819 int PolicyManager::loadStateDb()
820 {
821     HMI_DEBUG("Call");
822
823     std::string file_name(get_file_path("states.db"));
824
825     // Load states.db
826     json_object *json_obj;
827     int ret = this->inputJsonFilie(file_name.c_str(), &json_obj);
828     if (0 > ret)
829     {
830         HMI_DEBUG("Could not open states.db, so use default layout information");
831         json_obj = json_tokener_parse(kDefaultStateDb);
832     }
833     HMI_DEBUG("json_obj dump:%s", json_object_get_string(json_obj));
834
835     // Perse states
836     HMI_DEBUG("Perse states");
837     json_object *json_cfg;
838     if (!json_object_object_get_ex(json_obj, "states", &json_cfg))
839     {
840         HMI_ERROR("Parse Error!!");
841         return -1;
842     }
843
844     int len = json_object_array_length(json_cfg);
845     HMI_DEBUG("json_cfg len:%d", len);
846     HMI_DEBUG("json_cfg dump:%s", json_object_get_string(json_cfg));
847
848     const char *layout;
849     const char *role;
850     const char *category;
851     for (int i = 0; i < len; i++)
852     {
853         json_object *json_tmp = json_object_array_get_idx(json_cfg, i);
854
855         layout = this->getStringFromJson(json_tmp, "name");
856         if (nullptr == layout)
857         {
858             HMI_ERROR("Parse Error!!");
859             return -1;
860         }
861         HMI_DEBUG("> layout:%s", layout);
862
863         json_object *json_area_array;
864         if (!json_object_object_get_ex(json_tmp, "areas", &json_area_array))
865         {
866             HMI_ERROR("Parse Error!!");
867             return -1;
868         }
869
870         int len_area = json_object_array_length(json_area_array);
871         HMI_DEBUG("json_area_array len:%d", len_area);
872         HMI_DEBUG("json_area_array dump:%s", json_object_get_string(json_area_array));
873
874         LayoutState layout_state;
875         AreaState area_state;
876         std::map<std::string, int> category_num;
877         for (int ctg_no = StmCtgNoMin;
878              ctg_no <= StmCtgNoMax; ctg_no++)
879         {
880             const char *ctg_name = kStmCategoryName[ctg_no];
881             category_num[ctg_name] = 0;
882         }
883
884         for (int j = 0; j < len_area; j++)
885         {
886             json_object *json_area = json_object_array_get_idx(json_area_array, j);
887
888             // Get area name
889             const char *area = this->getStringFromJson(json_area, "name");
890             if (nullptr == area)
891             {
892                 HMI_ERROR("Parse Error!!");
893                 return -1;
894             }
895             area_state.name = std::string(area);
896             HMI_DEBUG(">> area:%s", area);
897
898             // Get app attribute of the area
899             category = this->getStringFromJson(json_area, "category");
900             if (nullptr == category)
901             {
902                 HMI_ERROR("Parse Error!!");
903                 return -1;
904             }
905             area_state.category = std::string(category);
906             category_num[category]++;
907             HMI_DEBUG(">>> category:%s", category);
908
909             role = this->getStringFromJson(json_area, "role");
910             if (nullptr != role)
911             {
912                 // Role is NOT essential here
913                 area_state.role = std::string(role);
914             }
915             else
916             {
917                 area_state.role = std::string("");
918             }
919             HMI_DEBUG(">>> role:%s", role);
920
921             layout_state.area_list.push_back(area_state);
922         }
923
924         layout_state.name = layout;
925         layout_state.category_num = category_num;
926         this->default_layouts[layout] = layout_state;
927     }
928
929     // initialize for none layout
930     LayoutState none_layout_state;
931     memset(&none_layout_state, 0, sizeof(none_layout_state));
932     none_layout_state.name = "none";
933     this->default_layouts["none"] = none_layout_state;
934
935     // Check
936     for (auto itr_layout = this->default_layouts.begin();
937          itr_layout != this->default_layouts.end(); ++itr_layout)
938     {
939         HMI_DEBUG(">>> layout:%s", itr_layout->first.c_str());
940
941         for (auto itr_area = itr_layout->second.area_list.begin();
942              itr_area != itr_layout->second.area_list.end(); ++itr_area)
943         {
944             HMI_DEBUG(">>> >>> area    :%s", itr_area->name.c_str());
945             HMI_DEBUG(">>> >>> category:%s", itr_area->category.c_str());
946             HMI_DEBUG(">>> >>> role    :%s", itr_area->role.c_str());
947         }
948     }
949
950     // Release json_object
951     json_object_put(json_obj);
952
953     return 0;
954 }
955
956 void PolicyManager::pushInvisibleRoleHistory(std::string category, std::string role)
957 {
958     auto i = std::remove_if(this->invisible_role_history[category].begin(),
959                             this->invisible_role_history[category].end(),
960                             [role](std::string x) { return (role == x); });
961
962     if (this->invisible_role_history[category].end() != i)
963     {
964         this->invisible_role_history[category].erase(i);
965     }
966
967     this->invisible_role_history[category].push_back(role);
968
969     if (pm::kInvisibleRoleHistoryNum < invisible_role_history[category].size())
970     {
971         this->invisible_role_history[category].erase(
972             this->invisible_role_history[category].begin());
973     }
974 }
975
976 std::string PolicyManager::popInvisibleRoleHistory(std::string category)
977 {
978     std::string role;
979     if (invisible_role_history[category].empty())
980     {
981         role = "";
982     }
983     else
984     {
985         role = this->invisible_role_history[category].back();
986         this->invisible_role_history[category].pop_back();
987     }
988     return role;
989 }
990
991 const char *PolicyManager::getStringFromJson(json_object *obj, const char *key)
992 {
993     json_object *tmp;
994     if (!json_object_object_get_ex(obj, key, &tmp))
995     {
996         HMI_DEBUG("Not found key \"%s\"", key);
997         return nullptr;
998     }
999
1000     return json_object_get_string(tmp);
1001 }
1002
1003 int PolicyManager::inputJsonFilie(const char *file, json_object **obj)
1004 {
1005     const int input_size = 128;
1006     int ret = -1;
1007
1008     HMI_DEBUG("Input file: %s", file);
1009
1010     // Open json file
1011     FILE *fp = fopen(file, "rb");
1012     if (nullptr == fp)
1013     {
1014         HMI_ERROR("Could not open file");
1015         return ret;
1016     }
1017
1018     // Parse file data
1019     struct json_tokener *tokener = json_tokener_new();
1020     enum json_tokener_error json_error;
1021     char buffer[input_size];
1022     int block_cnt = 1;
1023     while (1)
1024     {
1025         size_t len = fread(buffer, sizeof(char), input_size, fp);
1026         *obj = json_tokener_parse_ex(tokener, buffer, len);
1027         if (nullptr != *obj)
1028         {
1029             HMI_DEBUG("File input is success");
1030             ret = 0;
1031             break;
1032         }
1033
1034         json_error = json_tokener_get_error(tokener);
1035         if ((json_tokener_continue != json_error) || (input_size > len))
1036         {
1037             HMI_ERROR("Failed to parse file (byte:%d err:%s)",
1038                       (input_size * block_cnt), json_tokener_error_desc(json_error));
1039             HMI_ERROR("\n%s", buffer);
1040             *obj = nullptr;
1041             break;
1042         }
1043         block_cnt++;
1044     }
1045
1046     // Close json file
1047     fclose(fp);
1048
1049     // Free json_tokener
1050     json_tokener_free(tokener);
1051
1052     return ret;
1053 }
1054
1055 void PolicyManager::dumpLayerState(std::unordered_map<std::string, LayerState> &layers)
1056 {
1057     HMI_DEBUG("-------------------------------------------------------------------------------------------------------");
1058     HMI_DEBUG("|%-15s|%s|%-20s|%-20s|%-20s|%-20s|",
1059               "LAYER", "C", "LAYOUT", "AREA", "CATEGORY", "ROLE");
1060     for (const auto &itr : layers)
1061     {
1062         LayerState ls = itr.second;
1063         const char* layer   = ls.name.c_str();
1064         const char* changed = (ls.changed) ? "T" : "f";
1065         const char* layout  = ls.layout_state.name.c_str();
1066         bool first = true;
1067         for (const auto &as : ls.layout_state.area_list)
1068         {
1069             if (first)
1070             {
1071                 first = false;
1072                 HMI_DEBUG("|%-15s|%1s|%-20s|%-20s|%-20s|%-20s|",
1073                           layer, changed, layout,
1074                           as.name.c_str(), as.category.c_str(), as.role.c_str());
1075             }
1076             else
1077                 HMI_DEBUG("|%-15s|%1s|%-20s|%-20s|%-20s|%-20s|",
1078                           "", "", "", as.name.c_str(), as.category.c_str(), as.role.c_str());
1079         }
1080     }
1081     HMI_DEBUG("-------------------------------------------------------------------------------------------------------");
1082 }
1083
1084 void PolicyManager::dumpInvisibleRoleHistory()
1085 {
1086     HMI_DEBUG(">>>>>>>>>> DUMP INVISIBLE ROLE HISTORY ( category [older > newer] )");
1087     for (int ctg_no = StmCtgNoMin; ctg_no <= StmCtgNoMax; ctg_no++)
1088     {
1089         if (ctg_no == StmCtgNoNone)
1090             continue;
1091
1092         std::string category = std::string(kStmCategoryName[ctg_no]);
1093
1094         std::string str = category + " [ ";
1095         for (const auto &i : this->invisible_role_history[category])
1096             str += (i + " > ");
1097
1098         str += "]";
1099         HMI_DEBUG("%s", str.c_str());
1100     }
1101 }
1102
1103 std::vector<std::string> PolicyManager::parseString(std::string str, char delimiter)
1104 {
1105     // Parse string by delimiter
1106     std::vector<std::string> vct;
1107     std::stringstream ss{str};
1108     std::string buf;
1109     while (std::getline(ss, buf, delimiter))
1110     {
1111         if (!buf.empty())
1112         {
1113             // Delete space and push back to vector
1114             vct.push_back(this->deleteSpace(buf));
1115         }
1116     }
1117     return vct;
1118 }
1119
1120 std::string PolicyManager::deleteSpace(std::string str)
1121 {
1122     std::string ret = str;
1123     size_t pos;
1124     while ((pos = ret.find_first_of(" ")) != std::string::npos)
1125     {
1126         ret.erase(pos, 1);
1127     }
1128     return ret;
1129 }
1130
1131 const char *PolicyManager::kDefaultRoleDb = "{ \
1132     \"roles\":[ \
1133     { \
1134         \"category\": \"homescreen\", \
1135         \"role\": \"homescreen\", \
1136         \"area\": \"fullscreen\", \
1137     }, \
1138     { \
1139         \"category\": \"map\", \
1140         \"role\": \"map\", \
1141         \"area\": \"normal.full | split.main\", \
1142     }, \
1143     { \
1144         \"category\": \"general\", \
1145         \"role\": \"launcher | poi | browser | sdl | mixer | radio | hvac | debug | phone | video | music\", \
1146         \"area\": \"normal.full\", \
1147     }, \
1148     { \
1149         \"category\": \"system\", \
1150         \"role\": \"settings | dashboard\", \
1151         \"area\": \"normal.full\", \
1152     }, \
1153     { \
1154         \"category\": \"software_keyboard\", \
1155         \"role\": \"software_keyboard\", \
1156         \"area\": \"software_keyboard\", \
1157     }, \
1158     { \
1159         \"category\": \"restriction\", \
1160         \"role\": \"restriction\", \
1161         \"area\": \"restriction.normal | restriction.split.main | restriction.split.sub\", \
1162     }, \
1163     { \
1164         \"category\": \"pop_up\", \
1165         \"role\": \"pop_up\", \
1166         \"area\": \"on_screen\", \
1167     }, \
1168     { \
1169         \"category\": \"system_alert\", \
1170         \"role\": \"system_alert\", \
1171         \"area\": \"on_screen\", \
1172     } \
1173     ] \
1174 }";
1175
1176 const char *PolicyManager::kDefaultStateDb = "{ \
1177     \"states\": [ \
1178         { \
1179             \"name\": \"homescreen\", \
1180             \"layer\": \"far_homescreen\", \
1181             \"areas\": [ \
1182                 { \
1183                     \"name\": \"fullscreen\", \
1184                     \"category\": \"homescreen\" \
1185                 } \
1186             ] \
1187         }, \
1188         { \
1189             \"name\": \"map.normal\", \
1190             \"layer\": \"apps\", \
1191             \"areas\": [ \
1192                 { \
1193                     \"name\": \"normal.full\", \
1194                     \"category\": \"map\" \
1195                 } \
1196             ] \
1197         }, \
1198         { \
1199             \"name\": \"map.split\", \
1200             \"layer\": \"apps\", \
1201             \"areas\": [ \
1202                 { \
1203                     \"name\": \"split.main\", \
1204                     \"category\": \"map\" \
1205                 }, \
1206                 { \
1207                     \"name\": \"split.sub\", \
1208                     \"category\": \"splitable\" \
1209                 } \
1210             ] \
1211         }, \
1212         { \
1213             \"name\": \"map.fullscreen\", \
1214             \"layer\": \"apps\", \
1215             \"areas\": [ \
1216                 { \
1217                     \"name\": \"fullscreen\", \
1218                     \"category\": \"map\" \
1219                 } \
1220             ] \
1221         }, \
1222         { \
1223             \"name\": \"splitable.normal\", \
1224             \"layer\": \"apps\", \
1225             \"areas\": [ \
1226                 { \
1227                     \"name\": \"normal.full\", \
1228                     \"category\": \"splitable\" \
1229                 } \
1230             ] \
1231         }, \
1232         { \
1233             \"name\": \"splitable.split\", \
1234             \"layer\": \"apps\", \
1235             \"areas\": [ \
1236                 { \
1237                     \"name\": \"split.main\", \
1238                     \"category\": \"splitable\" \
1239                 }, \
1240                 { \
1241                     \"name\": \"split.sub\", \
1242                     \"category\": \"splitable\" \
1243                 } \
1244             ] \
1245         }, \
1246         { \
1247             \"name\": \"general.normal\", \
1248             \"layer\": \"apps\", \
1249             \"areas\": [ \
1250                 { \
1251                     \"name\": \"normal.full\", \
1252                     \"category\": \"general\" \
1253                 } \
1254             ] \
1255         }, \
1256         { \
1257             \"name\": \"system.normal\", \
1258             \"layer\": \"apps\", \
1259             \"areas\": [ \
1260                 { \
1261                     \"name\": \"normal.full\", \
1262                     \"category\": \"system\" \
1263                 } \
1264             ] \
1265         }, \
1266         { \
1267             \"name\": \"software_keyboard\", \
1268             \"layer\": \"near_homescreen\", \
1269             \"areas\": [ \
1270                 { \
1271                     \"name\": \"software_keyboard\", \
1272                     \"category\": \"software_keyboard\" \
1273                 } \
1274             ] \
1275         }, \
1276         { \
1277             \"name\": \"restriction.normal\", \
1278             \"layer\": \"restriction\", \
1279             \"areas\": [ \
1280                 { \
1281                     \"name\": \"restriction.normal\", \
1282                     \"category\": \"restriction\" \
1283                 } \
1284             ] \
1285         }, \
1286         { \
1287             \"name\": \"restriction.split.main\", \
1288             \"layer\": \"restriction\", \
1289             \"areas\": [ \
1290                 { \
1291                     \"name\": \"restriction.split.main\", \
1292                     \"category\": \"restriction\" \
1293                 } \
1294             ] \
1295         }, \
1296         { \
1297             \"name\": \"restriction.split.sub\", \
1298             \"layer\": \"restriction\", \
1299             \"areas\": [ \
1300                 { \
1301                     \"name\": \"restriction.split.sub\", \
1302                     \"category\": \"restriction\" \
1303                 } \
1304             ] \
1305         }, \
1306         { \
1307             \"name\": \"pop_up\", \
1308             \"layer\": \"on_screen\", \
1309             \"areas\": [ \
1310                 { \
1311                     \"name\": \"on_screen\", \
1312                     \"category\": \"pop_up\" \
1313                 } \
1314             ] \
1315         }, \
1316         { \
1317             \"name\": \"system_alert\", \
1318             \"layer\": \"on_screen\", \
1319             \"areas\": [ \
1320                 { \
1321                     \"name\": \"on_screen\", \
1322                     \"category\": \"system_alert\" \
1323                 } \
1324             ] \
1325         } \
1326     ] \
1327 }";