Fix a little
[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         if(ctxt.role != "launcher")
665         {
666             HMI_DEBUG("wm", "go to launcher");
667             auto pSid = this->id_alloc.lookup("launcher");
668             if(pSid != nullptr)
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         // TODO: re-show top surface. The bellow doesn't work.
680         /* this->deactivate(priv.main);
681         this->layout_commit();
682         this->activate(priv.main);
683         this->layout_commit(); */
684     }
685     else {}
686     g_app_list.removeClient(ctxt.name);
687 }
688
689 /*
690  ******* Private Functions *******
691  */
692
693 bool WindowManager::pop_pending_events()
694 {
695     bool x{true};
696     return this->pending_events.compare_exchange_strong(
697         x, false, std::memory_order_consume);
698 }
699
700 optional<int> WindowManager::lookup_id(char const *name)
701 {
702     return this->id_alloc.lookup(std::string(name));
703 }
704 optional<std::string> WindowManager::lookup_name(int id)
705 {
706     return this->id_alloc.lookup(id);
707 }
708
709 /**
710  * init_layers()
711  */
712 int WindowManager::init_layers()
713 {
714     if (!this->controller)
715     {
716         HMI_ERROR("wm", "ivi_controller global not available");
717         return -1;
718     }
719
720     if (this->outputs.empty())
721     {
722         HMI_ERROR("wm", "no output was set up!");
723         return -1;
724     }
725
726     auto &c = this->controller;
727
728     auto &o = this->outputs.front();
729     auto &s = c->screens.begin()->second;
730     auto &layers = c->layers;
731
732     // Write output dimensions to ivi controller...
733     c->output_size = compositor::size{uint32_t(o->width), uint32_t(o->height)};
734     c->physical_size = compositor::size{uint32_t(o->physical_width),
735                                         uint32_t(o->physical_height)};
736
737
738     HMI_DEBUG("wm", "SCALING: screen (%dx%d), physical (%dx%d)",
739               o->width, o->height, o->physical_width, o->physical_height);
740
741     this->layers.loadAreaDb();
742
743     const compositor::rect css_bg = this->layers.getAreaSize("fullscreen");
744     rectangle dp_bg(o->width, o->height);
745
746     dp_bg.set_aspect(static_cast<double>(css_bg.w) / css_bg.h);
747     dp_bg.fit(o->width, o->height);
748     dp_bg.center(o->width, o->height);
749     HMI_DEBUG("wm", "SCALING: CSS BG(%dx%d) -> DDP %dx%d,(%dx%d)",
750               css_bg.w, css_bg.h, dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
751
752     // Clear scene
753     layers.clear();
754
755     // Clear screen
756     s->clear();
757
758     // Quick and dirty setup of layers
759     for (auto const &i : this->layers.mapping)
760     {
761         c->layer_create(i.second.layer_id, dp_bg.width(), dp_bg.height());
762         auto &l = layers[i.second.layer_id];
763         l->set_destination_rectangle(dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
764         l->set_visibility(1);
765         HMI_DEBUG("wm", "Setting up layer %s (%d) for surface role match \"%s\"",
766                   i.second.name.c_str(), i.second.layer_id, i.second.role.c_str());
767     }
768
769     // Add layers to screen
770     s->set_render_order(this->layers.layers);
771
772     this->layout_commit();
773
774     c->scale = static_cast<double>(dp_bg.height()) / css_bg.h;
775     this->layers.setupArea(c->scale);
776
777     return 0;
778 }
779
780 void WindowManager::surface_set_layout(int surface_id, const std::string& area)
781 {
782     if (!this->controller->surface_exists(surface_id))
783     {
784         HMI_ERROR("wm", "Surface %d does not exist", surface_id);
785         return;
786     }
787
788     auto o_layer_id = this->layers.get_layer_id(surface_id);
789
790     if (!o_layer_id)
791     {
792         HMI_ERROR("wm", "Surface %d is not associated with any layer!", surface_id);
793         return;
794     }
795
796     uint32_t layer_id = *o_layer_id;
797
798     auto const &layer = this->layers.get_layer(layer_id);
799     auto rect = this->layers.getAreaSize(area);
800     HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "%s : x:%d y:%d w:%d h:%d", area.c_str(),
801                     rect.x, rect.y, rect.w, rect.h);
802     auto &s = this->controller->surfaces[surface_id];
803
804     int x = rect.x;
805     int y = rect.y;
806     int w = rect.w;
807     int h = rect.h;
808
809     HMI_DEBUG("wm", "surface_set_layout for surface %u on layer %u", surface_id,
810               layer_id);
811
812     // set destination to the display rectangle
813     s->set_destination_rectangle(x, y, w, h);
814
815     // update area information
816     this->area_info[surface_id].x = x;
817     this->area_info[surface_id].y = y;
818     this->area_info[surface_id].w = w;
819     this->area_info[surface_id].h = h;
820
821     HMI_DEBUG("wm", "Surface %u now on layer %u with rect { %d, %d, %d, %d }",
822               surface_id, layer_id, x, y, w, h);
823 }
824
825 void WindowManager::layout_commit()
826 {
827     this->controller->commit_changes();
828     this->display->flush();
829 }
830
831 void WindowManager::emit_activated(char const *label)
832 {
833     this->send_event(kListEventName[Event_Active], label);
834 }
835
836 void WindowManager::emit_deactivated(char const *label)
837 {
838     this->send_event(kListEventName[Event_Inactive], label);
839 }
840
841 void WindowManager::emit_syncdraw(char const *label, char const *area, int x, int y, int w, int h)
842 {
843     this->send_event(kListEventName[Event_SyncDraw], label, area, x, y, w, h);
844 }
845
846 void WindowManager::emit_syncdraw(const std::string &role, const std::string &area)
847 {
848     compositor::rect rect = this->layers.getAreaSize(area);
849     this->send_event(kListEventName[Event_SyncDraw],
850         role.c_str(), area.c_str(), rect.x, rect.y, rect.w, rect.h);
851 }
852
853 void WindowManager::emit_flushdraw(char const *label)
854 {
855     this->send_event(kListEventName[Event_FlushDraw], label);
856 }
857
858 void WindowManager::emit_visible(char const *label, bool is_visible)
859 {
860     this->send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], label);
861 }
862
863 void WindowManager::emit_invisible(char const *label)
864 {
865     return emit_visible(label, false);
866 }
867
868 void WindowManager::emit_visible(char const *label) { return emit_visible(label, true); }
869
870 void WindowManager::activate(int id)
871 {
872     auto ip = this->controller->sprops.find(id);
873     if (ip != this->controller->sprops.end())
874     {
875         this->controller->surfaces[id]->set_visibility(1);
876         char const *label =
877             this->lookup_name(id).value_or("unknown-name").c_str();
878
879          // FOR CES DEMO >>>
880         if ((0 == strcmp(label, "radio")) ||
881             (0 == strcmp(label, "music")) ||
882             (0 == strcmp(label, "video")) ||
883             (0 == strcmp(label, "map")))
884         {
885             for (auto i = surface_bg.begin(); i != surface_bg.end(); ++i)
886             {
887                 if (id == *i)
888                 {
889                     // Remove id
890                     this->surface_bg.erase(i);
891
892                     // Remove from BG layer (999)
893                     HMI_DEBUG("wm", "Remove %s(%d) from BG layer", label, id);
894                     this->controller->layers[999]->remove_surface(id);
895
896                     // Add to FG layer (1001)
897                     HMI_DEBUG("wm", "Add %s(%d) to FG layer", label, id);
898                     this->controller->layers[1001]->add_surface(id);
899
900                     for (int j : this->surface_bg)
901                     {
902                         HMI_DEBUG("wm", "Stored id:%d", j);
903                     }
904                     break;
905                 }
906             }
907         }
908         // <<< FOR CES DEMO
909
910         this->layout_commit();
911
912         // TODO: application requests by old role,
913         //       so convert role new to old for emitting event
914         const char* old_role = this->rolenew2old[label].c_str();
915
916         this->emit_visible(old_role);
917         this->emit_activated(old_role);
918     }
919 }
920
921 void WindowManager::deactivate(int id)
922 {
923     auto ip = this->controller->sprops.find(id);
924     if (ip != this->controller->sprops.end())
925     {
926         char const *label =
927             this->lookup_name(id).value_or("unknown-name").c_str();
928
929         // FOR CES DEMO >>>
930         if ((0 == strcmp(label, "radio")) ||
931             (0 == strcmp(label, "music")) ||
932             (0 == strcmp(label, "video")) ||
933             (0 == strcmp(label, "map")))
934         {
935
936             // Store id
937             this->surface_bg.push_back(id);
938
939             // Remove from FG layer (1001)
940             HMI_DEBUG("wm", "Remove %s(%d) from FG layer", label, id);
941             this->controller->layers[1001]->remove_surface(id);
942
943             // Add to BG layer (999)
944             HMI_DEBUG("wm", "Add %s(%d) to BG layer", label, id);
945             this->controller->layers[999]->add_surface(id);
946
947             for (int j : surface_bg)
948             {
949                 HMI_DEBUG("wm", "Stored id:%d", j);
950             }
951         }
952         else
953         {
954             this->controller->surfaces[id]->set_visibility(0);
955         }
956         // <<< FOR CES DEMO
957
958         this->layout_commit();
959
960         // TODO: application requests by old role,
961         //       so convert role new to old for emitting event
962         const char* old_role = this->rolenew2old[label].c_str();
963
964         this->emit_deactivated(old_role);
965         this->emit_invisible(old_role);
966     }
967 }
968
969 WMError WindowManager::setRequest(const std::string& appid, const std::string &role, const std::string &area,
970                             Task task, unsigned* req_num)
971 {
972     if (!g_app_list.contains(appid))
973     {
974         return WMError::NOT_REGISTERED;
975     }
976
977     auto client = g_app_list.lookUpClient(appid);
978
979     /*
980      * Queueing Phase
981      */
982     unsigned current = g_app_list.currentRequestNumber();
983     unsigned requested_num = g_app_list.getRequestNumber(appid);
984     if (requested_num != 0)
985     {
986         HMI_SEQ_INFO(requested_num,
987             "%s %s %s request is already queued", appid.c_str(), role.c_str(), area.c_str());
988         return REQ_REJECTED;
989     }
990
991     WMRequest req = WMRequest(appid, role, area, task);
992     unsigned new_req = g_app_list.addRequest(req);
993     *req_num = new_req;
994     g_app_list.reqDump();
995
996     HMI_SEQ_DEBUG(current, "%s start sequence with %s, %s", appid.c_str(), role.c_str(), area.c_str());
997
998     return WMError::SUCCESS;
999 }
1000
1001 WMError WindowManager::doTransition(unsigned req_num)
1002 {
1003     HMI_SEQ_DEBUG(req_num, "check policy");
1004     WMError ret = this->checkPolicy(req_num);
1005     if (ret != WMError::SUCCESS)
1006     {
1007         return ret;
1008     }
1009     HMI_SEQ_DEBUG(req_num, "Start transition.");
1010     ret = this->startTransition(req_num);
1011     return ret;
1012 }
1013
1014 WMError WindowManager::checkPolicy(unsigned req_num)
1015 {
1016     /*
1017     * Check Policy
1018     */
1019     // get current trigger
1020     bool found = false;
1021     bool split = false;
1022     WMError ret = WMError::LAYOUT_CHANGE_FAIL;
1023     auto trigger = g_app_list.getRequest(req_num, &found);
1024     if (!found)
1025     {
1026         ret = WMError::NO_ENTRY;
1027         return ret;
1028     }
1029     std::string req_area = trigger.area;
1030
1031     // >>>> Compatible with current window manager until policy manager coming
1032     if (trigger.task == Task::TASK_ALLOCATE)
1033     {
1034         HMI_SEQ_DEBUG(req_num, "Check split or not");
1035         const char *msg = this->check_surface_exist(trigger.role.c_str());
1036
1037         if (msg)
1038         {
1039             HMI_SEQ_ERROR(req_num, msg);
1040             ret = WMError::LAYOUT_CHANGE_FAIL;
1041             return ret;
1042         }
1043
1044         auto const &surface_id = this->lookup_id(trigger.role.c_str());
1045         auto o_state = *this->layers.get_layout_state(*surface_id);
1046         struct LayoutState &state = *o_state;
1047
1048         unsigned curernt_sid = state.main;
1049         split = this->can_split(state, *surface_id);
1050
1051         if (split)
1052         {
1053             HMI_SEQ_DEBUG(req_num, "Split happens");
1054             // Get current visible role
1055             std::string add_role = this->lookup_name(state.main).value();
1056             // Set next area
1057             std::string add_area = std::string(kNameLayoutSplit) + "." + std::string(kNameAreaMain);
1058             // Change request area
1059             req_area = std::string(kNameLayoutSplit) + "." + std::string(kNameAreaSub);
1060             HMI_SEQ_NOTICE(req_num, "Change request area from %s to %s, because split happens",
1061                                 trigger.area.c_str(), req_area.c_str());
1062             // set another action
1063             std::string add_name = g_app_list.getAppID(curernt_sid, add_role, &found);
1064             if (!found)
1065             {
1066                 HMI_SEQ_ERROR(req_num, "Couldn't widhdraw with surfaceID : %d", curernt_sid);
1067                 ret = WMError::NOT_REGISTERED;
1068                 return ret;
1069             }
1070             HMI_SEQ_INFO(req_num, "Additional split app %s, role: %s, area: %s",
1071                          add_name.c_str(), add_role.c_str(), add_area.c_str());
1072             // Set split action
1073             bool end_draw_finished = false;
1074             WMAction split_action{
1075                 add_name,
1076                 add_role,
1077                 add_area,
1078                 TaskVisible::VISIBLE,
1079                 end_draw_finished};
1080             WMError ret = g_app_list.setAction(req_num, split_action);
1081             if (ret != WMError::SUCCESS)
1082             {
1083                 HMI_SEQ_ERROR(req_num, "Failed to set action");
1084                 return ret;
1085             }
1086             g_app_list.reqDump();
1087         }
1088     }
1089     else
1090     {
1091         HMI_SEQ_DEBUG(req_num, "split doesn't happen");
1092     }
1093
1094     // Set invisible task(Remove if policy manager finish)
1095     ret = this->setInvisibleTask(trigger.role, split);
1096     if(ret != WMError::SUCCESS)
1097     {
1098         HMI_SEQ_ERROR(req_num, "Failed to set invisible task: %s", errorDescription(ret));
1099         return ret;
1100     }
1101
1102     /*  get new status from Policy Manager */
1103     HMI_SEQ_NOTICE(req_num, "ATM, Policy manager does't exist, then set WMAction as is");
1104     if(trigger.role == "homescreen")
1105     {
1106         // TODO : Remove when Policy Manager completed
1107         HMI_SEQ_NOTICE(req_num, "Hack. This process will be removed. Change HomeScreen code!!");
1108         req_area = "fullscreen";
1109     }
1110     TaskVisible task_visible =
1111         (trigger.task == Task::TASK_ALLOCATE) ? TaskVisible::VISIBLE : TaskVisible::INVISIBLE;
1112
1113     ret = g_app_list.setAction(req_num, trigger.appid, trigger.role, req_area, task_visible);
1114     g_app_list.reqDump();
1115
1116     return ret;
1117 }
1118
1119 WMError WindowManager::startTransition(unsigned req_num)
1120 {
1121     bool sync_draw_happen = false;
1122     bool found = false;
1123     WMError ret = WMError::SUCCESS;
1124     auto actions = g_app_list.getActions(req_num, &found);
1125     if (!found)
1126     {
1127         ret = WMError::NO_ENTRY;
1128         HMI_SEQ_ERROR(req_num,
1129             "Window Manager bug :%s : Action is not set", errorDescription(ret));
1130         return ret;
1131     }
1132
1133     for (const auto &action : actions)
1134     {
1135         if (action.visible != TaskVisible::INVISIBLE)
1136         {
1137             sync_draw_happen = true;
1138
1139             // TODO: application requests by old role,
1140             //       so convert role new to old for emitting event
1141             std::string old_role = this->rolenew2old[action.role];
1142
1143             this->emit_syncdraw(old_role, action.area);
1144             /* TODO: emit event for app not subscriber
1145             if(g_app_list.contains(y.appid))
1146                 g_app_list.lookUpClient(y.appid)->emit_syncdraw(y.role, y.area); */
1147         }
1148     }
1149
1150     if (sync_draw_happen)
1151     {
1152         this->setTimer();
1153     }
1154     else
1155     {
1156         // deactivate only, no syncDraw
1157         // Make it deactivate here
1158         for (const auto &x : actions)
1159         {
1160             if (g_app_list.contains(x.appid))
1161             {
1162                 auto client = g_app_list.lookUpClient(x.appid);
1163                 this->deactivate(client->surfaceID(x.role));
1164             }
1165         }
1166         ret = NO_LAYOUT_CHANGE;
1167     }
1168     return ret;
1169 }
1170
1171 WMError WindowManager::setInvisibleTask(const std::string &role, bool split)
1172 {
1173     unsigned req_num = g_app_list.currentRequestNumber();
1174     HMI_SEQ_DEBUG(req_num, "set current visible app to invisible task");
1175     bool found = false;
1176     auto trigger = g_app_list.getRequest(req_num, &found);
1177     // I don't check found == true here because this is checked in caller.
1178     if(trigger.role == "homescreen")
1179     {
1180         HMI_SEQ_INFO(req_num, "In case of 'homescreen' visible, don't change app to invisible");
1181         return WMError::SUCCESS;
1182     }
1183
1184     // This task is copied from original actiavete surface
1185     const char *drawing_name = this->rolenew2old[role].c_str();
1186     auto const &surface_id = this->lookup_id(role.c_str());
1187     auto layer_id = this->layers.get_layer_id(*surface_id);
1188     auto o_state = *this->layers.get_layout_state(*surface_id);
1189     struct LayoutState &state = *o_state;
1190     std::string add_name, add_role;
1191     std::string add_area = "";
1192     int surface;
1193     TaskVisible task_visible = TaskVisible::INVISIBLE;
1194     bool end_draw_finished = true;
1195
1196     for (auto const &l : this->layers.mapping)
1197     {
1198         if (l.second.layer_id <= *layer_id)
1199         {
1200             continue;
1201         }
1202         HMI_DEBUG("wm", "debug: main %d , sub : %d", l.second.state.main, l.second.state.sub);
1203         if (l.second.state.main != -1)
1204         {
1205             //this->deactivate(l.second.state.main);
1206             surface = l.second.state.main;
1207             add_role = *this->id_alloc.lookup(surface);
1208             add_name = g_app_list.getAppID(surface, add_role, &found);
1209             if(!found){
1210                 return WMError::NOT_REGISTERED;
1211             }
1212             HMI_SEQ_INFO(req_num, "Invisible %s", add_name.c_str());
1213             WMAction act{add_name, add_role, add_area, task_visible, end_draw_finished};
1214             g_app_list.setAction(req_num, act);
1215             l.second.state.main = -1;
1216         }
1217
1218         if (l.second.state.sub != -1)
1219         {
1220             //this->deactivate(l.second.state.sub);
1221             surface = l.second.state.sub;
1222             add_role = *this->id_alloc.lookup(surface);
1223             add_name = g_app_list.getAppID(surface, add_role, &found);
1224             if (!found)
1225             {
1226                 return WMError::NOT_REGISTERED;
1227             }
1228             HMI_SEQ_INFO(req_num, "Invisible %s", add_name.c_str());
1229             WMAction act{add_name, add_role, add_area, task_visible, end_draw_finished};
1230             g_app_list.setAction(req_num, act);
1231             l.second.state.sub = -1;
1232         }
1233     }
1234
1235     // change current state here, but this is hack
1236     auto layer = this->layers.get_layer(*layer_id);
1237
1238     if (state.main == -1)
1239     {
1240         HMI_DEBUG("wm", "Layout: %s", kNameLayoutNormal);
1241     }
1242     else
1243     {
1244         if (0 != strcmp(drawing_name, "HomeScreen"))
1245         {
1246             if (split)
1247             {
1248                 if (state.sub != *surface_id)
1249                 {
1250                     if (state.sub != -1)
1251                     {
1252                         //this->deactivate(state.sub);
1253                         WMAction deact_sub;
1254                         deact_sub.role =
1255                             std::move(*this->id_alloc.lookup(state.sub));
1256                         deact_sub.area = add_area;
1257                         deact_sub.appid = g_app_list.getAppID(state.sub, deact_sub.role, &found);
1258                         if (!found)
1259                         {
1260                             HMI_SEQ_ERROR(req_num, "App doesn't exist for role : %s",
1261                                             deact_sub.role.c_str());
1262                             return WMError::NOT_REGISTERED;
1263                         }
1264                         deact_sub.visible = task_visible;
1265                         deact_sub.end_draw_finished = end_draw_finished;
1266                         HMI_SEQ_DEBUG(req_num, "Set invisible task for %s", deact_sub.appid.c_str());
1267                         g_app_list.setAction(req_num, deact_sub);
1268                     }
1269                 }
1270                 //state = LayoutState{state.main, *surface_id};
1271             }
1272             else
1273             {
1274                 HMI_DEBUG("wm", "Layout: %s", kNameLayoutNormal);
1275
1276                 //this->surface_set_layout(*surface_id);
1277                 if (state.main != *surface_id)
1278                 {
1279                     // this->deactivate(state.main);
1280                     WMAction deact_main;
1281                     deact_main.role = std::move(*this->id_alloc.lookup(state.main));
1282                     ;
1283                     deact_main.area = add_area;
1284                     deact_main.appid = g_app_list.getAppID(state.main, deact_main.role, &found);
1285                     if (!found)
1286                     {
1287                         HMI_SEQ_DEBUG(req_num, "sub surface ddoesn't exist");
1288                         return WMError::NOT_REGISTERED;
1289                     }
1290                     deact_main.visible = task_visible;
1291                     deact_main.end_draw_finished = end_draw_finished;
1292                     HMI_SEQ_DEBUG(req_num, "sub surface doesn't exist");
1293                     g_app_list.setAction(req_num, deact_main);
1294                 }
1295                 if (state.sub != -1)
1296                 {
1297                     if (state.sub != *surface_id)
1298                     {
1299                         //this->deactivate(state.sub);
1300                         WMAction deact_sub;
1301                         deact_sub.role = std::move(*this->id_alloc.lookup(state.sub));
1302                         ;
1303                         deact_sub.area = add_area;
1304                         deact_sub.appid = g_app_list.getAppID(state.sub, deact_sub.role, &found);
1305                         if (!found)
1306                         {
1307                             HMI_SEQ_DEBUG(req_num, "sub surface ddoesn't exist");
1308                             return WMError::NOT_REGISTERED;
1309                         }
1310                         deact_sub.visible = task_visible;
1311                         deact_sub.end_draw_finished = end_draw_finished;
1312                         HMI_SEQ_DEBUG(req_num, "sub surface doesn't exist");
1313                         g_app_list.setAction(req_num, deact_sub);
1314                     }
1315                 }
1316                 //state = LayoutState{*surface_id};
1317             }
1318         }
1319     }
1320     return WMError::SUCCESS;
1321 }
1322
1323 WMError WindowManager::doEndDraw(unsigned req_num)
1324 {
1325     // get actions
1326     bool found;
1327     auto actions = g_app_list.getActions(req_num, &found);
1328     WMError ret = WMError::SUCCESS;
1329     if (!found)
1330     {
1331         ret = WMError::NO_ENTRY;
1332         return ret;
1333     }
1334
1335     HMI_SEQ_INFO(req_num, "do endDraw");
1336
1337     // layout change and make it visible
1338     for (const auto &act : actions)
1339     {
1340         // layout change
1341         if(!g_app_list.contains(act.appid)){
1342             ret = WMError::NOT_REGISTERED;
1343         }
1344         ret = this->layoutChange(act);
1345         if(ret != WMError::SUCCESS)
1346         {
1347             HMI_SEQ_WARNING(req_num,
1348                 "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
1349             return ret;
1350         }
1351         ret = this->visibilityChange(act);
1352         if (ret != WMError::SUCCESS)
1353         {
1354             HMI_SEQ_WARNING(req_num,
1355                 "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
1356             return ret;
1357         }
1358         HMI_SEQ_DEBUG(req_num, "visible %s", act.role.c_str());
1359         //this->lm_enddraw(act.role.c_str());
1360     }
1361     this->layout_commit();
1362
1363     // Change current state
1364     this->changeCurrentState(req_num);
1365
1366     HMI_SEQ_INFO(req_num, "emit flushDraw");
1367
1368     for(const auto &act_flush : actions)
1369     {
1370         if(act_flush.visible != TaskVisible::INVISIBLE)
1371         {
1372             // TODO: application requests by old role,
1373             //       so convert role new to old for emitting event
1374             std::string old_role = this->rolenew2old[act_flush.role];
1375
1376             this->emit_flushdraw(old_role.c_str());
1377         }
1378     }
1379
1380     return ret;
1381 }
1382
1383 WMError WindowManager::layoutChange(const WMAction &action)
1384 {
1385     if (action.visible == TaskVisible::INVISIBLE)
1386     {
1387         // Visibility is not change -> no redraw is required
1388         return WMError::SUCCESS;
1389     }
1390     auto client = g_app_list.lookUpClient(action.appid);
1391     unsigned surface = client->surfaceID(action.role);
1392     if (surface == 0)
1393     {
1394         HMI_SEQ_ERROR(g_app_list.currentRequestNumber(),
1395                       "client doesn't have surface with role(%s)", action.role.c_str());
1396         return WMError::NOT_REGISTERED;
1397     }
1398     // Layout Manager
1399     WMError ret = this->setSurfaceSize(surface, action.area);
1400     return ret;
1401 }
1402
1403 WMError WindowManager::visibilityChange(const WMAction &action)
1404 {
1405     HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "Change visibility");
1406     if(!g_app_list.contains(action.appid)){
1407         return WMError::NOT_REGISTERED;
1408     }
1409     auto client = g_app_list.lookUpClient(action.appid);
1410     unsigned surface = client->surfaceID(action.role);
1411     if(surface == 0)
1412     {
1413         HMI_SEQ_ERROR(g_app_list.currentRequestNumber(),
1414                       "client doesn't have surface with role(%s)", action.role.c_str());
1415         return WMError::NOT_REGISTERED;
1416     }
1417
1418     if (action.visible != TaskVisible::INVISIBLE)
1419     {
1420         this->activate(surface); // Layout Manager task
1421     }
1422     else
1423     {
1424         this->deactivate(surface); // Layout Manager task
1425     }
1426     return WMError::SUCCESS;
1427 }
1428
1429 WMError WindowManager::setSurfaceSize(unsigned surface, const std::string &area)
1430 {
1431     this->surface_set_layout(surface, area);
1432
1433     return WMError::SUCCESS;
1434 }
1435
1436 WMError WindowManager::changeCurrentState(unsigned req_num)
1437 {
1438     HMI_SEQ_DEBUG(req_num, "Change current layout state");
1439     bool trigger_found = false, action_found = false;
1440     auto trigger = g_app_list.getRequest(req_num, &trigger_found);
1441     auto actions = g_app_list.getActions(req_num, &action_found);
1442     if (!trigger_found || !action_found)
1443     {
1444         HMI_SEQ_ERROR(req_num, "Action not found");
1445         return WMError::LAYOUT_CHANGE_FAIL;
1446     }
1447
1448     // Layout state reset
1449     struct LayoutState reset_state{-1, -1};
1450     HMI_SEQ_DEBUG(req_num,"Reset layout state");
1451     for (const auto &action : actions)
1452     {
1453         if(!g_app_list.contains(action.appid)){
1454             return WMError::NOT_REGISTERED;
1455         }
1456         auto client = g_app_list.lookUpClient(action.appid);
1457         auto pCurState = *this->layers.get_layout_state((int)client->surfaceID(action.role));
1458         if(pCurState == nullptr)
1459         {
1460             HMI_SEQ_ERROR(req_num, "Counldn't find current status");
1461             continue;
1462         }
1463         pCurState->main = reset_state.main;
1464         pCurState->sub = reset_state.sub;
1465     }
1466
1467     HMI_SEQ_DEBUG(req_num, "Change state");
1468     for (const auto &action : actions)
1469     {
1470         auto client = g_app_list.lookUpClient(action.appid);
1471         auto pLayerCurState = *this->layers.get_layout_state((int)client->surfaceID(action.role));
1472         if (pLayerCurState == nullptr)
1473         {
1474             HMI_SEQ_ERROR(req_num, "Counldn't find current status");
1475             continue;
1476         }
1477         int surface = -1;
1478
1479         if (action.visible != TaskVisible::INVISIBLE)
1480         {
1481             surface = (int)client->surfaceID(action.role);
1482             HMI_SEQ_INFO(req_num, "Change %s surface : %d, state visible area : %s",
1483                             action.role.c_str(), surface, action.area.c_str());
1484             // visible == true -> layout changes
1485             if(action.area == "normal.full" || action.area == "split.main")
1486             {
1487                 pLayerCurState->main = surface;
1488             }
1489             else if (action.area == "split.sub")
1490             {
1491                 pLayerCurState->sub = surface;
1492             }
1493             else
1494             {
1495                 // normalfull
1496                 pLayerCurState->main = surface;
1497             }
1498         }
1499     }
1500
1501     return WMError::SUCCESS;
1502 }
1503
1504 void WindowManager::emitScreenUpdated(unsigned req_num)
1505 {
1506     // Get visible apps
1507     HMI_SEQ_DEBUG(req_num, "emit screen updated");
1508     bool found = false;
1509     auto actions = g_app_list.getActions(req_num, &found);
1510
1511     // create json object
1512     json_object *j = json_object_new_object();
1513     json_object *jarray = json_object_new_array();
1514
1515     for(const auto& action: actions)
1516     {
1517         if(action.visible != TaskVisible::INVISIBLE)
1518         {
1519             json_object_array_add(jarray, json_object_new_string(action.appid.c_str()));
1520         }
1521     }
1522     json_object_object_add(j, kKeyIds, jarray);
1523     HMI_SEQ_INFO(req_num, "Visible app: %s", json_object_get_string(j));
1524
1525     int ret = afb_event_push(
1526         this->map_afb_event[kListEventName[Event_ScreenUpdated]], j);
1527     if (ret != 0)
1528     {
1529         HMI_DEBUG("wm", "afb_event_push failed: %m");
1530     }
1531 }
1532
1533 void WindowManager::setTimer()
1534 {
1535     struct timespec ts;
1536     if (clock_gettime(CLOCK_BOOTTIME, &ts) != 0) {
1537         HMI_ERROR("wm", "Could't set time (clock_gettime() returns with error");
1538         return;
1539     }
1540
1541     HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "Timer set activate");
1542     if (g_timer_ev_src == nullptr)
1543     {
1544         // firsttime set into sd_event
1545         int ret = sd_event_add_time(afb_daemon_get_event_loop(), &g_timer_ev_src,
1546             CLOCK_BOOTTIME, (uint64_t)(ts.tv_sec + kTimeOut) * 1000000ULL, 1, processTimerHandler, this);
1547         if (ret < 0)
1548         {
1549             HMI_ERROR("wm", "Could't set timer");
1550         }
1551     }
1552     else
1553     {
1554         // update timer limitation after second time
1555         sd_event_source_set_time(g_timer_ev_src, (uint64_t)(ts.tv_sec + kTimeOut) * 1000000ULL);
1556         sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_ONESHOT);
1557     }
1558 }
1559
1560 void WindowManager::stopTimer()
1561 {
1562     unsigned req_num = g_app_list.currentRequestNumber();
1563     HMI_SEQ_DEBUG(req_num, "Timer stop");
1564     int rc = sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_OFF);
1565     if (rc < 0)
1566     {
1567         HMI_SEQ_ERROR(req_num, "Timer stop failed");
1568     }
1569 }
1570
1571 void WindowManager::processNextRequest()
1572 {
1573     g_app_list.next();
1574     g_app_list.reqDump();
1575     unsigned req_num = g_app_list.currentRequestNumber();
1576     if (g_app_list.haveRequest())
1577     {
1578         HMI_SEQ_DEBUG(req_num, "Process next request");
1579         WMError rc = doTransition(req_num);
1580         if (rc != WMError::SUCCESS)
1581         {
1582             HMI_SEQ_ERROR(req_num, errorDescription(rc));
1583         }
1584     }
1585     else
1586     {
1587         HMI_SEQ_DEBUG(req_num, "Nothing Request. Waiting Request");
1588     }
1589 }
1590
1591 const char* WindowManager::convertRoleOldToNew(char const *old_role)
1592 {
1593     const char *new_role = nullptr;
1594
1595     for (auto const &on : this->roleold2new)
1596     {
1597         std::regex regex = std::regex(on.first);
1598         if (std::regex_match(old_role, regex))
1599         {
1600             // role is old. So convert to new.
1601             new_role = on.second.c_str();
1602             break;
1603         }
1604     }
1605
1606     if (nullptr == new_role)
1607     {
1608         // role is new or fallback.
1609         new_role = old_role;
1610     }
1611
1612     HMI_DEBUG("wm", "old:%s -> new:%s", old_role, new_role);
1613
1614     return new_role;
1615 }
1616
1617 int WindowManager::loadOldRoleDb()
1618 {
1619     // Get afm application installed dir
1620     char const *afm_app_install_dir = getenv("AFM_APP_INSTALL_DIR");
1621     HMI_DEBUG("wm", "afm_app_install_dir:%s", afm_app_install_dir);
1622
1623     std::string file_name;
1624     if (!afm_app_install_dir)
1625     {
1626         HMI_ERROR("wm", "AFM_APP_INSTALL_DIR is not defined");
1627     }
1628     else
1629     {
1630         file_name = std::string(afm_app_install_dir) + std::string("/etc/old_roles.db");
1631     }
1632
1633     // Load old_role.db
1634     json_object* json_obj;
1635     int ret = jh::inputJsonFilie(file_name.c_str(), &json_obj);
1636     if (0 > ret)
1637     {
1638         HMI_ERROR("wm", "Could not open old_role.db, so use default old_role information");
1639         json_obj = json_tokener_parse(kDefaultOldRoleDb);
1640     }
1641     HMI_DEBUG("wm", "json_obj dump:%s", json_object_get_string(json_obj));
1642
1643     // Perse apps
1644     json_object* json_cfg;
1645     if (!json_object_object_get_ex(json_obj, "old_roles", &json_cfg))
1646     {
1647         HMI_ERROR("wm", "Parse Error!!");
1648         return -1;
1649     }
1650
1651     int len = json_object_array_length(json_cfg);
1652     HMI_DEBUG("wm", "json_cfg len:%d", len);
1653     HMI_DEBUG("wm", "json_cfg dump:%s", json_object_get_string(json_cfg));
1654
1655     for (int i=0; i<len; i++)
1656     {
1657         json_object* json_tmp = json_object_array_get_idx(json_cfg, i);
1658
1659         const char* old_role = jh::getStringFromJson(json_tmp, "name");
1660         if (nullptr == old_role)
1661         {
1662             HMI_ERROR("wm", "Parse Error!!");
1663             return -1;
1664         }
1665
1666         const char* new_role = jh::getStringFromJson(json_tmp, "new");
1667         if (nullptr == new_role)
1668         {
1669             HMI_ERROR("wm", "Parse Error!!");
1670             return -1;
1671         }
1672
1673         this->roleold2new[old_role] = std::string(new_role);
1674     }
1675
1676     // Check
1677     for(auto itr = this->roleold2new.begin();
1678       itr != this->roleold2new.end(); ++itr)
1679     {
1680         HMI_DEBUG("wm", ">>> role old:%s new:%s",
1681                   itr->first.c_str(), itr->second.c_str());
1682     }
1683
1684     // Release json_object
1685     json_object_put(json_obj);
1686
1687     return 0;
1688 }
1689
1690 const char *WindowManager::check_surface_exist(const char *drawing_name)
1691 {
1692     auto const &surface_id = this->lookup_id(drawing_name);
1693     if (!surface_id)
1694     {
1695         return "Surface does not exist";
1696     }
1697
1698     if (!this->controller->surface_exists(*surface_id))
1699     {
1700         return "Surface does not exist in controller!";
1701     }
1702
1703     auto layer_id = this->layers.get_layer_id(*surface_id);
1704
1705     if (!layer_id)
1706     {
1707         return "Surface is not on any layer!";
1708     }
1709
1710     auto o_state = *this->layers.get_layout_state(*surface_id);
1711
1712     if (o_state == nullptr)
1713     {
1714         return "Could not find layer for surface";
1715     }
1716
1717     HMI_DEBUG("wm", "surface %d is detected", *surface_id);
1718     return nullptr;
1719 }
1720
1721 bool WindowManager::can_split(struct LayoutState const &state, int new_id)
1722 {
1723     if (state.main != -1 && state.main != new_id)
1724     {
1725         auto new_id_layer = this->layers.get_layer_id(new_id).value();
1726         auto current_id_layer = this->layers.get_layer_id(state.main).value();
1727
1728         // surfaces are on separate layers, don't bother.
1729         if (new_id_layer != current_id_layer)
1730         {
1731             return false;
1732         }
1733
1734         std::string const &new_id_str = this->lookup_name(new_id).value();
1735         std::string const &cur_id_str = this->lookup_name(state.main).value();
1736
1737         auto const &layer = this->layers.get_layer(new_id_layer);
1738
1739         HMI_DEBUG("wm", "layer info name: %s", layer->name.c_str());
1740
1741         if (layer->layouts.empty())
1742         {
1743             return false;
1744         }
1745
1746         for (auto i = layer->layouts.cbegin(); i != layer->layouts.cend(); i++)
1747         {
1748             HMI_DEBUG("wm", "%d main_match '%s'", new_id_layer, i->main_match.c_str());
1749             auto rem = std::regex(i->main_match);
1750             if (std::regex_match(cur_id_str, rem))
1751             {
1752                 // build the second one only if the first already matched
1753                 HMI_DEBUG("wm", "%d sub_match '%s'", new_id_layer, i->sub_match.c_str());
1754                 auto res = std::regex(i->sub_match);
1755                 if (std::regex_match(new_id_str, res))
1756                 {
1757                     HMI_DEBUG("wm", "layout matched!");
1758                     return true;
1759                 }
1760             }
1761         }
1762     }
1763
1764     return false;
1765 }
1766
1767 const char* WindowManager::kDefaultOldRoleDb = "{ \
1768     \"old_roles\": [ \
1769         { \
1770             \"name\": \"HomeScreen\", \
1771             \"new\": \"homescreen\" \
1772         }, \
1773         { \
1774             \"name\": \"Music\", \
1775             \"new\": \"music\" \
1776         }, \
1777         { \
1778             \"name\": \"MediaPlayer\", \
1779             \"new\": \"music\" \
1780         }, \
1781         { \
1782             \"name\": \"Video\", \
1783             \"new\": \"video\" \
1784         }, \
1785         { \
1786             \"name\": \"VideoPlayer\", \
1787             \"new\": \"video\" \
1788         }, \
1789         { \
1790             \"name\": \"WebBrowser\", \
1791             \"new\": \"browser\" \
1792         }, \
1793         { \
1794             \"name\": \"Radio\", \
1795             \"new\": \"radio\" \
1796         }, \
1797         { \
1798             \"name\": \"Phone\", \
1799             \"new\": \"phone\" \
1800         }, \
1801         { \
1802             \"name\": \"Navigation\", \
1803             \"new\": \"map\" \
1804         }, \
1805         { \
1806             \"name\": \"HVAC\", \
1807             \"new\": \"hvac\" \
1808         }, \
1809         { \
1810             \"name\": \"Settings\", \
1811             \"new\": \"settings\" \
1812         }, \
1813         { \
1814             \"name\": \"Dashboard\", \
1815             \"new\": \"dashboard\" \
1816         }, \
1817         { \
1818             \"name\": \"POI\", \
1819             \"new\": \"poi\" \
1820         }, \
1821         { \
1822             \"name\": \"Mixer\", \
1823             \"new\": \"mixer\" \
1824         }, \
1825         { \
1826             \"name\": \"Restriction\", \
1827             \"new\": \"restriction\" \
1828         }, \
1829         { \
1830             \"name\": \"^OnScreen.*\", \
1831             \"new\": \"on_screen\" \
1832         } \
1833     ] \
1834 }";
1835
1836 /**
1837  * controller_hooks
1838  */
1839 void controller_hooks::surface_created(uint32_t surface_id)
1840 {
1841     this->wmgr->surface_created(surface_id);
1842 }
1843
1844 void controller_hooks::surface_removed(uint32_t surface_id)
1845 {
1846     this->wmgr->surface_removed(surface_id);
1847 }
1848
1849 void controller_hooks::surface_visibility(uint32_t /*surface_id*/,
1850                                           uint32_t /*v*/) {}
1851
1852 void controller_hooks::surface_destination_rectangle(uint32_t /*surface_id*/,
1853                                                      uint32_t /*x*/,
1854                                                      uint32_t /*y*/,
1855                                                      uint32_t /*w*/,
1856                                                      uint32_t /*h*/) {}
1857
1858 } // namespace wm