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