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