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