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