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