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