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