Add initialize code
[apps/agl-service-windowmanager.git] / src / window_manager.cpp
1 /*
2  * Copyright (c) 2017 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 <regex>
19
20 #include "window_manager.hpp"
21 #include "json_helper.hpp"
22 #include "applist.hpp"
23
24 extern "C"
25 {
26 #include <systemd/sd-event.h>
27 }
28
29 using std::string;
30 using std::vector;
31
32 namespace wm
33 {
34
35 static const uint64_t kTimeOut = 3ULL; /* 3s */
36
37 /* DrawingArea name used by "{layout}.{area}" */
38 const char kNameLayoutNormal[] = "normal";
39 const char kNameLayoutSplit[]  = "split";
40 const char kNameAreaFull[]     = "full";
41 const char kNameAreaMain[]     = "main";
42 const char kNameAreaSub[]      = "sub";
43
44 /* Key for json obejct */
45 const char kKeyDrawingName[] = "drawing_name";
46 const char kKeyDrawingArea[] = "drawing_area";
47 const char kKeyDrawingRect[] = "drawing_rect";
48 const char kKeyX[]           = "x";
49 const char kKeyY[]           = "y";
50 const char kKeyWidth[]       = "width";
51 const char kKeyHeight[]      = "height";
52 const char kKeyWidthPixel[]  = "width_pixel";
53 const char kKeyHeightPixel[] = "height_pixel";
54 const char kKeyWidthMm[]     = "width_mm";
55 const char kKeyHeightMm[]    = "height_mm";
56 const char kKeyScale[]       = "scale";
57 const char kKeyIds[]         = "ids";
58
59 static sd_event_source *g_timer_ev_src = nullptr;
60 static AppList g_app_list;
61 static WindowManager *g_context;
62
63 namespace
64 {
65
66 // using nlohmann::json;
67
68 /* result<json> file_to_json(char const *filename)
69 {
70     json j;
71     std::ifstream i(filename);
72     if (i.fail())
73     {
74         HMI_DEBUG("Could not open config file, so use default layer information");
75         j = default_layers_json;
76     }
77     else
78     {
79         i >> j;
80     }
81
82     return Ok(j);
83 }
84
85 struct result<layer_map> load_layer_map(char const *filename)
86 {
87     HMI_DEBUG("loading IDs from %s", filename);
88
89     auto j = file_to_json(filename);
90     if (j.is_err())
91     {
92         return Err<layer_map>(j.unwrap_err());
93     }
94     json jids = j.unwrap();
95
96     return to_layer_map(jids);
97 } */
98
99 static int processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata)
100 {
101     HMI_NOTICE("Time out occurs because the client replys endDraw slow, so revert the request");
102     reinterpret_cast<wm::WindowManager *>(userdata)->timerHandler();
103     return 0;
104 }
105
106 static void onStateTransitioned(vector<WMAction> actions)
107 {
108     g_context->startTransitionWrapper(actions);
109 }
110
111 static void onError()
112 {
113     g_context->processError(WMError::LAYOUT_CHANGE_FAIL);
114 }
115 } // namespace
116
117 /**
118  * WindowManager Impl
119  */
120 WindowManager::WindowManager()
121     : chooks{this},
122       id_alloc{}
123 {
124     const char *path = getenv("AFM_APP_INSTALL_DIR");
125     if (!path)
126     {
127         HMI_ERROR("AFM_APP_INSTALL_DIR is not defined");
128     }
129     string root = path;
130
131     this->lc = std::make_shared<LayerControl>(root);
132
133     HMI_DEBUG("Layer Controller initialized");
134
135 /*     try
136     {
137         {
138             auto l = load_layer_map(path.c_str());
139             if (l.is_ok())
140             {
141                 this->layers = l.unwrap();
142             }
143             else
144             {
145                 HMI_ERROR("%s", l.err().value());
146             }
147         }
148     }
149     catch (std::exception &e)
150     {
151         HMI_ERROR("Loading of configuration failed: %s", e.what());
152     } */
153 }
154
155 int WindowManager::init()
156 {
157     /* if (!this->display->ok())
158     {
159         return -1;
160     }
161
162     if (this->layers.mapping.empty())
163     {
164         HMI_ERROR("No surface -> layer mapping loaded");
165         return -1;
166     } */
167
168     // TODO: application requests by old role,
169     //       so create role map (old, new)
170     // Load old_role.db
171     LayerControlCallbacks lmcb;
172     lmcb.surfaceCreated = [this](unsigned surface){HMI_DEBUG("show %d", surface);};
173     this->lc->init(lmcb);
174     this->loadOldRoleDb();
175
176     // Store my context for calling callback from PolicyManager
177     g_context = this;
178
179     // Initialize PMWrapper
180     this->pmw.initialize();
181
182     // Register callback to PolicyManager
183     this->pmw.registerCallback(onStateTransitioned, onError);
184
185     // Make afb event
186     for (int i = Event_Val_Min; i <= Event_Val_Max; i++)
187     {
188         map_afb_event[kListEventName[i]] = afb_daemon_make_event(kListEventName[i]);
189     }
190
191     const struct rect css_bg = this->lc->getAreaSize("fullscreen");
192     Screen screen = this->lc->getScreenInfo();
193     rectangle dp_bg(screen.width(), screen.height());
194
195     dp_bg.set_aspect(static_cast<double>(css_bg.w) / css_bg.h);
196     dp_bg.fit(screen.width(), screen.height());
197     dp_bg.center(screen.width(), screen.height());
198     HMI_DEBUG("SCALING: CSS BG(%dx%d) -> DDP %dx%d,(%dx%d)",
199               css_bg.w, css_bg.h, dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
200
201     double scale = static_cast<double>(dp_bg.height()) / css_bg.h;
202     this->lc->setupArea(scale);
203
204     /* this->display->add_global_handler(
205         "wl_output", [this](wl_registry *r, uint32_t name, uint32_t v) {
206             this->outputs.emplace_back(std::make_unique<wl::output>(r, name, v));
207         });
208
209     this->display->add_global_handler(
210         "ivi_wm", [this](wl_registry *r, uint32_t name, uint32_t v) {
211             this->controller =
212                 std::make_unique<struct compositor::controller>(r, name, v);
213
214             // Init controller hooks
215             this->controller->chooks = &this->chooks;
216
217             // This protocol needs the output, so lets just add our mapping here...
218             this->controller->add_proxy_to_id_mapping(
219                 this->outputs.front()->proxy.get(),
220                 wl_proxy_get_id(reinterpret_cast<struct wl_proxy *>(
221                     this->outputs.front()->proxy.get())));
222
223             // Create screen
224             this->controller->create_screen(this->outputs.front()->proxy.get());
225
226             // Set display to controller
227             this->controller->display = this->display;
228         });
229
230     // First level objects
231     this->display->roundtrip();
232     // Second level objects
233     this->display->roundtrip();
234     // Third level objects
235     this->display->roundtrip(); */
236
237     return 0; //init_layers();
238 }
239
240 /* int WindowManager::dispatch_pending_events()
241 {
242     if (this->pop_pending_events())
243     {
244         this->display->dispatch_pending();
245         return 0;
246     }
247     return -1;
248 }
249
250 void WindowManager::set_pending_events()
251 {
252     this->pending_events.store(true, std::memory_order_release);
253 } */
254
255 result<int> WindowManager::api_request_surface(char const *appid, char const *drawing_name)
256 {
257     // TODO: application requests by old role,
258     //       so convert role old to new
259     const char *role = this->convertRoleOldToNew(drawing_name);
260     string l_name;
261
262     // auto lid = this->layers.get_layer_id(string(role));
263     unsigned l_id = this->lc->getNewLayerID(role, &l_name);
264     if (l_id == 0)
265     {
266         /**
267        * register drawing_name as fallback and make it displayed.
268        */
269         // lid = this->layers.get_layer_id(string("fallback"));
270         l_id = this->lc->getNewLayerID("fallback", &l_name);
271         HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
272         if (l_id == 0)
273         {
274             return Err<int>("Designated role does not match any role, fallback is disabled");
275         }
276     }
277
278     this->lc->createNewLayer(l_id);
279
280     // generate surface ID for ivi-shell application
281
282     auto rname = this->id_alloc.lookup(string(role));
283     if (!rname)
284     {
285         // name does not exist yet, allocate surface id...
286         auto id = int(this->id_alloc.generate_id(role));
287         // this->layers.add_surface(id, *lid);
288
289         // set the main_surface[_name] here and now
290         // if (!this->layers.main_surface_name.empty() &&
291         //     this->layers.main_surface_name == drawing_name)
292         // {
293         //     this->layers.main_surface = id;
294         //     HMI_DEBUG("Set main_surface id to %u", id);
295         // }
296
297         // add client into the db
298         string appid_str(appid);
299         g_app_list.addClient(appid_str, l_id, l_name, id, string(role));
300
301         /* if(g_app_list.contains(appid_str))
302         {
303             // add surface into app
304             auto client = g_app_list.lookUpClient(appid_str);
305             // client.addSurface(id);
306         }
307         else
308         {
309             g_app_list.addClient(appid_str, l_id, id, string(role));
310         } */
311
312         // Set role map of (new, old)
313         this->rolenew2old[role] = string(drawing_name);
314
315         return Ok<int>(id);
316     }
317
318     // Check currently registered drawing names if it is already there.
319     return Err<int>("Surface already present");
320 }
321
322 char const *WindowManager::api_request_surface(char const *appid, char const *drawing_name,
323                                      char const *ivi_id)
324 {
325     // TODO: application requests by old role,
326     //       so convert role old to new
327     const char *role = this->convertRoleOldToNew(drawing_name);
328     string str = role;
329     string l_name;
330
331     // auto lid = this->layers.get_layer_id(string(role));
332     unsigned lid = this->lc->getNewLayerID(str, &l_name);
333     unsigned sid = std::stol(ivi_id);
334
335     if (lid == 0)
336     {
337         //register drawing_name as fallback and make it displayed.
338         lid = this->lc->getNewLayerID(str, &l_name);
339         HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
340         if (lid == 0)
341         {
342             return "Drawing name does not match any role, fallback is disabled";
343         }
344     }
345
346     this->lc->createNewLayer(lid);
347
348     auto rname = this->id_alloc.lookup(str);
349
350     if (rname)
351     {
352         return "Surface already present";
353     }
354
355     // register pair drawing_name and ivi_id
356     this->id_alloc.register_name_id(role, sid);
357     // this->layers.add_surface(sid, *lid);
358
359     // this surface is already created
360     // HMI_DEBUG("surface_id is %u, layer_id is %u", sid, *lid);
361
362     // this->controller->layers[*lid]->add_surface(sid);
363     // this->layout_commit();
364
365     // add client into the db
366     string appid_str(appid);
367     g_app_list.addClient(appid_str, lid, l_name, sid, string(role));
368
369     // Set role map of (new, old)
370     this->rolenew2old[role] = string(drawing_name);
371
372     return nullptr;
373 }
374
375 /**
376  * This function is substitute of requestSurface
377  * If surface creation is faster than application request of this function,
378  * WM will bind surfaceID with application and role.
379  * If surface creation is slower than application request of thie function,
380  * WM will put Client into pending list.
381  *
382  * Note :
383  * Application can request with pid but this is temporary solution for now.
384  * This will be removed.
385  * */
386 bool WindowManager::api_set_role(char const *appid, char const *drawing_name, unsigned pid){
387     string id = appid;
388     string role = drawing_name;
389     string l_name;
390     unsigned surface = 0;
391     WMError wm_err = WMError::UNKNOWN;
392     bool ret = false;
393
394     // get layer ID which role should be in
395     // auto lid = this->layers.get_layer_id(role);
396     unsigned lid = this->lc->getNewLayerID(role, &l_name);
397     if (lid == 0)
398     {
399         // lid = this->layers.get_layer_id(string("fallback"));
400         HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role.c_str());
401         if (lid == 0)
402         {
403             HMI_ERROR("Drawing name does not match any role, fallback is disabled");
404             return ret;
405         }
406     }
407
408     if(0 != pid){
409         // search floating surfaceID from pid if pid is designated.
410         wm_err = g_app_list.popFloatingSurface(pid, &surface);
411     }
412     else{
413         // get floating surface with appid. If WM queries appid from pid,
414         // WM can bind surface and role with appid(not implemented yet)
415         //wm_err = g_app_list.popFloatingSurface(id);
416     }
417     if(wm_err != WMError::SUCCESS){
418         HMI_ERROR("No floating surface for app: %s", id.c_str());
419         g_app_list.addFloatingClient(id, lid, role);
420         HMI_NOTICE("%s : Waiting for surface creation", id.c_str());
421         return ret;
422     }
423
424     ret = true;
425     if (g_app_list.contains(id))
426     {
427         HMI_INFO("Add role: %s with surface: %d. Client %s has multi surfaces.",
428                  role.c_str(), surface, id.c_str());
429         auto client = g_app_list.lookUpClient(id);
430         client->appendRole(role);
431     }
432     else{
433         HMI_INFO("Create new client: %s, surface: %d into layer: %d with role: %s",
434                  id.c_str(), surface, lid, role.c_str());
435         g_app_list.addClient(id, lid, l_name, surface, role);
436     }
437
438     // register pair drawing_name and ivi_id
439     this->id_alloc.register_name_id(role.c_str(), surface);
440     // this->layers.add_surface(surface, *lid);
441
442     // this surface is already created
443     HMI_DEBUG("surface_id is %u, layer_id is %u", surface, lid);
444
445     // const auto &o_layer = this->layers.get_layer(*lid);
446     /* auto rect = o_layer.value().rect;
447     if(rect.w < 0)
448     {
449         rect.w = this->controller->output_size.w + 1 + rect.w;
450     }
451     if(rect.h < 0)
452     {
453         rect.h = this->controller->output_size.h + 1 + rect.h;
454     } */
455
456     // this->controller->layers[*lid]->add_surface(surface);
457     // this->layout_commit();
458
459     return ret;
460 }
461
462 void WindowManager::api_activate_surface(char const *appid, char const *drawing_name,
463                                char const *drawing_area, const reply_func &reply)
464 {
465     ;
466
467     // TODO: application requests by old role,
468     //       so convert role old to new
469     const char *c_role = this->convertRoleOldToNew(drawing_name);
470
471     string id = appid;
472     string role = c_role;
473     string area = drawing_area;
474
475     if(!g_app_list.contains(id))
476     {
477         reply("app doesn't request 'requestSurface' or 'setRole' yet");
478         return;
479     }
480     auto client = g_app_list.lookUpClient(id);
481
482     // unsigned srfc = client->surfaceID(role);
483     // unsigned layer = client->layerID();
484
485     // g_app_list.removeFloatingSurface(client->surfaceID());
486     // g_app_list.removeFloatingSurface(client);
487
488     Task task = Task::TASK_ALLOCATE;
489     unsigned req_num = 0;
490     WMError ret = WMError::UNKNOWN;
491
492     ret = this->setRequest(id, role, area, task, &req_num);
493
494     //vector<WMLayerState> current_states = this->lc->getCurrentStates();
495     // ret = this->setRequest(id, role, area, task, current_states, &req_num);
496
497     if(ret != WMError::SUCCESS)
498     {
499         HMI_ERROR(errorDescription(ret));
500         reply("Failed to set request");
501         return;
502     }
503
504     reply(nullptr);
505     if (req_num != g_app_list.currentRequestNumber())
506     {
507         // Add request, then invoked after the previous task is finished
508         HMI_SEQ_DEBUG(req_num, "request is accepted");
509         return;
510     }
511
512     /*
513      * Do allocate tasks
514      */
515     ret = this->checkPolicy(req_num);
516
517     if (ret != WMError::SUCCESS)
518     {
519         //this->emit_error()
520         HMI_SEQ_ERROR(req_num, errorDescription(ret));
521         g_app_list.removeRequest(req_num);
522         this->processNextRequest();
523     }
524 }
525
526 void WindowManager::api_deactivate_surface(char const *appid, char const *drawing_name,
527                                  const reply_func &reply)
528 {
529     ;
530
531     // TODO: application requests by old role,
532     //       so convert role old to new
533     const char *c_role = this->convertRoleOldToNew(drawing_name);
534
535     /*
536     * Check Phase
537     */
538     string id = appid;
539     string role = c_role;
540     string area = ""; //drawing_area;
541     Task task = Task::TASK_RELEASE;
542     unsigned req_num = 0;
543     WMError ret = WMError::UNKNOWN;
544
545     ret = this->setRequest(id, role, area, task, &req_num);
546     //vector<WMLayerState> current_states = this->lc->getCurrentStates();
547     // ret = this->setRequest(id, role, area, task, current_states, &req_num);
548
549     if (ret != WMError::SUCCESS)
550     {
551         HMI_ERROR(errorDescription(ret));
552         reply("Failed to set request");
553         return;
554     }
555
556     reply(nullptr);
557     if (req_num != g_app_list.currentRequestNumber())
558     {
559         // Add request, then invoked after the previous task is finished
560         HMI_SEQ_DEBUG(req_num, "request is accepted");
561         return;
562     }
563
564     /*
565     * Do allocate tasks
566     */
567     ret = this->checkPolicy(req_num);
568
569     if (ret != WMError::SUCCESS)
570     {
571         //this->emit_error()
572         HMI_SEQ_ERROR(req_num, errorDescription(ret));
573         g_app_list.removeRequest(req_num);
574         this->processNextRequest();
575     }
576 }
577
578 void WindowManager::api_enddraw(char const *appid, char const *drawing_name)
579 {
580     // TODO: application requests by old role,
581     //       so convert role old to new
582     const char *c_role = this->convertRoleOldToNew(drawing_name);
583
584     string id = appid;
585     string role = c_role;
586     unsigned current_req = g_app_list.currentRequestNumber();
587     bool result = g_app_list.setEndDrawFinished(current_req, id, role);
588
589     if (!result)
590     {
591         HMI_ERROR("%s is not in transition state", id.c_str());
592         return;
593     }
594
595     if (g_app_list.endDrawFullfilled(current_req))
596     {
597         // do task for endDraw
598         this->stopTimer();
599         WMError ret = this->doEndDraw(current_req);
600
601         if(ret != WMError::SUCCESS)
602         {
603             //this->emit_error();
604
605             // Undo state of PolicyManager
606             this->pmw.undoState();
607             this->lc->undoUpdate();
608         }
609         this->emitScreenUpdated(current_req);
610         HMI_SEQ_INFO(current_req, "Finish request status: %s", errorDescription(ret));
611
612         g_app_list.removeRequest(current_req);
613
614         this->processNextRequest();
615     }
616     else
617     {
618         HMI_SEQ_INFO(current_req, "Wait other App call endDraw");
619         return;
620     }
621 }
622
623 result<json_object *> WindowManager::api_get_display_info()
624 {
625     /* if (!this->display->ok())
626     {
627         return Err<json_object *>("Wayland compositor is not available");
628     } */
629
630     // Set display info
631 /*     size o_size = this->controller->output_size;
632     size p_size = this->controller->physical_size; */
633     Screen screen = this->lc->getScreenInfo();
634
635     json_object *object = json_object_new_object();
636     json_object_object_add(object, kKeyWidthPixel, json_object_new_int(screen.width()));
637     json_object_object_add(object, kKeyHeightPixel, json_object_new_int(screen.height()));
638     // TODO: set size
639     json_object_object_add(object, kKeyWidthMm, json_object_new_int(0));
640     json_object_object_add(object, kKeyHeightMm, json_object_new_int(0));
641     json_object_object_add(object, kKeyScale, json_object_new_double(this->lc->scale()));
642
643     return Ok<json_object *>(object);
644 }
645
646 result<json_object *> WindowManager::api_get_area_info(char const *drawing_name)
647 {
648     HMI_DEBUG("called");
649
650     // TODO: application requests by old role,
651     //       so convert role old to new
652     const char *role = this->convertRoleOldToNew(drawing_name);
653
654     // Check drawing name, surface/layer id
655     auto const &surface_id = this->id_alloc.lookup(string(role));
656     if (!surface_id)
657     {
658         return Err<json_object *>("Surface does not exist");
659     }
660
661     /* if (!this->controller->surface_exists(*surface_id))
662     {
663         return Err<json_object *>("Surface does not exist in controller!");
664     } */
665
666     /* // auto layer_id = this->layers.get_layer_id(*surface_id);
667     if (!layer_id)
668     {
669         return Err<json_object *>("Surface is not on any layer!");
670     } */
671
672     // Set area rectangle
673     rect area_info = this->area_info[*surface_id];
674     json_object *object = json_object_new_object();
675     json_object_object_add(object, kKeyX, json_object_new_int(area_info.x));
676     json_object_object_add(object, kKeyY, json_object_new_int(area_info.y));
677     json_object_object_add(object, kKeyWidth, json_object_new_int(area_info.w));
678     json_object_object_add(object, kKeyHeight, json_object_new_int(area_info.h));
679
680     return Ok<json_object *>(object);
681 }
682
683 void WindowManager::api_ping() { /* this->dispatch_pending_events(); */ }
684
685 void WindowManager::send_event(char const *evname, char const *label)
686 {
687     HMI_DEBUG("%s: %s(%s)", __func__, evname, label);
688
689     json_object *j = json_object_new_object();
690     json_object_object_add(j, kKeyDrawingName, json_object_new_string(label));
691
692     int ret = afb_event_push(this->map_afb_event[evname], j);
693     if (ret != 0)
694     {
695         HMI_DEBUG("afb_event_push failed: %m");
696     }
697 }
698
699 void WindowManager::send_event(char const *evname, char const *label, char const *area,
700                      int x, int y, int w, int h)
701 {
702     HMI_DEBUG("%s: %s(%s, %s) x:%d y:%d w:%d h:%d",
703               __func__, evname, label, area, x, y, w, h);
704
705     json_object *j_rect = json_object_new_object();
706     json_object_object_add(j_rect, kKeyX, json_object_new_int(x));
707     json_object_object_add(j_rect, kKeyY, json_object_new_int(y));
708     json_object_object_add(j_rect, kKeyWidth, json_object_new_int(w));
709     json_object_object_add(j_rect, kKeyHeight, json_object_new_int(h));
710
711     json_object *j = json_object_new_object();
712     json_object_object_add(j, kKeyDrawingName, json_object_new_string(label));
713     json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area));
714     json_object_object_add(j, kKeyDrawingRect, j_rect);
715
716     int ret = afb_event_push(this->map_afb_event[evname], j);
717     if (ret != 0)
718     {
719         HMI_DEBUG("afb_event_push failed: %m");
720     }
721 }
722
723 /**
724  * proxied events
725  */
726 void WindowManager::surface_created(uint32_t surface_id)
727 {
728     /* this->controller->get_surface_properties(surface_id, IVI_WM_PARAM_SIZE);
729
730     auto layer_id = this->layers.get_layer_id(surface_id);
731     if (!layer_id)
732     {
733         HMI_DEBUG("Newly created surfce %d is not associated with any layer!",
734                   surface_id);
735         return;
736     }
737
738     HMI_DEBUG("surface_id is %u, layer_id is %u", surface_id, *layer_id);
739
740     this->controller->layers[*layer_id]->add_surface(surface_id);
741     this->layout_commit(); */
742 }
743
744 void WindowManager::surface_removed(uint32_t surface_id)
745 {
746     HMI_DEBUG("Delete surface_id %u", surface_id);
747     this->id_alloc.remove_id(surface_id);
748     // this->layers.remove_surface(surface_id);
749     g_app_list.removeSurface(surface_id);
750 }
751
752 void WindowManager::surface_properties(unsigned surface_id, unsigned pid)
753 {
754     HMI_DEBUG("get surface properties");
755
756     // search pid from surfaceID
757     /*json_object *response;
758     afb_service_call_sync("afm-main", "runners", nullptr, &response);
759
760     // retrieve appid from pid from application manager
761     string appid = "";
762     if(response == nullptr)
763     {
764         HMI_ERROR("No runners");
765     }
766     else
767     {
768         // check appid then add it to the client
769         HMI_INFO("Runners:%s", json_object_get_string(response));
770         int size = json_object_array_length(response);
771         for(int i = 0; i < size; i++)
772         {
773             json_object *j = json_object_array_get_idx(response, i);
774             const char* id = jh::getStringFromJson(j, "id");
775             int runid      = jh::getIntFromJson(j, "runid");
776             if(id && (runid > 0))
777             {
778                 if(runid == pid)
779                 {
780                     appid = id;
781                     break;
782                 }
783             }
784         }
785     }
786     json_object_put(response);
787
788     g_app_list.addFloatingSurface(appid, surface_id, pid);*/
789 }
790
791 void WindowManager::removeClient(const string &appid)
792 {
793     HMI_DEBUG("Remove clinet %s from list", appid.c_str());
794     g_app_list.removeClient(appid);
795 }
796
797 void WindowManager::exceptionProcessForTransition()
798 {
799     unsigned req_num = g_app_list.currentRequestNumber();
800     HMI_SEQ_NOTICE(req_num, "Process exception handling for request. Remove current request %d", req_num);
801     g_app_list.removeRequest(req_num);
802     HMI_SEQ_NOTICE(g_app_list.currentRequestNumber(), "Process next request if exists");
803     this->processNextRequest();
804 }
805
806 void WindowManager::timerHandler()
807 {
808     unsigned req_num = g_app_list.currentRequestNumber();
809     HMI_SEQ_DEBUG(req_num, "Timer expired remove Request");
810     g_app_list.reqDump();
811     g_app_list.removeRequest(req_num);
812     this->processNextRequest();
813 }
814
815 void WindowManager::startTransitionWrapper(vector<WMAction> &actions)
816 {
817     WMError ret;
818     unsigned req_num = g_app_list.currentRequestNumber();
819
820     if (actions.empty())
821     {
822         if (g_app_list.haveRequest())
823         {
824             HMI_SEQ_DEBUG(req_num, "There is no WMAction for this request");
825             goto proc_remove_request;
826         }
827         else
828         {
829             HMI_SEQ_DEBUG(req_num, "There is no request");
830             return;
831         }
832     }
833
834     for (auto &act : actions)
835     {
836         if ("" != act.role)
837         {
838             bool found;
839             auto const &surface_id = this->id_alloc.lookup(act.role);
840             string appid = g_app_list.getAppID(*surface_id, act.role, &found);
841             if (!found)
842             {
843                 if (TaskVisible::INVISIBLE == act.visible)
844                 {
845                     // App is killed, so do not set this action
846                     continue;
847                 }
848                 else
849                 {
850                     HMI_SEQ_ERROR(req_num, "appid which is visible is not found");
851                     ret = WMError::FAIL;
852                     goto error;
853                 }
854             }
855             act.appid = appid;
856         }
857
858         ret = g_app_list.setAction(req_num, act);
859         if (ret != WMError::SUCCESS)
860         {
861             HMI_SEQ_ERROR(req_num, "Setting action is failed");
862             goto error;
863         }
864     }
865
866     HMI_SEQ_DEBUG(req_num, "Start transition.");
867     ret = this->startTransition(req_num);
868     if (ret != WMError::SUCCESS)
869     {
870         if (ret == WMError::NO_LAYOUT_CHANGE)
871         {
872             goto proc_remove_request;
873         }
874         else
875         {
876             HMI_SEQ_ERROR(req_num, "Transition state is failed");
877             goto error;
878         }
879     }
880
881     return;
882
883 error:
884     //this->emit_error()
885     HMI_SEQ_ERROR(req_num, errorDescription(ret));
886     this->pmw.undoState();
887
888 proc_remove_request:
889     g_app_list.removeRequest(req_num);
890     this->processNextRequest();
891 }
892
893 void WindowManager::processError(WMError error)
894 {
895     unsigned req_num = g_app_list.currentRequestNumber();
896
897     //this->emit_error()
898     HMI_SEQ_ERROR(req_num, errorDescription(error));
899     g_app_list.removeRequest(req_num);
900     this->processNextRequest();
901 }
902
903 /*
904  ******* Private Functions *******
905  */
906
907 /**
908  * init_layers()
909  */
910 int WindowManager::init_layers()
911 {
912     /* if (!this->controller)
913     {
914         HMI_ERROR("ivi_controller global not available");
915         return -1;
916     }
917
918     if (this->outputs.empty())
919     {
920         HMI_ERROR("no output was set up!");
921         return -1;
922     }
923
924     auto &c = this->controller;
925
926     auto &o = this->outputs.front();
927     auto &s = c->screens.begin()->second;
928     auto &layers = c->layers;
929
930     // Write output dimensions to ivi controller...
931     c->output_size = compositor::size{uint32_t(o->width), uint32_t(o->height)};
932     c->physical_size = compositor::size{uint32_t(o->physical_width),
933                                         uint32_t(o->physical_height)};
934
935
936     HMI_DEBUG("SCALING: screen (%dx%d), physical (%dx%d)",
937               o->width, o->height, o->physical_width, o->physical_height);
938
939     // this->layers.loadAreaDb();
940
941     const compositor::rect css_bg = this->layers.getAreaSize("fullscreen");
942     rectangle dp_bg(o->width, o->height);
943
944     dp_bg.set_aspect(static_cast<double>(css_bg.w) / css_bg.h);
945     dp_bg.fit(o->width, o->height);
946     dp_bg.center(o->width, o->height);
947     HMI_DEBUG("SCALING: CSS BG(%dx%d) -> DDP %dx%d,(%dx%d)",
948               css_bg.w, css_bg.h, dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
949
950     // Clear scene
951     // layers.clear();
952
953     // Clear screen
954     // s->clear();
955
956     // Quick and dirty setup of layers
957     for (auto const &i : this->layers.mapping)
958     {
959         c->layer_create(i.second.layer_id, dp_bg.width(), dp_bg.height());
960         auto &l = layers[i.second.layer_id];
961         l->set_destination_rectangle(dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
962         l->set_visibility(1);
963         HMI_DEBUG("Setting up layer %s (%d) for surface role match \"%s\"",
964                   i.second.name.c_str(), i.second.layer_id, i.second.role.c_str());
965     }
966
967     // Add layers to screen
968     s->set_render_order(this->layers.layers);
969
970     this->layout_commit();
971
972     c->scale = static_cast<double>(dp_bg.height()) / css_bg.h;
973     this->layers.setupArea(c->scale);
974  */
975     return 0;
976 }
977
978 void WindowManager::surface_set_layout(int surface_id, const string& area)
979 {
980     /* if (!this->controller->surface_exists(surface_id))
981     {
982         HMI_ERROR("Surface %d does not exist", surface_id);
983         return;
984     }
985
986     auto o_layer_id = this->layers.get_layer_id(surface_id);
987
988     if (!o_layer_id)
989     {
990         HMI_ERROR("Surface %d is not associated with any layer!", surface_id);
991         return;
992     }
993
994     uint32_t layer_id = *o_layer_id;
995
996     auto const &layer = this->layers.get_layer(layer_id);
997     auto rect = this->layers.getAreaSize(area);
998     HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "%s : x:%d y:%d w:%d h:%d", area.c_str(),
999                     rect.x, rect.y, rect.w, rect.h);
1000     auto &s = this->controller->surfaces[surface_id];
1001
1002     int x = rect.x;
1003     int y = rect.y;
1004     int w = rect.w;
1005     int h = rect.h;
1006
1007     HMI_DEBUG("surface_set_layout for surface %u on layer %u", surface_id,
1008               layer_id);
1009
1010     // set destination to the display rectangle
1011     s->set_destination_rectangle(x, y, w, h);
1012
1013     // update area information
1014     this->area_info[surface_id].x = x;
1015     this->area_info[surface_id].y = y;
1016     this->area_info[surface_id].w = w;
1017     this->area_info[surface_id].h = h;
1018
1019     HMI_DEBUG("Surface %u now on layer %u with rect { %d, %d, %d, %d }",
1020               surface_id, layer_id, x, y, w, h); */
1021 }
1022
1023 void WindowManager::layout_commit()
1024 {
1025 /*     this->controller->commit_changes();
1026     this->display->flush(); */
1027 }
1028
1029 void WindowManager::emit_activated(char const *label)
1030 {
1031     this->send_event(kListEventName[Event_Active], label);
1032 }
1033
1034 void WindowManager::emit_deactivated(char const *label)
1035 {
1036     this->send_event(kListEventName[Event_Inactive], label);
1037 }
1038
1039 void WindowManager::emit_syncdraw(char const *label, char const *area, int x, int y, int w, int h)
1040 {
1041     this->send_event(kListEventName[Event_SyncDraw], label, area, x, y, w, h);
1042 }
1043
1044 void WindowManager::emit_syncdraw(const string &role, const string &area)
1045 {
1046 /*     rect rect = this->layers.getAreaSize(area);
1047     this->send_event(kListEventName[Event_SyncDraw],
1048         role.c_str(), area.c_str(), rect.x, rect.y, rect.w, rect.h); */
1049 }
1050
1051 void WindowManager::emit_flushdraw(char const *label)
1052 {
1053     this->send_event(kListEventName[Event_FlushDraw], label);
1054 }
1055
1056 void WindowManager::emit_visible(char const *label, bool is_visible)
1057 {
1058     this->send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], label);
1059 }
1060
1061 void WindowManager::emit_invisible(char const *label)
1062 {
1063     return emit_visible(label, false);
1064 }
1065
1066 void WindowManager::emit_visible(char const *label) { return emit_visible(label, true); }
1067
1068 void WindowManager::activate(int id)
1069 {
1070     /* auto ip = this->controller->sprops.find(id);
1071     if (ip != this->controller->sprops.end())
1072     {
1073         this->controller->surfaces[id]->set_visibility(1);
1074         */
1075         char const *label =
1076             this->id_alloc.lookup(id).value_or("unknown-name").c_str();
1077
1078         /* // FOR CES DEMO >>>
1079         if ((0 == strcmp(label, "radio")) ||
1080             (0 == strcmp(label, "music")) ||
1081             (0 == strcmp(label, "video")) ||
1082             (0 == strcmp(label, "map")))
1083         {
1084             for (auto i = surface_bg.begin(); i != surface_bg.end(); ++i)
1085             {
1086                 if (id == *i)
1087                 {
1088                     // Remove id
1089                     this->surface_bg.erase(i);
1090
1091                     // Remove from BG layer (999)
1092                     HMI_DEBUG("Remove %s(%d) from BG layer", label, id);
1093                     this->controller->layers[999]->remove_surface(id);
1094
1095                     // Add to FG layer (1001)
1096                     HMI_DEBUG("Add %s(%d) to FG layer", label, id);
1097                     this->controller->layers[1001]->add_surface(id);
1098
1099                     for (int j : this->surface_bg)
1100                     {
1101                         HMI_DEBUG("Stored id:%d", j);
1102                     }
1103                     break;
1104                 }
1105             }
1106         }
1107         // <<< FOR CES DEMO
1108
1109         this->layout_commit(); */
1110
1111         // TODO: application requests by old role,
1112         //       so convert role new to old for emitting event
1113         const char* old_role = this->rolenew2old[label].c_str();
1114
1115         this->emit_visible(old_role);
1116         this->emit_activated(old_role);
1117     // }
1118 }
1119
1120 void WindowManager::deactivate(int id)
1121 {
1122     /* auto ip = this->controller->sprops.find(id);
1123     if (ip != this->controller->sprops.end())
1124     {*/
1125         char const *label =
1126             this->id_alloc.lookup(id).value_or("unknown-name").c_str();
1127
1128         /*// FOR CES DEMO >>>
1129         if ((0 == strcmp(label, "radio")) ||
1130             (0 == strcmp(label, "music")) ||
1131             (0 == strcmp(label, "video")) ||
1132             (0 == strcmp(label, "map")))
1133         {
1134
1135             // Store id
1136             this->surface_bg.push_back(id);
1137
1138             // Remove from FG layer (1001)
1139             HMI_DEBUG("Remove %s(%d) from FG layer", label, id);
1140             this->controller->layers[1001]->remove_surface(id);
1141
1142             // Add to BG layer (999)
1143             HMI_DEBUG("Add %s(%d) to BG layer", label, id);
1144             this->controller->layers[999]->add_surface(id);
1145
1146             for (int j : surface_bg)
1147             {
1148                 HMI_DEBUG("Stored id:%d", j);
1149             }
1150         }
1151         else
1152         {
1153             this->controller->surfaces[id]->set_visibility(0);
1154         }
1155         // <<< FOR CES DEMO
1156
1157         this->layout_commit(); */
1158
1159         // TODO: application requests by old role,
1160         //       so convert role new to old for emitting event
1161         const char* old_role = this->rolenew2old[label].c_str();
1162
1163         this->emit_deactivated(old_role);
1164         this->emit_invisible(old_role);
1165     // }
1166 }
1167
1168 WMError WindowManager::setRequest(const string& appid, const string &role, const string &area,
1169                             Task task, unsigned* req_num)
1170 {
1171     if (!g_app_list.contains(appid))
1172     {
1173         return WMError::NOT_REGISTERED;
1174     }
1175
1176     auto client = g_app_list.lookUpClient(appid);
1177
1178     /*
1179      * Queueing Phase
1180      */
1181     unsigned current = g_app_list.currentRequestNumber();
1182     unsigned requested_num = g_app_list.getRequestNumber(appid);
1183     if (requested_num != 0)
1184     {
1185         HMI_SEQ_INFO(requested_num,
1186             "%s %s %s request is already queued", appid.c_str(), role.c_str(), area.c_str());
1187         return REQ_REJECTED;
1188     }
1189
1190     WMRequest req = WMRequest(appid, role, area, task);
1191     unsigned new_req = g_app_list.addRequest(req);
1192     *req_num = new_req;
1193     g_app_list.reqDump();
1194
1195     HMI_SEQ_DEBUG(current, "%s start sequence with %s, %s", appid.c_str(), role.c_str(), area.c_str());
1196
1197     return WMError::SUCCESS;
1198 }
1199
1200 WMError WindowManager::checkPolicy(unsigned req_num)
1201 {
1202     /*
1203     * Check Policy
1204     */
1205     // get current trigger
1206     bool found = false;
1207     WMError ret = WMError::LAYOUT_CHANGE_FAIL;
1208     auto trigger = g_app_list.getRequest(req_num, &found);
1209     if (!found)
1210     {
1211         ret = WMError::NO_ENTRY;
1212         return ret;
1213     }
1214     string req_area = trigger.area;
1215
1216     if (trigger.task == Task::TASK_ALLOCATE)
1217     {
1218         const char *msg = this->check_surface_exist(trigger.role.c_str());
1219
1220         if (msg)
1221         {
1222             HMI_SEQ_ERROR(req_num, msg);
1223             return ret;
1224         }
1225     }
1226
1227     // Input event data to PolicyManager
1228     if (0 > this->pmw.setInputEventData(trigger.task, trigger.role, trigger.area))
1229     {
1230         HMI_SEQ_ERROR(req_num, "Failed to set input event data to PolicyManager");
1231         return ret;
1232     }
1233
1234     // Execute state transition of PolicyManager
1235     if (0 > this->pmw.executeStateTransition())
1236     {
1237         HMI_SEQ_ERROR(req_num, "Failed to execute state transition of PolicyManager");
1238         return ret;
1239     }
1240
1241     ret = WMError::SUCCESS;
1242
1243     g_app_list.reqDump();
1244
1245     return ret;
1246 }
1247
1248 WMError WindowManager::startTransition(unsigned req_num)
1249 {
1250     bool sync_draw_happen = false;
1251     bool found = false;
1252     WMError ret = WMError::SUCCESS;
1253     auto actions = g_app_list.getActions(req_num, &found);
1254     if (!found)
1255     {
1256         ret = WMError::NO_ENTRY;
1257         HMI_SEQ_ERROR(req_num,
1258             "Window Manager bug :%s : Action is not set", errorDescription(ret));
1259         return ret;
1260     }
1261
1262     for (const auto &action : actions)
1263     {
1264         if (action.visible == TaskVisible::VISIBLE)
1265         {
1266             sync_draw_happen = true;
1267
1268             // TODO: application requests by old role,
1269             //       so convert role new to old for emitting event
1270             string old_role = this->rolenew2old[action.role];
1271
1272             this->emit_syncdraw(old_role, action.area);
1273             /* TODO: emit event for app not subscriber
1274             if(g_app_list.contains(y.appid))
1275                 g_app_list.lookUpClient(y.appid)->emit_syncdraw(y.role, y.area); */
1276         }
1277     }
1278
1279     if (sync_draw_happen)
1280     {
1281         this->setTimer();
1282     }
1283     else
1284     {
1285         // deactivate only, no syncDraw
1286         // Make it deactivate here
1287         for (const auto &x : actions)
1288         {
1289             if (g_app_list.contains(x.appid))
1290             {
1291                 auto client = g_app_list.lookUpClient(x.appid);
1292                 this->deactivate(client->surfaceID(x.role));
1293             }
1294         }
1295         ret = WMError::NO_LAYOUT_CHANGE;
1296     }
1297     return ret;
1298 }
1299
1300 WMError WindowManager::doEndDraw(unsigned req_num)
1301 {
1302     // get actions
1303     bool found;
1304     auto actions = g_app_list.getActions(req_num, &found);
1305     WMError ret = WMError::SUCCESS;
1306     if (!found)
1307     {
1308         ret = WMError::NO_ENTRY;
1309         return ret;
1310     }
1311
1312     HMI_SEQ_INFO(req_num, "do endDraw");
1313
1314     // layout change and make it visible
1315     for (const auto &act : actions)
1316     {
1317         if(act.visible != TaskVisible::NO_CHANGE)
1318         {
1319             // layout change
1320             if(!g_app_list.contains(act.appid)){
1321                 ret = WMError::NOT_REGISTERED;
1322             }
1323             ret = this->lc->layoutChange(act);
1324             if(ret != WMError::SUCCESS)
1325             {
1326                 HMI_SEQ_WARNING(req_num,
1327                     "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
1328                 return ret;
1329             }
1330             ret = this->lc->visibilityChange(act);
1331             if (ret != WMError::SUCCESS)
1332             {
1333                 HMI_SEQ_WARNING(req_num,
1334                     "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
1335                 return ret;
1336             }
1337             HMI_SEQ_DEBUG(req_num, "visible %s", act.role.c_str());
1338             //this->lc_enddraw(act.role.c_str());
1339         }
1340     }
1341     this->lc->commitChange();
1342
1343     HMI_SEQ_INFO(req_num, "emit flushDraw");
1344
1345     for(const auto &act_flush : actions)
1346     {
1347         if(act_flush.visible == TaskVisible::VISIBLE)
1348         {
1349             // TODO: application requests by old role,
1350             //       so convert role new to old for emitting event
1351             string old_role = this->rolenew2old[act_flush.role];
1352
1353             this->emit_flushdraw(old_role.c_str());
1354         }
1355     }
1356
1357     return ret;
1358 }
1359
1360 WMError WindowManager::layoutChange(const WMAction &action)
1361 {
1362     if (action.visible == TaskVisible::INVISIBLE)
1363     {
1364         // Visibility is not change -> no redraw is required
1365         return WMError::SUCCESS;
1366     }
1367     auto client = g_app_list.lookUpClient(action.appid);
1368     unsigned surface = client->surfaceID(action.role);
1369     if (surface == 0)
1370     {
1371         HMI_SEQ_ERROR(g_app_list.currentRequestNumber(),
1372                       "client doesn't have surface with role(%s)", action.role.c_str());
1373         return WMError::NOT_REGISTERED;
1374     }
1375     // Layout Manager
1376     WMError ret = this->setSurfaceSize(surface, action.area);
1377     return ret;
1378 }
1379
1380 WMError WindowManager::visibilityChange(const WMAction &action)
1381 {
1382     HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "Change visibility");
1383     if(!g_app_list.contains(action.appid)){
1384         return WMError::NOT_REGISTERED;
1385     }
1386     auto client = g_app_list.lookUpClient(action.appid);
1387     unsigned surface = client->surfaceID(action.role);
1388     if(surface == 0)
1389     {
1390         HMI_SEQ_ERROR(g_app_list.currentRequestNumber(),
1391                       "client doesn't have surface with role(%s)", action.role.c_str());
1392         return WMError::NOT_REGISTERED;
1393     }
1394
1395     if (action.visible != TaskVisible::INVISIBLE)
1396     {
1397         this->activate(surface); // Layout Manager task
1398     }
1399     else
1400     {
1401         this->deactivate(surface); // Layout Manager task
1402     }
1403     return WMError::SUCCESS;
1404 }
1405
1406 WMError WindowManager::setSurfaceSize(unsigned surface, const string &area)
1407 {
1408     this->surface_set_layout(surface, area);
1409
1410     return WMError::SUCCESS;
1411 }
1412
1413 void WindowManager::emitScreenUpdated(unsigned req_num)
1414 {
1415     // Get visible apps
1416     HMI_SEQ_DEBUG(req_num, "emit screen updated");
1417     bool found = false;
1418     auto actions = g_app_list.getActions(req_num, &found);
1419
1420     // create json object
1421     json_object *j = json_object_new_object();
1422     json_object *jarray = json_object_new_array();
1423
1424     for(const auto& action: actions)
1425     {
1426         if(action.visible != TaskVisible::INVISIBLE)
1427         {
1428             json_object_array_add(jarray, json_object_new_string(action.appid.c_str()));
1429         }
1430     }
1431     json_object_object_add(j, kKeyIds, jarray);
1432     HMI_SEQ_INFO(req_num, "Visible app: %s", json_object_get_string(j));
1433
1434     int ret = afb_event_push(
1435         this->map_afb_event[kListEventName[Event_ScreenUpdated]], j);
1436     if (ret != 0)
1437     {
1438         HMI_DEBUG("afb_event_push failed: %m");
1439     }
1440 }
1441
1442 void WindowManager::setTimer()
1443 {
1444     struct timespec ts;
1445     if (clock_gettime(CLOCK_BOOTTIME, &ts) != 0) {
1446         HMI_ERROR("Could't set time (clock_gettime() returns with error");
1447         return;
1448     }
1449
1450     HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "Timer set activate");
1451     if (g_timer_ev_src == nullptr)
1452     {
1453         // firsttime set into sd_event
1454         int ret = sd_event_add_time(afb_daemon_get_event_loop(), &g_timer_ev_src,
1455             CLOCK_BOOTTIME, (uint64_t)(ts.tv_sec + kTimeOut) * 1000000ULL, 1, processTimerHandler, this);
1456         if (ret < 0)
1457         {
1458             HMI_ERROR("Could't set timer");
1459         }
1460     }
1461     else
1462     {
1463         // update timer limitation after second time
1464         sd_event_source_set_time(g_timer_ev_src, (uint64_t)(ts.tv_sec + kTimeOut) * 1000000ULL);
1465         sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_ONESHOT);
1466     }
1467 }
1468
1469 void WindowManager::stopTimer()
1470 {
1471     unsigned req_num = g_app_list.currentRequestNumber();
1472     HMI_SEQ_DEBUG(req_num, "Timer stop");
1473     int rc = sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_OFF);
1474     if (rc < 0)
1475     {
1476         HMI_SEQ_ERROR(req_num, "Timer stop failed");
1477     }
1478 }
1479
1480 void WindowManager::processNextRequest()
1481 {
1482     g_app_list.next();
1483     g_app_list.reqDump();
1484     unsigned req_num = g_app_list.currentRequestNumber();
1485     if (g_app_list.haveRequest())
1486     {
1487         HMI_SEQ_DEBUG(req_num, "Process next request");
1488         WMError rc = checkPolicy(req_num);
1489         if (rc != WMError::SUCCESS)
1490         {
1491             HMI_SEQ_ERROR(req_num, errorDescription(rc));
1492         }
1493     }
1494     else
1495     {
1496         HMI_SEQ_DEBUG(req_num, "Nothing Request. Waiting Request");
1497     }
1498 }
1499
1500 const char* WindowManager::convertRoleOldToNew(char const *old_role)
1501 {
1502     const char *new_role = nullptr;
1503
1504     for (auto const &on : this->roleold2new)
1505     {
1506         std::regex regex = std::regex(on.first);
1507         if (std::regex_match(old_role, regex))
1508         {
1509             // role is old. So convert to new.
1510             new_role = on.second.c_str();
1511             break;
1512         }
1513     }
1514
1515     if (nullptr == new_role)
1516     {
1517         // role is new or fallback.
1518         new_role = old_role;
1519     }
1520
1521     HMI_DEBUG("old:%s -> new:%s", old_role, new_role);
1522
1523     return new_role;
1524 }
1525
1526 int WindowManager::loadOldRoleDb()
1527 {
1528     // Get afm application installed dir
1529     char const *afm_app_install_dir = getenv("AFM_APP_INSTALL_DIR");
1530     HMI_DEBUG("afm_app_install_dir:%s", afm_app_install_dir);
1531
1532     string file_name;
1533     if (!afm_app_install_dir)
1534     {
1535         HMI_ERROR("AFM_APP_INSTALL_DIR is not defined");
1536     }
1537     else
1538     {
1539         file_name = string(afm_app_install_dir) + string("/etc/old_roles.db");
1540     }
1541
1542     // Load old_role.db
1543     json_object* json_obj;
1544     int ret = jh::inputJsonFilie(file_name.c_str(), &json_obj);
1545     if (0 > ret)
1546     {
1547         HMI_ERROR("Could not open old_role.db, so use default old_role information");
1548         json_obj = json_tokener_parse(kDefaultOldRoleDb);
1549     }
1550     HMI_DEBUG("json_obj dump:%s", json_object_get_string(json_obj));
1551
1552     // Perse apps
1553     json_object* json_cfg;
1554     if (!json_object_object_get_ex(json_obj, "old_roles", &json_cfg))
1555     {
1556         HMI_ERROR("Parse Error!!");
1557         return -1;
1558     }
1559
1560     int len = json_object_array_length(json_cfg);
1561     HMI_DEBUG("json_cfg len:%d", len);
1562     HMI_DEBUG("json_cfg dump:%s", json_object_get_string(json_cfg));
1563
1564     for (int i=0; i<len; i++)
1565     {
1566         json_object* json_tmp = json_object_array_get_idx(json_cfg, i);
1567
1568         const char* old_role = jh::getStringFromJson(json_tmp, "name");
1569         if (nullptr == old_role)
1570         {
1571             HMI_ERROR("Parse Error!!");
1572             return -1;
1573         }
1574
1575         const char* new_role = jh::getStringFromJson(json_tmp, "new");
1576         if (nullptr == new_role)
1577         {
1578             HMI_ERROR("Parse Error!!");
1579             return -1;
1580         }
1581
1582         this->roleold2new[old_role] = string(new_role);
1583     }
1584
1585     // Check
1586     for(auto itr = this->roleold2new.begin();
1587       itr != this->roleold2new.end(); ++itr)
1588     {
1589         HMI_DEBUG(">>> role old:%s new:%s",
1590                   itr->first.c_str(), itr->second.c_str());
1591     }
1592
1593     // Release json_object
1594     json_object_put(json_obj);
1595
1596     return 0;
1597 }
1598
1599 const char *WindowManager::check_surface_exist(const char *drawing_name)
1600 {
1601     auto const &surface_id = this->id_alloc.lookup(string(drawing_name));
1602     if (!surface_id)
1603     {
1604         return "Surface does not exist";
1605     }
1606
1607     /* if (!this->controller->surface_exists(*surface_id))
1608     {
1609         return "Surface does not exist in controller!";
1610     } */
1611
1612     /* auto layer_id = this->layers.get_layer_id(*surface_id);
1613
1614     if (!layer_id)
1615     {
1616         return "Surface is not on any layer!";
1617     } */
1618
1619     HMI_DEBUG("surface %d is detected", *surface_id);
1620     return nullptr;
1621 }
1622
1623 const char* WindowManager::kDefaultOldRoleDb = "{ \
1624     \"old_roles\": [ \
1625         { \
1626             \"name\": \"HomeScreen\", \
1627             \"new\": \"homescreen\" \
1628         }, \
1629         { \
1630             \"name\": \"Music\", \
1631             \"new\": \"music\" \
1632         }, \
1633         { \
1634             \"name\": \"MediaPlayer\", \
1635             \"new\": \"music\" \
1636         }, \
1637         { \
1638             \"name\": \"Video\", \
1639             \"new\": \"video\" \
1640         }, \
1641         { \
1642             \"name\": \"VideoPlayer\", \
1643             \"new\": \"video\" \
1644         }, \
1645         { \
1646             \"name\": \"WebBrowser\", \
1647             \"new\": \"browser\" \
1648         }, \
1649         { \
1650             \"name\": \"Radio\", \
1651             \"new\": \"radio\" \
1652         }, \
1653         { \
1654             \"name\": \"Phone\", \
1655             \"new\": \"phone\" \
1656         }, \
1657         { \
1658             \"name\": \"Navigation\", \
1659             \"new\": \"map\" \
1660         }, \
1661         { \
1662             \"name\": \"HVAC\", \
1663             \"new\": \"hvac\" \
1664         }, \
1665         { \
1666             \"name\": \"Settings\", \
1667             \"new\": \"settings\" \
1668         }, \
1669         { \
1670             \"name\": \"Dashboard\", \
1671             \"new\": \"dashboard\" \
1672         }, \
1673         { \
1674             \"name\": \"POI\", \
1675             \"new\": \"poi\" \
1676         }, \
1677         { \
1678             \"name\": \"Mixer\", \
1679             \"new\": \"mixer\" \
1680         }, \
1681         { \
1682             \"name\": \"Restriction\", \
1683             \"new\": \"restriction\" \
1684         }, \
1685         { \
1686             \"name\": \"^OnScreen.*\", \
1687             \"new\": \"on_screen\" \
1688         } \
1689     ] \
1690 }";
1691
1692 /**
1693  * controller_hooks
1694  */
1695 void controller_hooks::surface_created(uint32_t surface_id)
1696 {
1697     this->wmgr->surface_created(surface_id);
1698 }
1699
1700 void controller_hooks::surface_removed(uint32_t surface_id)
1701 {
1702     this->wmgr->surface_removed(surface_id);
1703 }
1704
1705 void controller_hooks::surface_visibility(uint32_t /*surface_id*/,
1706                                           uint32_t /*v*/) {}
1707
1708 void controller_hooks::surface_destination_rectangle(uint32_t /*surface_id*/,
1709                                                      uint32_t /*x*/,
1710                                                      uint32_t /*y*/,
1711                                                      uint32_t /*w*/,
1712                                                      uint32_t /*h*/) {}
1713
1714 void controller_hooks::surface_properties(uint32_t surface_id, uint32_t pid)
1715 {
1716     this->wmgr->surface_properties(surface_id, pid);
1717 }
1718
1719 } // namespace wm