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