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