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