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