31caebfd082c0f2106d212b6e32c7402e0a314da
[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 #include <sstream>
20
21 #include "window_manager.hpp"
22 #include "json_helper.hpp"
23 #include "applist.hpp"
24
25 extern "C"
26 {
27 #include <systemd/sd-event.h>
28 }
29
30 using std::string;
31 using std::vector;
32
33 namespace wm
34 {
35
36 static const uint64_t kTimeOut = 3ULL; /* 3s */
37
38 /* DrawingArea name used by "{layout}.{area}" */
39 const char kNameLayoutNormal[] = "normal";
40 const char kNameLayoutSplit[]  = "split";
41 const char kNameAreaFull[]     = "full";
42 const char kNameAreaMain[]     = "main";
43 const char kNameAreaSub[]      = "sub";
44
45 /* Key for json obejct */
46 const char kKeyDrawingName[] = "drawing_name";
47 const char kKeyDrawingArea[] = "drawing_area";
48 const char kKeyDrawingRect[] = "drawing_rect";
49 const char kKeyX[]           = "x";
50 const char kKeyY[]           = "y";
51 const char kKeyWidth[]       = "width";
52 const char kKeyHeight[]      = "height";
53 const char kKeyWidthPixel[]  = "width_pixel";
54 const char kKeyHeightPixel[] = "height_pixel";
55 const char kKeyWidthMm[]     = "width_mm";
56 const char kKeyHeightMm[]    = "height_mm";
57 const char kKeyScale[]       = "scale";
58 const char kKeyIds[]         = "ids";
59
60 static const char kPathOldRolesConfigFile[] = "/etc/old_roles.json";
61
62 static sd_event_source *g_timer_ev_src = nullptr;
63 static AppList g_app_list;
64 static WindowManager *g_context;
65
66 struct AfbClosure {
67 public:
68     AfbClosure(unsigned pid, unsigned ppid, unsigned surface)
69         : pid(pid), ppid(ppid), surface(surface) {}
70     ~AfbClosure() = default;
71     unsigned pid;
72     unsigned ppid;
73     unsigned surface;
74 };
75
76 namespace
77 {
78
79 static int processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata)
80 {
81     HMI_NOTICE("Time out occurs because the client replys endDraw slow, so revert the request");
82     reinterpret_cast<wm::WindowManager *>(userdata)->timerHandler();
83     return 0;
84 }
85
86 static void onStateTransitioned(vector<WMAction> actions)
87 {
88     g_context->startTransitionWrapper(actions);
89 }
90
91 static void onError()
92 {
93     g_context->processError(WMError::LAYOUT_CHANGE_FAIL);
94 }
95
96 static void onReceiveRemoteRequest(json_object *data)
97 {
98     g_context->processForRemoteRequest(data);
99 }
100 } // namespace
101
102 /**
103  * WindowManager Impl
104  */
105 WindowManager::WindowManager()
106     : wmcon{},
107       id_alloc{}
108 {
109     const char *path = getenv("AFM_APP_INSTALL_DIR");
110     if (!path)
111     {
112         HMI_ERROR("AFM_APP_INSTALL_DIR is not defined");
113     }
114     string root = path;
115
116     // TODO: ECU name should be decide by config file
117     // Get mode and decide ECU name
118     string ecu_name = this->wmcon.getEcuName();
119
120     this->lc = std::make_shared<LayerControl>(root, ecu_name);
121
122     HMI_DEBUG("Layer Controller initialized");
123 }
124
125 int WindowManager::init()
126 {
127     LayerControlCallbacks lmcb;
128     lmcb.surfaceCreated = [&](unsigned pid, unsigned surface){
129         this->surface_created(pid, surface);
130         };
131     lmcb.surfaceDestroyed = [&](unsigned surface){
132         this->surface_removed(surface);
133     };
134     this->lc->init(lmcb);
135
136     // TODO: application requests by old role,
137     //       so create role map (old, new)
138     // Load old_roles config file
139     this->loadOldRolesConfigFile();
140
141     // Initialize LowCanClient
142     this->lcc.initialize();
143
144     // Store my context for calling callback from PolicyManager
145     g_context = this;
146
147     // Initialize PMWrapper
148     this->pmw.initialize(this->wmcon.getEcuName());
149
150     // Register callback to PolicyManager
151     this->pmw.registerCallback(onStateTransitioned, onError);
152
153     // Initialize WMConnection
154     this->wmcon.initialize();
155
156     // Register callback to WMConnection
157     this->wmcon.registerCallback(onReceiveRemoteRequest);
158
159     // Make afb event
160     for (int i = Event_Val_Min; i <= Event_Val_Max; i++)
161     {
162         map_afb_event[kListEventName[i]] = afb_daemon_make_event(kListEventName[i]);
163     }
164
165     const struct rect css_bg = this->lc->getAreaSize("fullscreen");
166     Screen screen = this->lc->getScreenInfo();
167     rectangle dp_bg(screen.width(), screen.height());
168
169     dp_bg.set_aspect(static_cast<double>(css_bg.w) / css_bg.h);
170     dp_bg.fit(screen.width(), screen.height());
171     dp_bg.center(screen.width(), screen.height());
172     HMI_DEBUG("SCALING: CSS BG(%dx%d) -> DDP %dx%d,(%dx%d)",
173               css_bg.w, css_bg.h, dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
174
175     double scale = static_cast<double>(dp_bg.height()) / css_bg.h;
176     this->lc->setupArea(dp_bg, scale);
177
178     return 0; //init_layers();
179 }
180
181 result<int> WindowManager::api_request_surface(char const *appid, char const *drawing_name)
182 {
183     // TODO: application requests by old role,
184     //       so convert role old to new
185     const char *role = this->convertRoleOldToNew(drawing_name);
186     string l_name;
187     string s_appid = appid;
188     string s_role = role;
189
190     if(!g_app_list.contains(s_appid))
191     {
192         // auto lid = this->layers.get_layer_id(string(role));
193         unsigned l_id = this->lc->getNewLayerID(s_role, &l_name);
194         if (l_id == 0)
195         {
196             /**
197              * register drawing_name as fallback and make it displayed.
198              */
199             l_id = this->lc->getNewLayerID("fallback", &l_name);
200             HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
201             if (l_id == 0)
202             {
203                 return Err<int>("Designated role does not match any role, fallback is disabled");
204             }
205         }
206
207         // TODO: remote layer size is fixed value
208         if ("Remote" == l_name)
209         {
210             this->lc->createNewRemoteLayer(l_id);
211         }
212         else
213         {
214             this->lc->createNewLayer(l_id);
215         }
216
217         // add client into the db
218         g_app_list.addClient(s_appid, l_id, s_role);
219     }
220
221     // generate surface ID for ivi-shell application
222
223     auto rname = this->id_alloc.lookup(string(role));
224     if (!rname)
225     {
226         // name does not exist yet, allocate surface id...
227         auto id = int(this->id_alloc.generate_id(role));
228         this->tmp_surface2app[id] = {s_appid, 0};
229
230         // Set role map of (new, old)
231         this->rolenew2old[role] = string(drawing_name);
232
233         return Ok<int>(id);
234     }
235
236     // Check currently registered drawing names if it is already there.
237     return Err<int>("Surface already present");
238 }
239
240 char const *WindowManager::api_request_surface(char const *appid, char const *drawing_name,
241                                      char const *ivi_id)
242 {
243     unsigned sid = std::stol(ivi_id);
244
245     HMI_DEBUG("This API(requestSurfaceXDG) is for XDG Application using runXDG");
246     /*
247      * IVI-shell doesn't send surface_size event via ivi-wm protocol
248      * if the application is using XDG surface.
249      * So WM has to set surface size with original size here
250      */
251     WMError ret = this->lc->setXDGSurfaceOriginSize(sid);
252     if(ret != SUCCESS)
253     {
254         HMI_ERROR("%s", errorDescription(ret));
255         HMI_WARNING("The main user of this API is runXDG");
256         return "fail";
257     }
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 s_role = role;
263     string s_appid = appid;
264     string l_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             l_id = this->lc->getNewLayerID("fallback", &l_name);
276             HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
277             if (l_id == 0)
278             {
279                 return "Designated role does not match any role, fallback is disabled";
280             }
281         }
282
283         // TODO: remote layer size is fixed value
284         if ("Remote" == l_name)
285         {
286             this->lc->createNewRemoteLayer(l_id);
287         }
288         else
289         {
290             this->lc->createNewLayer(l_id);
291         }
292
293         // add client into the db
294         g_app_list.addClient(s_appid, l_id, s_role);
295     }
296
297     auto rname = this->id_alloc.lookup(s_role);
298     if (rname)
299     {
300         return "Surface already present";
301     }
302
303     // register pair drawing_name and ivi_id
304     this->id_alloc.register_name_id(role, sid);
305
306     auto client = g_app_list.lookUpClient(s_appid);
307     client->addSurface(sid);
308
309     // Set role map of (new, old)
310     this->rolenew2old[role] = string(drawing_name);
311
312     return nullptr;
313 }
314
315 bool WindowManager::api_set_role(char const *appid, char const *drawing_name)
316 {
317     bool ret = false;
318
319     // TODO: application requests by old role,
320     //       so convert role old to new
321     const char *role = this->convertRoleOldToNew(drawing_name);
322     string s_role = role;
323     string s_appid = appid;
324     string l_name;
325
326     // Create WMClient
327     if(!g_app_list.contains(s_appid))
328     {
329         // auto lid = this->layers.get_layer_id(string(role));
330         unsigned l_id = this->lc->getNewLayerID(s_role, &l_name);
331         if (l_id == 0)
332         {
333             /**
334              * register drawing_name as fallback and make it displayed.
335              */
336             l_id = this->lc->getNewLayerID("fallback", &l_name);
337             HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
338             if (l_id == 0)
339             {
340                 HMI_ERROR("Designated role does not match any role, fallback is disabled");
341                 return ret;
342             }
343         }
344
345         // TODO: remote layer size is fixed value
346         if ("Remote" == l_name)
347         {
348             this->lc->createNewRemoteLayer(l_id);
349         }
350         else
351         {
352             this->lc->createNewLayer(l_id);
353         }
354
355         // add client into the db
356         g_app_list.addClient(s_appid, l_id, s_role);
357         // Set role map of (new, old)
358         this->rolenew2old[role] = string(drawing_name);
359     }
360
361     // for(auto itr = this->tmp_surface2app.begin();
362     //         itr != this->tmp_surface2app.end() ; ++itr)
363     // {
364     for(auto& x : this->tmp_surface2app)
365     {
366         if(x.second.appid == s_appid)
367         {
368             unsigned surface = x.first;
369             auto client = g_app_list.lookUpClient(s_appid);
370             client->addSurface(surface);
371             this->tmp_surface2app.erase(surface);
372             this->id_alloc.register_name_id(s_role, surface);
373             break;
374         }
375     }
376
377 /*     if(0 != pid){
378         // search floating surfaceID from pid if pid is designated.
379         wm_err = g_app_list.popFloatingSurface(pid, &surface);
380     }
381     else{
382         // get floating surface with appid. If WM queries appid from pid,
383         // WM can bind surface and role with appid(not implemented yet)
384         //wm_err = g_app_list.popFloatingSurface(id);
385     }
386     if(wm_err != WMError::SUCCESS){
387         HMI_ERROR("No floating surface for app: %s", id.c_str());
388         g_app_list.addFloatingClient(id, lid, role);
389         HMI_NOTICE("%s : Waiting for surface creation", id.c_str());
390         return ret;
391     }
392
393     ret = true;
394     if (g_app_list.contains(id))
395     {
396         HMI_INFO("Add role: %s with surface: %d. Client %s has multi surfaces.",
397                  role.c_str(), surface, id.c_str());
398         auto client = g_app_list.lookUpClient(id);
399         client->appendRole(role);
400     }
401     else{
402         HMI_INFO("Create new client: %s, surface: %d into layer: %d with role: %s",
403                  id.c_str(), surface, lid, role.c_str());
404         g_app_list.addClient(id, lid, role);
405     } */
406
407     // register pair drawing_name and ivi_id
408
409     return true;
410 }
411
412 void WindowManager::api_activate_surface(char const *appid, char const *drawing_name,
413                                char const *drawing_area, const reply_func &reply)
414 {
415     // TODO: application requests by old role,
416     //       so convert role old to new
417     const char *c_role = this->convertRoleOldToNew(drawing_name);
418
419     string id = appid;
420     string role = c_role;
421     string area = drawing_area;
422
423     if(!g_app_list.contains(id))
424     {
425         reply("app doesn't request 'requestSurface' or 'setRole' yet");
426         return;
427     }
428     auto client = g_app_list.lookUpClient(id);
429
430     // unsigned srfc = client->surfaceID(role);
431     // unsigned layer = client->layerID();
432
433     // g_app_list.removeFloatingSurface(client->surfaceID());
434     // g_app_list.removeFloatingSurface(client);
435
436     Task task = Task::TASK_ALLOCATE;
437     unsigned req_num = 0;
438     WMError ret = WMError::UNKNOWN;
439
440     ret = this->setRequest(id, role, area, task, &req_num);
441
442     //vector<WMLayerState> current_states = this->lc->getCurrentStates();
443     // ret = this->setRequest(id, role, area, task, current_states, &req_num);
444
445     if(ret != WMError::SUCCESS)
446     {
447         HMI_ERROR(errorDescription(ret));
448         reply("Failed to set request");
449         return;
450     }
451
452     reply(nullptr);
453     if (req_num != g_app_list.currentRequestNumber())
454     {
455         // Add request, then invoked after the previous task is finished
456         HMI_SEQ_DEBUG(req_num, "request is accepted");
457         return;
458     }
459
460     /*
461      * Do allocate tasks
462      */
463     ret = this->checkPolicy(req_num);
464
465     if (ret != WMError::SUCCESS)
466     {
467         //this->emit_error()
468         HMI_SEQ_ERROR(req_num, errorDescription(ret));
469         g_app_list.removeRequest(req_num);
470         this->processNextRequest();
471     }
472 }
473
474 void WindowManager::api_activate_surface_for_slave(
475                                char const *appid, char const *drawing_name,
476                                char const *drawing_area, const reply_func &reply)
477 {
478     // TODO: application requests by old role,
479     //       so convert role old to new
480     const char *c_role = this->convertRoleOldToNew(drawing_name);
481
482     string id = appid;
483     string role = c_role;
484     string area = drawing_area;
485
486     if(!g_app_list.contains(id))
487     {
488         // Request surface of app in slave to register app information
489         this->api_request_surface(appid, drawing_name);
490
491         // Set role of app in slave to register app information
492         this->api_set_role(appid, drawing_name);
493     }
494     auto client = g_app_list.lookUpClient(id);
495
496     // unsigned srfc = client->surfaceID(role);
497     // unsigned layer = client->layerID();
498
499     // g_app_list.removeFloatingSurface(client->surfaceID());
500     // g_app_list.removeFloatingSurface(client);
501
502     Task task = Task::TASK_ALLOCATE;
503     unsigned req_num = 0;
504     WMError ret = WMError::UNKNOWN;
505
506     ret = this->setRequestForSlave(id, role, area, task, &req_num);
507
508     //vector<WMLayerState> current_states = this->lc->getCurrentStates();
509     // ret = this->setRequest(id, role, area, task, current_states, &req_num);
510
511     if(ret != WMError::SUCCESS)
512     {
513         HMI_ERROR(errorDescription(ret));
514         reply("Failed to set request");
515         return;
516     }
517
518     reply(nullptr);
519     if (req_num != g_app_list.currentRequestNumber())
520     {
521         // Add request, then invoked after the previous task is finished
522         HMI_SEQ_DEBUG(req_num, "request is accepted");
523         return;
524     }
525
526     /*
527      * Do allocate tasks
528      */
529     ret = this->checkPolicyForSlave(req_num);
530
531     if (ret != WMError::SUCCESS)
532     {
533         //this->emit_error()
534         HMI_SEQ_ERROR(req_num, errorDescription(ret));
535         g_app_list.removeRequest(req_num);
536         this->processNextRequest();
537     }
538 }
539
540 void WindowManager::api_activate_surface_to_master(
541                                char const *appid, char const *drawing_name,
542                                char const *drawing_area, const reply_func &reply)
543 {
544     // TODO: application requests by old role,
545     //       so convert role old to new
546     const char *c_role = this->convertRoleOldToNew(drawing_name);
547
548     string id = appid;
549     string role = c_role;
550     string area = drawing_area;
551
552     if(!g_app_list.contains(id))
553     {
554         reply("app doesn't request 'requestSurface' or 'setRole' yet");
555         return;
556     }
557     auto client = g_app_list.lookUpClient(id);
558
559     // unsigned srfc = client->surfaceID(role);
560     // unsigned layer = client->layerID();
561
562     // g_app_list.removeFloatingSurface(client->surfaceID());
563     // g_app_list.removeFloatingSurface(client);
564
565     Task task = Task::TASK_ALLOCATE;
566     unsigned req_num = 0;
567     WMError ret = WMError::UNKNOWN;
568
569     ret = this->setRequest(id, role, area, task, &req_num);
570
571     //vector<WMLayerState> current_states = this->lc->getCurrentStates();
572     // ret = this->setRequest(id, role, area, task, current_states, &req_num);
573
574     if(ret != WMError::SUCCESS)
575     {
576         HMI_ERROR(errorDescription(ret));
577         reply("Failed to set request");
578         return;
579     }
580
581     reply(nullptr);
582     if (req_num != g_app_list.currentRequestNumber())
583     {
584         // Add request, then invoked after the previous task is finished
585         HMI_SEQ_DEBUG(req_num, "request is accepted");
586         return;
587     }
588
589     /*
590      * Do allocate tasks
591      */
592     int i_ret = this->wmcon.sendRequest("activateWindow", appid,
593                                         drawing_name, drawing_area);
594     if (0 > i_ret)
595     {
596         //this->emit_error()
597         HMI_SEQ_ERROR(req_num, errorDescription(ret));
598         g_app_list.removeRequest(req_num);
599         this->processNextRequest();
600     }
601
602     this->setTimer();
603 }
604
605 void WindowManager::api_deactivate_surface(char const *appid, char const *drawing_name,
606                                  const reply_func &reply)
607 {
608     // TODO: application requests by old role,
609     //       so convert role old to new
610     const char *c_role = this->convertRoleOldToNew(drawing_name);
611
612     /*
613     * Check Phase
614     */
615     string id = appid;
616     string role = c_role;
617     string area = ""; //drawing_area;
618     Task task = Task::TASK_RELEASE;
619     unsigned req_num = 0;
620     WMError ret = WMError::UNKNOWN;
621
622     ret = this->setRequest(id, role, area, task, &req_num);
623
624     if (ret != WMError::SUCCESS)
625     {
626         HMI_ERROR(errorDescription(ret));
627         reply("Failed to set request");
628         return;
629     }
630
631     reply(nullptr);
632     if (req_num != g_app_list.currentRequestNumber())
633     {
634         // Add request, then invoked after the previous task is finished
635         HMI_SEQ_DEBUG(req_num, "request is accepted");
636         return;
637     }
638
639     /*
640     * Do allocate tasks
641     */
642     ret = this->checkPolicy(req_num);
643
644     if (ret != WMError::SUCCESS)
645     {
646         //this->emit_error()
647         HMI_SEQ_ERROR(req_num, errorDescription(ret));
648         g_app_list.removeRequest(req_num);
649         this->processNextRequest();
650     }
651 }
652
653 void WindowManager::api_deactivate_surface_for_slave(char const *appid, char const *drawing_name,
654                                  const reply_func &reply)
655 {
656     // TODO: application requests by old role,
657     //       so convert role old to new
658     const char *c_role = this->convertRoleOldToNew(drawing_name);
659
660     /*
661     * Check Phase
662     */
663     string id = appid;
664     string role = c_role;
665     string area = "";//drawing_area;
666     Task task = Task::TASK_RELEASE;
667     unsigned req_num = 0;
668     WMError ret = WMError::UNKNOWN;
669
670     ret = this->setRequest(id, role, area, task, &req_num);
671
672     if (ret != WMError::SUCCESS)
673     {
674         HMI_ERROR(errorDescription(ret));
675         reply("Failed to set request");
676         return;
677     }
678
679     reply(nullptr);
680     if (req_num != g_app_list.currentRequestNumber())
681     {
682         // Add request, then invoked after the previous task is finished
683         HMI_SEQ_DEBUG(req_num, "request is accepted");
684         return;
685     }
686
687     /*
688     * Do allocate tasks
689     */
690     ret = this->checkPolicyForSlave(req_num);
691
692     if (ret != WMError::SUCCESS)
693     {
694         //this->emit_error()
695         HMI_SEQ_ERROR(req_num, errorDescription(ret));
696         g_app_list.removeRequest(req_num);
697         this->processNextRequest();
698     }
699 }
700
701 void WindowManager::api_deactivate_surface_to_master(char const *appid, char const *drawing_name,
702                                  const reply_func &reply)
703 {
704     // TODO: application requests by old role,
705     //       so convert role old to new
706     const char *c_role = this->convertRoleOldToNew(drawing_name);
707
708     /*
709     * Check Phase
710     */
711     string id = appid;
712     string role = c_role;
713     string area = "";//drawing_area;
714     Task task = Task::TASK_RELEASE;
715     unsigned req_num = 0;
716     WMError ret = WMError::UNKNOWN;
717
718     ret = this->setRequest(id, role, area, task, &req_num);
719
720     if (ret != WMError::SUCCESS)
721     {
722         HMI_ERROR(errorDescription(ret));
723         reply("Failed to set request");
724         return;
725     }
726
727     reply(nullptr);
728     if (req_num != g_app_list.currentRequestNumber())
729     {
730         // Add request, then invoked after the previous task is finished
731         HMI_SEQ_DEBUG(req_num, "request is accepted");
732         return;
733     }
734
735     /*
736     * Do allocate tasks
737     */
738     int i_ret = this->wmcon.sendRequest("deactivateWindow", appid,
739                                         drawing_name, "");
740     if (0 > i_ret)
741     {
742         //this->emit_error()
743         HMI_SEQ_ERROR(req_num, errorDescription(ret));
744         g_app_list.removeRequest(req_num);
745         this->processNextRequest();
746     }
747
748     this->setTimer();
749 }
750
751 void WindowManager::api_enddraw(char const *appid, char const *drawing_name)
752 {
753     // TODO: application requests by old role,
754     //       so convert role old to new
755     const char *c_role = this->convertRoleOldToNew(drawing_name);
756
757     string id = appid;
758     string role = c_role;
759     unsigned current_req = g_app_list.currentRequestNumber();
760     bool result = g_app_list.setEndDrawFinished(current_req, id, role);
761
762     if (!result)
763     {
764         HMI_ERROR("%s is not in transition state", id.c_str());
765         return;
766     }
767
768     if (g_app_list.endDrawFullfilled(current_req))
769     {
770         // do task for endDraw
771         this->stopTimer();
772         WMError ret = this->doEndDraw(current_req);
773
774         if(ret != WMError::SUCCESS)
775         {
776             //this->emit_error();
777
778             // Undo state of PolicyManager
779             this->pmw.undoState();
780             this->lc->undoUpdate();
781         }
782         this->emitScreenUpdated(current_req);
783         HMI_SEQ_INFO(current_req, "Finish request status: %s", errorDescription(ret));
784
785         g_app_list.removeRequest(current_req);
786
787         this->processNextRequest();
788     }
789     else
790     {
791         HMI_SEQ_INFO(current_req, "Wait other App call endDraw");
792         return;
793     }
794 }
795
796 void WindowManager::api_enddraw_for_remote(char const *appid, char const *drawing_name)
797 {
798     int ret = this->wmcon.sendRequest("endDraw", appid, drawing_name, "");
799     if (0 > ret)
800     {
801         //this->emit_error()
802
803         this->pmw.undoState();
804         this->lc->undoUpdate();
805
806         unsigned current_req = g_app_list.currentRequestNumber();
807         g_app_list.removeRequest(current_req);
808         this->processNextRequest();
809
810         return;
811     }
812
813     this->api_enddraw(appid, drawing_name);
814 }
815
816 bool WindowManager::api_client_set_render_order(char const* appid, const vector<string>& render_order)
817 {
818     bool ret = false;
819     string id = appid;
820     auto client = g_app_list.lookUpClient(id);
821     if(client)
822     {
823         client->setRenderOrder(render_order);
824     }
825     return ret;
826 }
827
828 string WindowManager::api_client_attach_service_surface
829     (const char* appid, const char* dest, const char* service_surface)
830 {
831     string uuid, s_dest = dest;
832     auto client = g_app_list.lookUpClient(s_dest);
833     if(!client)
834     {
835         HMI_ERROR("Failed to look up destination [%s]", dest);
836         return uuid;
837     }
838     uuid = client->attachTmpServiceSurface(appid, service_surface);
839     this->tmp_services.emplace_back(TmpService{appid, dest, service_surface, uuid});
840     return uuid;
841 }
842
843 result<json_object *> WindowManager::api_get_display_info()
844 {
845     Screen screen = this->lc->getScreenInfo();
846
847     json_object *object = json_object_new_object();
848     json_object_object_add(object, kKeyWidthPixel, json_object_new_int(screen.width()));
849     json_object_object_add(object, kKeyHeightPixel, json_object_new_int(screen.height()));
850     // TODO: set size
851     json_object_object_add(object, kKeyWidthMm, json_object_new_int(0));
852     json_object_object_add(object, kKeyHeightMm, json_object_new_int(0));
853     json_object_object_add(object, kKeyScale, json_object_new_double(this->lc->scale()));
854
855     return Ok<json_object *>(object);
856 }
857
858 result<json_object *> WindowManager::api_get_area_info(char const *drawing_name)
859 {
860     HMI_DEBUG("called");
861
862     // TODO: application requests by old role,
863     //       so convert role old to new
864     const char *role = this->convertRoleOldToNew(drawing_name);
865
866     // Check drawing name, surface/layer id
867     auto const &surface_id = this->id_alloc.lookup(string(role));
868     if (!surface_id)
869     {
870         return Err<json_object *>("Surface does not exist");
871     }
872
873     // Set area rectangle
874     rect area_info = this->area_info[*surface_id];
875     json_object *object = json_object_new_object();
876     json_object_object_add(object, kKeyX, json_object_new_int(area_info.x));
877     json_object_object_add(object, kKeyY, json_object_new_int(area_info.y));
878     json_object_object_add(object, kKeyWidth, json_object_new_int(area_info.w));
879     json_object_object_add(object, kKeyHeight, json_object_new_int(area_info.h));
880
881     return Ok<json_object *>(object);
882 }
883
884 result<json_object *> WindowManager::api_get_car_info(char const *label)
885 {
886     json_object *j_in  = nullptr;
887     json_object *j_out = nullptr;
888
889     if (0 == strcmp("parking_brake_status", label))
890     {
891         // Get parking brake status
892         json_bool val = (this->crr_car_info.parking_brake_stt) ? TRUE : FALSE;
893         j_in = json_object_new_boolean(val);
894     }
895     else if (0 == strcmp("accelerator.pedal.position", label))
896     {
897         // Get accelerator pedal position
898         double val = this->crr_car_info.accel_pedal_pos;
899         j_in = json_object_new_double(val);
900     }
901     else if (0 == strcmp("car_state", label))
902     {
903         // Get running state
904         const char* val = (this->crr_car_info.running_stt) ? "run" : "stop";
905         j_in = json_object_new_string(val);
906     }
907     else if (0 == strcmp("lightstatus.brake", label)) {
908         // Get lightstatus brake status
909         json_bool val = (this->crr_car_info.lightstatus_brake_stt) ? TRUE : FALSE;
910         j_in = json_object_new_boolean(val);
911     }
912     else
913     {
914        return Err<json_object *>("Car info does not exist");
915     }
916
917     // Create output object
918     j_out = json_object_new_object();
919     json_object_object_add(j_out, "value", j_in);
920
921     return Ok<json_object *>(j_out);
922 }
923
924 void WindowManager::send_event(char const *evname)
925 {
926     HMI_DEBUG("%s: %s", __func__, evname);
927
928     int ret = afb_event_push(this->map_afb_event[evname], nullptr);
929     if (ret != 0)
930     {
931         HMI_DEBUG("afb_event_push: %m");
932     }
933 }
934
935 void WindowManager::send_event(char const *evname, char const *label)
936 {
937     HMI_DEBUG("%s: %s(%s)", __func__, evname, label);
938
939     json_object *j = json_object_new_object();
940     json_object_object_add(j, kKeyDrawingName, json_object_new_string(label));
941
942     int ret = afb_event_push(this->map_afb_event[evname], j);
943     if (ret != 0)
944     {
945         HMI_DEBUG("afb_event_push failed: %m");
946     }
947 }
948
949 void WindowManager::send_event(char const *evname, char const *label, char const *area,
950                      int x, int y, int w, int h)
951 {
952     HMI_DEBUG("%s: %s(%s, %s) x:%d y:%d w:%d h:%d",
953               __func__, evname, label, area, x, y, w, h);
954
955     json_object *j_rect = json_object_new_object();
956     json_object_object_add(j_rect, kKeyX, json_object_new_int(x));
957     json_object_object_add(j_rect, kKeyY, json_object_new_int(y));
958     json_object_object_add(j_rect, kKeyWidth, json_object_new_int(w));
959     json_object_object_add(j_rect, kKeyHeight, json_object_new_int(h));
960
961     json_object *j = json_object_new_object();
962     json_object_object_add(j, kKeyDrawingName, json_object_new_string(label));
963     json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area));
964     json_object_object_add(j, kKeyDrawingRect, j_rect);
965
966     int ret = afb_event_push(this->map_afb_event[evname], j);
967     if (ret != 0)
968     {
969         HMI_DEBUG("afb_event_push failed: %m");
970     }
971 }
972
973 string WindowManager::searchApp(unsigned pid, unsigned ppid, unsigned surface, json_object* resp)
974 {
975     // retrieve appid from pid from application manager
976     string appid;
977     // check appid then add it to the client
978     HMI_INFO("Runners:%s", json_object_get_string(resp));
979     int size = json_object_array_length(resp);
980     HMI_INFO("pid %d, ppid %d, surface %d",pid, ppid, surface);
981     for(int i = 0; i < size; i++)
982     {
983         json_object *j = json_object_array_get_idx(resp, i);
984         int runid      = jh::getIntFromJson(j, "runid");
985         const char* id = jh::getStringFromJson(j, "id");
986         HMI_DEBUG("Appid %s, runid %d", id, runid);
987         if(id && (runid == ppid))
988         {
989             string s_id = id;
990             s_id.erase(s_id.find('@'));
991             appid = s_id;
992             HMI_INFO("App found %s", appid.c_str());
993             break;
994         }
995     }
996     if(appid.empty())
997     {
998         HMI_WARNING("Failed to retrieve id");
999     }
1000     return appid;
1001 }
1002
1003 void WindowManager::storeSurface(const string& appid, unsigned ppid, unsigned surface)
1004 {
1005     auto elem = std::find_if(this->tmp_services.begin(), this->tmp_services.end(),
1006                 [&appid](TmpService& ts){
1007                     return (ts.dest == appid );
1008                 });
1009
1010     this->lc->setXDGSurfaceOriginSize(surface);
1011     if(elem != this->tmp_services.end())
1012     {
1013         // attachApp
1014         auto client = g_app_list.lookUpClient(elem->dest);
1015         if(client == nullptr)
1016         {
1017             return;
1018         }
1019         HMI_INFO("Attach surface %d (service %s) to app %s", surface, elem->service.c_str(), elem->dest.c_str());
1020         client->attachServiceSurface(elem->service, surface);
1021     }
1022     else
1023     {
1024         // setRole
1025         auto client = g_app_list.lookUpClient(appid);
1026         if(client != nullptr)
1027         {
1028             client->addSurface(surface);
1029             this->id_alloc.register_name_id(client->role(), surface);
1030         }
1031         else
1032         {
1033             // Store tmp surface and appid for application
1034             // who requests setRole after creating shell surface
1035             this->tmp_surface2app.emplace(surface, TmpClient{appid, ppid});
1036         }
1037     }
1038 }
1039
1040 /**
1041  * proxied events
1042  */
1043 void WindowManager::surface_created(unsigned pid, unsigned surface_id)
1044 {
1045     // requestSurface
1046     if(this->tmp_surface2app.count(surface_id) != 0)
1047     {
1048         string appid = this->tmp_surface2app[surface_id].appid;
1049         auto client = g_app_list.lookUpClient(appid);
1050         if(client != nullptr)
1051         {
1052             WMError ret = client->addSurface(surface_id);
1053             HMI_INFO("Add surface %d to \"%s\"", surface_id, appid.c_str());
1054             if(ret != WMError::SUCCESS)
1055             {
1056                 HMI_ERROR("Failed to add surface to client %s", client->appID().c_str());
1057             }
1058         }
1059         this->tmp_surface2app.erase(surface_id);
1060     }
1061     else
1062     {
1063         HMI_NOTICE("Unknown surface %d", surface_id);
1064         // retrieve ppid
1065         std::ostringstream os;
1066         os << pid ;
1067         string path = "/proc/" + os.str() + "/stat";
1068         std::ifstream ifs(path.c_str());
1069         string str;
1070         unsigned ppid = 0;
1071         if(!ifs.fail() && std::getline(ifs, str))
1072         {
1073             std::sscanf(str.data(), "%*d %*s %*c %d", &ppid);
1074             HMI_INFO("Retrieve ppid %d", ppid);
1075         }
1076         else
1077         {
1078             HMI_ERROR("Failed to open /proc/%d/stat", pid);
1079             HMI_ERROR("File system may be different");
1080             return;
1081         }
1082         struct AfbClosure* c = new struct AfbClosure(pid, ppid, surface_id);
1083         // search pid from surfaceID
1084         afb_service_call("afm-main", "runners", json_object_new_object(),
1085             [](void* closure, int stat, json_object* resp){
1086                 HMI_DEBUG("check %s", json_object_get_string(resp));
1087                 struct AfbClosure* c = static_cast<struct AfbClosure*>(closure);
1088                 HMI_DEBUG("check");
1089                 if(stat != 0)
1090                 {
1091                     HMI_ERROR("Failed to call runners");
1092                 }
1093                 else
1094                 {
1095                     json_object* j;
1096                     json_object_object_get_ex(resp, "response", &j);
1097                     string appid = g_context->searchApp(c->pid, c->ppid, c->surface, j);
1098                     if(!appid.empty())
1099                     {
1100                         g_context->storeSurface(appid, c->ppid, c->surface);
1101                     }
1102                 }
1103                 json_object_put(resp);
1104                 delete c;
1105             }, c);
1106     }
1107 }
1108
1109 void WindowManager::surface_removed(unsigned surface_id)
1110 {
1111     HMI_DEBUG("Delete surface_id %u", surface_id);
1112     this->id_alloc.remove_id(surface_id);
1113     // this->layers.remove_surface(surface_id);
1114     g_app_list.removeSurface(surface_id);
1115 }
1116
1117 void WindowManager::removeClient(const string &appid)
1118 {
1119     HMI_DEBUG("Remove clinet %s from list", appid.c_str());
1120     auto client = g_app_list.lookUpClient(appid);
1121     this->lc->terminateApp(client);
1122     g_app_list.removeClient(appid);
1123 }
1124
1125 void WindowManager::exceptionProcessForTransition()
1126 {
1127     unsigned req_num = g_app_list.currentRequestNumber();
1128     HMI_SEQ_NOTICE(req_num, "Process exception handling for request. Remove current request %d", req_num);
1129     g_app_list.removeRequest(req_num);
1130     HMI_SEQ_NOTICE(g_app_list.currentRequestNumber(), "Process next request if exists");
1131     this->processNextRequest();
1132 }
1133
1134 void WindowManager::analyzeReceivedEvent(const char *event, struct json_object *object)
1135 {
1136     HMI_DEBUG("event:%s", event);
1137
1138     // If receive low can signal
1139     if (strstr(event, "low-can"))
1140     {
1141         // Analyze low can signal
1142         const char *signal_name = this->lcc.analyzeCanSignal(object);
1143
1144         // Create task for car state and input it to PolicyManager
1145         Task task = this->convertCanSignalToCarStateTask(signal_name);
1146         if (Task::TASK_INVALID != task)
1147         {
1148             this->inputCarStateTask(task);
1149         }
1150     }
1151 }
1152
1153 void WindowManager::timerHandler()
1154 {
1155     unsigned req_num = g_app_list.currentRequestNumber();
1156     HMI_SEQ_DEBUG(req_num, "Timer expired remove Request");
1157     g_app_list.reqDump();
1158     g_app_list.removeRequest(req_num);
1159     this->processNextRequest();
1160 }
1161
1162 void WindowManager::startTransitionWrapper(vector<WMAction> &actions)
1163 {
1164     WMError ret = WMError::UNKNOWN;
1165     // req_num is guaranteed by Window Manager
1166     unsigned req_num = g_app_list.currentRequestNumber();
1167     Task task = Task::TASK_INVALID;
1168
1169     if (actions.empty())
1170     {
1171         if (g_app_list.haveRequest())
1172         {
1173             HMI_SEQ_DEBUG(req_num, "There is no WMAction for this request");
1174             goto proc_remove_request;
1175         }
1176         else
1177         {
1178             HMI_SEQ_DEBUG(req_num, "There is no request");
1179             return;
1180         }
1181     }
1182
1183     // Check weather there is the no request task
1184     //   [The no request task]
1185     //     - TaskCarState::RESTRICTION_MODE_OFF
1186     //     - TaskCarState::RESTRICTION_MODE_ON
1187     for (const auto &act : actions)
1188     {
1189         if (TaskCarState::RESTRICTION_MODE_OFF == act.car_state)
1190         {
1191             task = Task::TASK_RESTRICTION_MODE_OFF;
1192             break;
1193         }
1194         else if (TaskCarState::RESTRICTION_MODE_ON == act.car_state)
1195         {
1196             task = Task::TASK_RESTRICTION_MODE_ON;
1197             break;
1198         }
1199     }
1200
1201     // If there is the request-less task, set request here
1202     if (Task::TASK_INVALID != task) {
1203         unsigned req_num;
1204         ret = this->setRequest(task, &req_num);
1205
1206         if(ret != WMError::SUCCESS)
1207         {
1208             goto error;
1209         }
1210     }
1211
1212     for (auto &act : actions)
1213     {
1214         if ("" != act.role)
1215         {
1216             bool found;
1217             auto const &surface_id = this->id_alloc.lookup(act.role.c_str());
1218             if(surface_id == nullopt)
1219             {
1220                 HMI_SEQ_DEBUG(req_num, "There is not surface id for role:%s", act.role.c_str());
1221                 continue;
1222             }
1223
1224             std::string appid = g_app_list.getAppID(*surface_id, &found);
1225             if (!found)
1226             {
1227                 if (TaskVisible::INVISIBLE == act.visible)
1228                 {
1229                     HMI_SEQ_DEBUG(req_num, "role:%s is killed, so do not set this action", act.role.c_str());
1230                     continue;
1231                 }
1232                 else
1233                 {
1234                     HMI_SEQ_ERROR(req_num, "appid of role:%s which is visible is not found", act.role.c_str());
1235                     ret = WMError::FAIL;
1236                     goto error;
1237                 }
1238             }
1239             auto client = g_app_list.lookUpClient(appid);
1240             act.req_num = req_num;
1241             act.client = client;
1242
1243             // If Window Manager is master and this action is for slave,
1244             // change TaskVisible
1245             if (this->wmcon.isMasterMode())
1246             {
1247                 if (this->wmcon.isMasterArea(act.area.c_str()))
1248                 {
1249                     HMI_DEBUG("Set TaskVisible::REQ_REMOTE_VISIBLE");
1250                     act.visible = TaskVisible::REQ_REMOTE_VISIBLE;
1251                 }
1252                 // TODO: Check whether role is tbtnavi to request remote invisible
1253                 else if (("tbtnavi" == act.role) &&
1254                          (TaskVisible::INVISIBLE == act.visible))
1255                 {
1256                     HMI_DEBUG("Set TaskVisible::REQ_REMOTE_INVISIBLE");
1257                     act.visible = TaskVisible::REQ_REMOTE_INVISIBLE;
1258                 }
1259             }
1260         }
1261
1262         ret = g_app_list.setAction(req_num, act);
1263         if (ret != WMError::SUCCESS)
1264         {
1265             HMI_SEQ_ERROR(req_num, "Setting action is failed");
1266             goto error;
1267         }
1268     }
1269
1270     HMI_SEQ_DEBUG(req_num, "Start transition.");
1271     ret = this->startTransition(req_num);
1272     if (ret != WMError::SUCCESS)
1273     {
1274         if (ret == WMError::NO_LAYOUT_CHANGE)
1275         {
1276             goto proc_remove_request;
1277         }
1278         else
1279         {
1280             HMI_SEQ_ERROR(req_num, "Transition state is failed");
1281             goto error;
1282         }
1283     }
1284
1285     return;
1286
1287 error:
1288     //this->emit_error()
1289     HMI_SEQ_ERROR(req_num, errorDescription(ret));
1290     this->pmw.undoState();
1291
1292 proc_remove_request:
1293     g_app_list.removeRequest(req_num);
1294     this->processNextRequest();
1295 }
1296
1297 void WindowManager::processError(WMError error)
1298 {
1299     unsigned req_num = g_app_list.currentRequestNumber();
1300
1301     //this->emit_error()
1302     HMI_SEQ_ERROR(req_num, errorDescription(error));
1303     g_app_list.removeRequest(req_num);
1304     this->processNextRequest();
1305 }
1306
1307 void WindowManager::processForRemoteRequest(json_object *data)
1308 {
1309     const char *req          = jh::getStringFromJson(data, "req");
1310     const char *appid        = jh::getStringFromJson(data, "appid");
1311     const char *drawing_name = jh::getStringFromJson(data, "drawing_name");
1312     const char *drawing_area = jh::getStringFromJson(data, "drawing_area");
1313
1314     if (!req || !drawing_name)
1315     {
1316         HMI_ERROR("Parse Error!!");
1317         return;
1318     }
1319
1320     if (this->wmcon.isMasterMode())
1321     {
1322         if (!appid)
1323         {
1324             HMI_ERROR("Parse Error!!");
1325             return;
1326         }
1327
1328         auto reply = [](const char *errmsg) {
1329             if (errmsg != nullptr)
1330             {
1331                 HMI_ERROR(errmsg);
1332                 return;
1333             }
1334         };
1335
1336         if ("activateWindow" == std::string(req))
1337         {
1338             if (!drawing_area)
1339             {
1340                 HMI_ERROR("Parse Error!!");
1341                 return;
1342             }
1343
1344             this->api_activate_surface_for_slave(
1345                 appid, drawing_name, drawing_area, reply);
1346         }
1347         else if ("deactivateWindow" == std::string(req))
1348         {
1349             this->api_deactivate_surface_for_slave(
1350                 appid, drawing_name, reply);
1351         }
1352         else if ("endDraw" == std::string(req))
1353         {
1354             this->api_enddraw(appid, drawing_name);
1355         }
1356     }
1357     else
1358     {
1359         if ("syncDraw" == std::string(req))
1360         {
1361             this->stopTimer();
1362
1363             if (!appid || !drawing_area)
1364             {
1365                 HMI_ERROR("Parse Error!!");
1366                 return;
1367             }
1368
1369             unsigned req_num = g_app_list.currentRequestNumber();
1370             auto client = g_app_list.lookUpClient(appid);
1371
1372             // TODO: application requests by old role,
1373             //       so convert role old to new
1374             const char *c_role = this->convertRoleOldToNew(drawing_name);
1375
1376             // Create action
1377             bool end_draw_finished = false;
1378             WMAction act
1379             {
1380                 req_num,
1381                 client,
1382                 string(c_role),
1383                 string(drawing_area),
1384                 TaskVisible::REMOTE_VISIBLE,
1385                 end_draw_finished,
1386                 TaskCarState::NO_TASK
1387             };
1388
1389             // Set action
1390             WMError ret = g_app_list.setAction(req_num, act);
1391             if (ret != WMError::SUCCESS)
1392             {
1393                 HMI_SEQ_ERROR(req_num, "Setting action is failed");
1394                 return;
1395             }
1396
1397             this->emit_syncdraw(string(drawing_name), string(drawing_area));
1398             this->wmcon.startSyncDrawForRemote(appid);
1399             this->setTimer();
1400         }
1401         else if ("activated" == std::string(req))
1402         {
1403             this->emit_visible(drawing_name);
1404             this->emit_activated(drawing_name);
1405         }
1406         else if ("deactivated" == std::string(req))
1407         {
1408             this->stopTimer();
1409
1410             if (!appid || !drawing_area)
1411             {
1412                 HMI_ERROR("Parse Error!!");
1413                 return;
1414             }
1415
1416             unsigned req_num = g_app_list.currentRequestNumber();
1417             auto client = g_app_list.lookUpClient(appid);
1418
1419             // TODO: application requests by old role,
1420             //       so convert role old to new
1421             const char *c_role = this->convertRoleOldToNew(drawing_name);
1422
1423             // Create action
1424             bool end_draw_finished = true;
1425             WMAction act
1426             {
1427                 req_num,
1428                 client,
1429                 string(c_role),
1430                 "",
1431                 TaskVisible::REMOTE_INVISIBLE,
1432                 end_draw_finished,
1433                 TaskCarState::NO_TASK
1434             };
1435
1436             this->lc->visibilityChange(act);
1437             this->lc->renderLayers();
1438             this->lc->renderLayersRemote();
1439
1440             this->emit_invisible(drawing_name);
1441             this->emit_deactivated(drawing_name);
1442             this->emitScreenUpdated(req_num);
1443
1444             g_app_list.removeRequest(req_num);
1445             this->processNextRequest();
1446         }
1447         else if ("flushDraw" == std::string(req))
1448         {
1449             this->emit_flushdraw(drawing_name);
1450         }
1451     }
1452 }
1453
1454 /*
1455  ******* Private Functions *******
1456  */
1457
1458 void WindowManager::emit_activated(char const *label)
1459 {
1460     this->send_event(kListEventName[Event_Active], label);
1461 }
1462
1463 void WindowManager::emit_deactivated(char const *label)
1464 {
1465     this->send_event(kListEventName[Event_Inactive], label);
1466 }
1467
1468 void WindowManager::emit_syncdraw(char const *label, char const *area, int x, int y, int w, int h)
1469 {
1470     this->send_event(kListEventName[Event_SyncDraw], label, area, x, y, w, h);
1471 }
1472
1473 void WindowManager::emit_syncdraw(const string &role, const string &area)
1474 {
1475     rect rect = this->lc->getAreaSize(area);
1476     this->send_event(kListEventName[Event_SyncDraw],
1477                      role.c_str(), area.c_str(), rect.x, rect.y, rect.w, rect.h);
1478 }
1479
1480 void WindowManager::emit_flushdraw(char const *label)
1481 {
1482     this->send_event(kListEventName[Event_FlushDraw], label);
1483 }
1484
1485 void WindowManager::emit_visible(char const *label, bool is_visible)
1486 {
1487     this->send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], label);
1488 }
1489
1490 void WindowManager::emit_invisible(char const *label)
1491 {
1492     return emit_visible(label, false);
1493 }
1494
1495 void WindowManager::emit_visible(char const *label) { return emit_visible(label, true); }
1496
1497 void WindowManager::emitHeadlampOff()
1498 {
1499     // Send HeadlampOff event for all application
1500     this->send_event(kListEventName[Event_HeadlampOff]);
1501 }
1502
1503 void WindowManager::emitHeadlampOn()
1504 {
1505     // Send HeadlampOn event for all application
1506     this->send_event(kListEventName[Event_HeadlampOn]);
1507 }
1508
1509 void WindowManager::emitParkingBrakeOff()
1510 {
1511     // Send ParkingBrakeOff event for all application
1512     this->send_event(kListEventName[Event_ParkingBrakeOff]);
1513 }
1514
1515 void WindowManager::emitParkingBrakeOn()
1516 {
1517     // Send ParkingBrakeOn event for all application
1518     this->send_event(kListEventName[Event_ParkingBrakeOn]);
1519 }
1520
1521 void WindowManager::emitLightstatusBrakeOff()
1522 {
1523     // Send LightstatusBrakeOff event for all application
1524     this->send_event(kListEventName[Event_LightstatusBrakeOff]);
1525 }
1526
1527 void WindowManager::emitLightstatusBrakeOn()
1528 {
1529     // Send LightstatusBrakeOn event for all application
1530     this->send_event(kListEventName[Event_LightstatusBrakeOn]);
1531 }
1532
1533 void WindowManager::emitCarStop()
1534 {
1535     // Send CarStop event for all application
1536     this->send_event(kListEventName[Event_CarStop]);
1537 }
1538
1539 void WindowManager::emitCarRun()
1540 {
1541     // Send CarRun event for all application
1542     this->send_event(kListEventName[Event_CarRun]);
1543 }
1544
1545 WMError WindowManager::setRequest(const string& appid, const string &role, const string &area,
1546                             Task task, unsigned* req_num)
1547 {
1548     if (!g_app_list.contains(appid))
1549     {
1550         return WMError::NOT_REGISTERED;
1551     }
1552
1553     auto client = g_app_list.lookUpClient(appid);
1554
1555     /*
1556      * Queueing Phase
1557      */
1558     unsigned current = g_app_list.currentRequestNumber();
1559     unsigned requested_num = g_app_list.getRequestNumber(appid);
1560     if (requested_num != 0)
1561     {
1562         HMI_SEQ_INFO(requested_num,
1563             "%s %s %s request is already queued", appid.c_str(), role.c_str(), area.c_str());
1564         return REQ_REJECTED;
1565     }
1566
1567     WMRequest req = WMRequest(appid, role, area, task);
1568     unsigned new_req = g_app_list.addRequest(req);
1569     *req_num = new_req;
1570     g_app_list.reqDump();
1571
1572     HMI_SEQ_DEBUG(current, "%s start sequence with %s, %s", appid.c_str(), role.c_str(), area.c_str());
1573
1574     return WMError::SUCCESS;
1575 }
1576
1577 WMError WindowManager::setRequest(Task task, unsigned* req_num)
1578 {
1579     /*
1580      * Queueing Phase
1581      */
1582     unsigned current = g_app_list.currentRequestNumber();
1583
1584     WMRequest req = WMRequest(task);
1585     unsigned new_req = g_app_list.addRequest(req);
1586     *req_num = new_req;
1587     g_app_list.reqDump();
1588
1589     HMI_SEQ_DEBUG(current, "start sequence for task:%d", task);
1590
1591     return WMError::SUCCESS;
1592 }
1593
1594 WMError WindowManager::setRequestForSlave(const string& appid, const string &role, const string &area,
1595                             Task task, unsigned* req_num)
1596 {
1597     /*
1598      * Queueing Phase
1599      */
1600     unsigned current = g_app_list.currentRequestNumber();
1601     unsigned requested_num = g_app_list.getRequestNumber(appid);
1602     if (requested_num != 0)
1603     {
1604         HMI_SEQ_INFO(requested_num,
1605             "%s %s %s request is already queued", appid.c_str(), role.c_str(), area.c_str());
1606         return REQ_REJECTED;
1607     }
1608
1609     WMRequest req = WMRequest(appid, role, area, task);
1610     unsigned new_req = g_app_list.addRequest(req);
1611     *req_num = new_req;
1612     g_app_list.reqDump();
1613
1614     HMI_SEQ_DEBUG(current, "%s start sequence with %s, %s", appid.c_str(), role.c_str(), area.c_str());
1615
1616     return WMError::SUCCESS;
1617 }
1618
1619 WMError WindowManager::checkPolicy(unsigned req_num)
1620 {
1621     /*
1622     * Check Policy
1623     */
1624     // get current trigger
1625     bool found = false;
1626     WMError ret = WMError::LAYOUT_CHANGE_FAIL;
1627     auto trigger = g_app_list.getRequest(req_num, &found);
1628     if (!found)
1629     {
1630         ret = WMError::NO_ENTRY;
1631         return ret;
1632     }
1633     string req_area = trigger.area;
1634
1635     if (trigger.task == Task::TASK_ALLOCATE)
1636     {
1637         const char *msg = this->check_surface_exist(trigger.role.c_str());
1638
1639         if (msg)
1640         {
1641             HMI_SEQ_ERROR(req_num, msg);
1642             return ret;
1643         }
1644     }
1645
1646     // Input event data to PolicyManager
1647     if (0 > this->pmw.setInputEventData(trigger.task, trigger.role, trigger.area))
1648     {
1649         HMI_SEQ_ERROR(req_num, "Failed to set input event data to PolicyManager");
1650         return ret;
1651     }
1652
1653     // Execute state transition of PolicyManager
1654     if (0 > this->pmw.executeStateTransition())
1655     {
1656         HMI_SEQ_ERROR(req_num, "Failed to execute state transition of PolicyManager");
1657         return ret;
1658     }
1659
1660     ret = WMError::SUCCESS;
1661
1662     g_app_list.reqDump();
1663
1664     return ret;
1665 }
1666
1667 WMError WindowManager::checkPolicyForSlave(unsigned req_num)
1668 {
1669     /*
1670     * Check Policy
1671     */
1672     // get current trigger
1673     bool found = false;
1674     WMError ret = WMError::LAYOUT_CHANGE_FAIL;
1675     auto trigger = g_app_list.getRequest(req_num, &found);
1676     if (!found)
1677     {
1678         ret = WMError::NO_ENTRY;
1679         return ret;
1680     }
1681     string req_area = trigger.area;
1682
1683     // Input event data to PolicyManager
1684     if (0 > this->pmw.setInputEventData(trigger.task, trigger.role, trigger.area))
1685     {
1686         HMI_SEQ_ERROR(req_num, "Failed to set input event data to PolicyManager");
1687         return ret;
1688     }
1689
1690     // Execute state transition of PolicyManager
1691     if (0 > this->pmw.executeStateTransition())
1692     {
1693         HMI_SEQ_ERROR(req_num, "Failed to execute state transition of PolicyManager");
1694         return ret;
1695     }
1696
1697     ret = WMError::SUCCESS;
1698
1699     g_app_list.reqDump();
1700
1701     return ret;
1702 }
1703
1704 WMError WindowManager::startTransition(unsigned req_num)
1705 {
1706     bool sync_draw_happen = false;
1707     bool found = false;
1708     WMError ret = WMError::SUCCESS;
1709     auto actions = g_app_list.getActions(req_num, &found);
1710     if (!found)
1711     {
1712         ret = WMError::NO_ENTRY;
1713         HMI_SEQ_ERROR(req_num,
1714             "Window Manager bug :%s : Action is not set", errorDescription(ret));
1715         return ret;
1716     }
1717
1718     g_app_list.reqDump();
1719     for (const auto &action : actions)
1720     {
1721         // TODO: application requests by old role,
1722         //       so convert role new to old for emitting event
1723         string old_role = this->rolenew2old[action.role];
1724
1725         if (action.visible == TaskVisible::VISIBLE)
1726         {
1727             sync_draw_happen = true;
1728
1729             this->emit_syncdraw(old_role, action.area);
1730             /* TODO: emit event for app not subscriber
1731                if(g_app_list.contains(y.appid))
1732                g_app_list.lookUpClient(y.appid)->emit_syncdraw(y.role, y.area); */
1733         }
1734         else if(action.visible == TaskVisible::REQ_REMOTE_VISIBLE)
1735         {
1736             // If this action is for slave, send to slave
1737             this->wmcon.sendRequest("syncDraw", action.client->appID().c_str(),
1738                                     old_role.c_str(), action.area.c_str());
1739         }
1740         else if (action.car_state != TaskCarState::NO_TASK)
1741         {
1742             this->transitionCarState(action.car_state);
1743         }
1744     }
1745
1746     if (sync_draw_happen)
1747     {
1748         this->setTimer();
1749     }
1750     else
1751     {
1752         // deactivate only, no syncDraw
1753         // Make it deactivate here
1754         for (const auto &x : actions)
1755         {
1756             this->lc->visibilityChange(x);
1757             string old_role = this->rolenew2old[x.role];
1758
1759             if (x.visible == TaskVisible::INVISIBLE)
1760             {
1761                 emit_deactivated(old_role.c_str());
1762             }
1763             else if (x.visible == TaskVisible::REQ_REMOTE_INVISIBLE)
1764             {
1765                 // If this action is for slave, send to slave
1766                 int i_ret = this->wmcon.sendRequest("deactivated", x.client->appID().c_str(),
1767                                                     old_role.c_str(), "");
1768                 if (0 > i_ret)
1769                 {
1770                     ret = WMError::FAIL;
1771                 }
1772             }
1773
1774             /* if (g_app_list.contains(x.appid))
1775             {
1776                 auto client = g_app_list.lookUpClient(x.appid);
1777                 //this->deactivate(client->surfaceID(x.role));
1778             } */
1779         }
1780         this->lc->renderLayers();
1781         this->lc->renderLayersRemote();
1782         ret = WMError::NO_LAYOUT_CHANGE;
1783     }
1784     return ret;
1785 }
1786
1787 void WindowManager::transitionCarState(TaskCarState task)
1788 {
1789     if (TaskCarState::PARKING_BRAKE_OFF == task)
1790     {
1791         this->crr_car_info.parking_brake_stt = false;
1792         this->emitParkingBrakeOff();
1793     }
1794     else if (TaskCarState::PARKING_BRAKE_ON == task)
1795     {
1796         this->crr_car_info.parking_brake_stt = true;
1797         this->emitParkingBrakeOn();
1798     }
1799     else if (TaskCarState::ACCEL_PEDAL_OFF == task)
1800     {
1801         this->crr_car_info.accel_pedal_stt = false;
1802     }
1803     else if (TaskCarState::ACCEL_PEDAL_ON == task)
1804     {
1805         this->crr_car_info.accel_pedal_stt = true;
1806     }
1807     else if (TaskCarState::HEDLAMP_OFF == task)
1808     {
1809         this->crr_car_info.headlamp_stt = false;
1810         this->emitHeadlampOff();
1811     }
1812     else if (TaskCarState::HEDLAMP_ON == task)
1813     {
1814         this->crr_car_info.headlamp_stt = true;
1815         this->emitHeadlampOn();
1816     }
1817     else if (TaskCarState::LIGHTSTATUS_BRAKE_OFF == task)
1818     {
1819         this->crr_car_info.lightstatus_brake_stt = false;
1820         this->emitLightstatusBrakeOff();
1821     }
1822     else if (TaskCarState::LIGHTSTATUS_BRAKE_ON == task)
1823     {
1824         this->crr_car_info.lightstatus_brake_stt = true;
1825         this->emitLightstatusBrakeOn();
1826     }
1827     else if (TaskCarState::CAR_STOP == task)
1828     {
1829         this->crr_car_info.running_stt = false;
1830         this->emitCarStop();
1831     }
1832     else if (TaskCarState::CAR_RUN == task)
1833     {
1834         this->crr_car_info.running_stt = true;
1835         this->emitCarRun();
1836     }
1837 }
1838
1839 WMError WindowManager::doEndDraw(unsigned req_num)
1840 {
1841     // get actions
1842     bool found;
1843     auto actions = g_app_list.getActions(req_num, &found);
1844     WMError ret = WMError::SUCCESS;
1845     if (!found)
1846     {
1847         ret = WMError::NO_ENTRY;
1848         return ret;
1849     }
1850
1851     HMI_SEQ_INFO(req_num, "do endDraw");
1852
1853     // layout change and make it visible
1854     for (const auto &act : actions)
1855     {
1856         if(act.visible != TaskVisible::NO_CHANGE)
1857         {
1858             // layout change
1859             ret = this->lc->layoutChange(act);
1860             if(ret != WMError::SUCCESS)
1861             {
1862                 HMI_SEQ_WARNING(req_num,
1863                     "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
1864                 return ret;
1865             }
1866             ret = this->lc->visibilityChange(act);
1867
1868             // Emit active/deactive event
1869             string old_role = this->rolenew2old[act.role];
1870             if(act.visible == TaskVisible::VISIBLE)
1871             {
1872                 emit_visible(old_role.c_str());
1873                 emit_activated(old_role.c_str());
1874             }
1875             else if(act.visible == TaskVisible::REQ_REMOTE_VISIBLE)
1876             {
1877                 // If this action is for slave, send to slave
1878                 int i_ret = this->wmcon.sendRequest("activated", "", old_role.c_str(), "");
1879                 if (0 > i_ret)
1880                 {
1881                     ret = WMError::FAIL;
1882                 }
1883             }
1884             else if(act.visible == TaskVisible::REQ_REMOTE_INVISIBLE)
1885             {
1886                 // If this action is for slave, send to slave
1887                 int i_ret = this->wmcon.sendRequest("deactivated", "", old_role.c_str(), "");
1888                 if (0 > i_ret)
1889                 {
1890                     ret = WMError::FAIL;
1891                 }
1892             }
1893             else if((act.visible == TaskVisible::REMOTE_VISIBLE) ||
1894                     (act.visible == TaskVisible::REMOTE_INVISIBLE))
1895             {
1896                 // nop because emit active/deactive by event from remote
1897             }
1898             else
1899             {
1900                 emit_invisible(old_role.c_str());
1901                 emit_deactivated(old_role.c_str());
1902             }
1903
1904             if (ret != WMError::SUCCESS)
1905             {
1906                 HMI_SEQ_WARNING(req_num,
1907                     "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
1908                 return ret;
1909             }
1910             HMI_SEQ_DEBUG(req_num, "visible %s", act.role.c_str());
1911         }
1912     }
1913     this->lc->renderLayers();
1914     this->lc->renderLayersRemote();
1915
1916     HMI_SEQ_INFO(req_num, "emit flushDraw");
1917
1918     for(const auto &act_flush : actions)
1919     {
1920         // TODO: application requests by old role,
1921         //       so convert role new to old for emitting event
1922         string old_role = this->rolenew2old[act_flush.role];
1923
1924         if(act_flush.visible == TaskVisible::VISIBLE)
1925         {
1926             this->emit_flushdraw(old_role.c_str());
1927         }
1928         else if(act_flush.visible == TaskVisible::REQ_REMOTE_VISIBLE)
1929         {
1930             // If this action is for slave, send to slave
1931             this->wmcon.sendRequest("flushDraw", "", old_role.c_str(), "");
1932         }
1933     }
1934
1935     return ret;
1936 }
1937
1938 void WindowManager::emitScreenUpdated(unsigned req_num)
1939 {
1940     // Get visible apps
1941     HMI_SEQ_DEBUG(req_num, "emit screen updated");
1942     bool found = false;
1943     auto actions = g_app_list.getActions(req_num, &found);
1944
1945     HMI_DEBUG("@@@@@");
1946     // create json object
1947     json_object *j = json_object_new_object();
1948     json_object *jarray = json_object_new_array();
1949
1950     for(const auto& action: actions)
1951     {
1952         if((action.visible == TaskVisible::VISIBLE) ||
1953            (action.visible == TaskVisible::REMOTE_VISIBLE))
1954         {
1955             json_object_array_add(jarray, json_object_new_string(action.client->appID().c_str()));
1956         }
1957     }
1958     json_object_object_add(j, kKeyIds, jarray);
1959     HMI_SEQ_INFO(req_num, "Visible app: %s", json_object_get_string(j));
1960
1961     int ret = afb_event_push(
1962         this->map_afb_event[kListEventName[Event_ScreenUpdated]], j);
1963     if (ret != 0)
1964     {
1965         HMI_DEBUG("afb_event_push failed: %m");
1966     }
1967 }
1968
1969 void WindowManager::setTimer()
1970 {
1971     struct timespec ts;
1972     if (clock_gettime(CLOCK_BOOTTIME, &ts) != 0) {
1973         HMI_ERROR("Could't set time (clock_gettime() returns with error");
1974         return;
1975     }
1976
1977     HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "Timer set activate");
1978     if (g_timer_ev_src == nullptr)
1979     {
1980         // firsttime set into sd_event
1981         int ret = sd_event_add_time(afb_daemon_get_event_loop(), &g_timer_ev_src,
1982             CLOCK_BOOTTIME, (uint64_t)(ts.tv_sec + kTimeOut) * 1000000ULL, 1, processTimerHandler, this);
1983         if (ret < 0)
1984         {
1985             HMI_ERROR("Could't set timer");
1986         }
1987     }
1988     else
1989     {
1990         // update timer limitation after second time
1991         sd_event_source_set_time(g_timer_ev_src, (uint64_t)(ts.tv_sec + kTimeOut) * 1000000ULL);
1992         sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_ONESHOT);
1993     }
1994 }
1995
1996 void WindowManager::stopTimer()
1997 {
1998     unsigned req_num = g_app_list.currentRequestNumber();
1999     HMI_SEQ_DEBUG(req_num, "Timer stop");
2000     int rc = sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_OFF);
2001     if (rc < 0)
2002     {
2003         HMI_SEQ_ERROR(req_num, "Timer stop failed");
2004     }
2005 }
2006
2007 void WindowManager::processNextRequest()
2008 {
2009     g_app_list.next();
2010     g_app_list.reqDump();
2011     unsigned req_num = g_app_list.currentRequestNumber();
2012     if (g_app_list.haveRequest())
2013     {
2014         HMI_SEQ_DEBUG(req_num, "Process next request");
2015         WMError rc = checkPolicy(req_num);
2016         if (rc != WMError::SUCCESS)
2017         {
2018             HMI_SEQ_ERROR(req_num, errorDescription(rc));
2019         }
2020     }
2021     else
2022     {
2023         HMI_SEQ_DEBUG(req_num, "Nothing Request. Waiting Request");
2024     }
2025 }
2026
2027 const char* WindowManager::convertRoleOldToNew(char const *old_role)
2028 {
2029     const char *new_role = nullptr;
2030
2031     for (auto const &on : this->roleold2new)
2032     {
2033         std::regex regex = std::regex(on.first);
2034         if (std::regex_match(old_role, regex))
2035         {
2036             // role is old. So convert to new.
2037             new_role = on.second.c_str();
2038             break;
2039         }
2040     }
2041
2042     if (nullptr == new_role)
2043     {
2044         // role is new or fallback.
2045         new_role = old_role;
2046     }
2047
2048     HMI_DEBUG("old:%s -> new:%s", old_role, new_role);
2049
2050     return new_role;
2051 }
2052
2053 int WindowManager::loadOldRolesConfigFile()
2054 {
2055     // Get afm application installed dir
2056     char const *afm_app_install_dir = getenv("AFM_APP_INSTALL_DIR");
2057     HMI_DEBUG("afm_app_install_dir:%s", afm_app_install_dir);
2058
2059     string file_name;
2060     if (!afm_app_install_dir)
2061     {
2062         HMI_ERROR("AFM_APP_INSTALL_DIR is not defined");
2063     }
2064     else
2065     {
2066         file_name = string(afm_app_install_dir) + string(kPathOldRolesConfigFile);
2067     }
2068
2069     // Load old_rolea config file
2070     json_object* json_obj;
2071     int ret = jh::inputJsonFilie(file_name.c_str(), &json_obj);
2072     if (0 > ret)
2073     {
2074         HMI_ERROR("Could not open %s, so use default old_roles information", kPathOldRolesConfigFile);
2075         json_obj = json_tokener_parse(kDefaultOldRolesConfig);
2076     }
2077     HMI_DEBUG("json_obj dump:%s", json_object_get_string(json_obj));
2078
2079     // Perse apps
2080     json_object* json_cfg;
2081     if (!json_object_object_get_ex(json_obj, "old_roles", &json_cfg))
2082     {
2083         HMI_ERROR("Parse Error!!");
2084         return -1;
2085     }
2086
2087     int len = json_object_array_length(json_cfg);
2088     HMI_DEBUG("json_cfg len:%d", len);
2089     HMI_DEBUG("json_cfg dump:%s", json_object_get_string(json_cfg));
2090
2091     for (int i=0; i<len; i++)
2092     {
2093         json_object* json_tmp = json_object_array_get_idx(json_cfg, i);
2094
2095         const char* old_role = jh::getStringFromJson(json_tmp, "name");
2096         if (nullptr == old_role)
2097         {
2098             HMI_ERROR("Parse Error!!");
2099             return -1;
2100         }
2101
2102         const char* new_role = jh::getStringFromJson(json_tmp, "new");
2103         if (nullptr == new_role)
2104         {
2105             HMI_ERROR("Parse Error!!");
2106             return -1;
2107         }
2108
2109         this->roleold2new[old_role] = string(new_role);
2110     }
2111
2112     // Check
2113     for(auto itr = this->roleold2new.begin();
2114       itr != this->roleold2new.end(); ++itr)
2115     {
2116         HMI_DEBUG(">>> role old:%s new:%s",
2117                   itr->first.c_str(), itr->second.c_str());
2118     }
2119
2120     // Release json_object
2121     json_object_put(json_obj);
2122
2123     return 0;
2124 }
2125
2126 Task WindowManager::convertCanSignalToCarStateTask(const char *signal_name)
2127 {
2128     wm::LowCanClient *lcc = &(this->lcc);
2129     Task task = Task::TASK_INVALID;
2130
2131     // If car info is updated, set car state change event
2132     if (strstr(signal_name, lcc->kSignalName[lcc->SignalNoParkingBrake]))
2133     {
2134         HMI_DEBUG("Parking Brake state is changed");
2135
2136         if (lcc->getCurrentParkingBrakeState())
2137         {
2138             task = wm::Task::TASK_PARKING_BRAKE_ON;
2139         }
2140         else
2141         {
2142             task = wm::Task::TASK_PARKING_BRAKE_OFF;
2143         }
2144     }
2145     else if (strstr(signal_name, lcc->kSignalName[lcc->SignalNoAccelPedalPos]))
2146     {
2147         // Update accel pedal position
2148         this->crr_car_info.accel_pedal_pos = lcc->getCurrentAccelPedalPosition();
2149
2150         if (lcc->isChangedAccelPedalState())
2151         {
2152             HMI_DEBUG("Accelerator Pedal state is changed");
2153
2154             if (lcc->getCurrentAccelPedalState())
2155             {
2156                 task = wm::Task::TASK_ACCEL_PEDAL_ON;
2157             }
2158             else
2159             {
2160                 task = wm::Task::TASK_ACCEL_PEDAL_OFF;
2161             }
2162         }
2163     }
2164     else if (strstr(signal_name, lcc->kSignalName[lcc->SignalNoHeadlame]))
2165     {
2166         HMI_DEBUG("Headlamp state is changed");
2167
2168         if (lcc->getCurrentHeadlampState())
2169         {
2170             task = wm::Task::TASK_HEDLAMP_ON;
2171         }
2172         else
2173         {
2174             task = wm::Task::TASK_HEDLAMP_OFF;
2175         }
2176     }
2177     else if (strstr(signal_name, lcc->kSignalName[lcc->SignalNoLightstatusBrake]))
2178     {
2179         HMI_DEBUG("Lightstatus Brake state is changed");
2180
2181         if (lcc->getCurrentLightstatusBrakeState())
2182         {
2183             task = wm::Task::TASK_LIGHTSTATUS_BRAKE_ON;
2184         }
2185         else
2186         {
2187             task = wm::Task::TASK_LIGHTSTATUS_BRAKE_OFF;
2188         }
2189     }
2190     return task;
2191 }
2192
2193 void WindowManager::inputCarStateTask(Task task)
2194 {
2195     unsigned req_num = 0;
2196     WMError ret = WMError::UNKNOWN;
2197
2198     ret = this->setRequest(task, &req_num);
2199
2200     if(ret != WMError::SUCCESS)
2201     {
2202         HMI_ERROR(errorDescription(ret));
2203         return;
2204     }
2205
2206     if (req_num != g_app_list.currentRequestNumber())
2207     {
2208         // Add request, then invoked after the previous task is finished
2209         HMI_SEQ_DEBUG(req_num, "request is accepted");
2210         return;
2211     }
2212
2213     /*
2214      * Do allocate tasks
2215      */
2216     ret = this->checkPolicy(req_num);
2217
2218     if (ret != WMError::SUCCESS)
2219     {
2220         //this->emit_error()
2221         HMI_SEQ_ERROR(req_num, errorDescription(ret));
2222         g_app_list.removeRequest(req_num);
2223         this->processNextRequest();
2224     }
2225 }
2226
2227 const char *WindowManager::check_surface_exist(const char *drawing_name)
2228 {
2229     auto const &surface_id = this->id_alloc.lookup(string(drawing_name));
2230     if (!surface_id)
2231     {
2232         return "Surface does not exist";
2233     }
2234
2235     /* if (!this->controller->surface_exists(*surface_id))
2236     {
2237         return "Surface does not exist in controller!";
2238     } */
2239
2240     /* auto layer_id = this->layers.get_layer_id(*surface_id);
2241
2242     if (!layer_id)
2243     {
2244         return "Surface is not on any layer!";
2245     } */
2246
2247     HMI_DEBUG("surface %d is detected", *surface_id);
2248     return nullptr;
2249 }
2250
2251 const char* WindowManager::kDefaultOldRolesConfig = "{ \
2252     \"old_roles\": [ \
2253         { \
2254             \"name\": \"HomeScreen\", \
2255             \"new\": \"homescreen\" \
2256         }, \
2257         { \
2258             \"name\": \"Music\", \
2259             \"new\": \"music\" \
2260         }, \
2261         { \
2262             \"name\": \"MediaPlayer\", \
2263             \"new\": \"music\" \
2264         }, \
2265         { \
2266             \"name\": \"Video\", \
2267             \"new\": \"video\" \
2268         }, \
2269         { \
2270             \"name\": \"VideoPlayer\", \
2271             \"new\": \"video\" \
2272         }, \
2273         { \
2274             \"name\": \"WebBrowser\", \
2275             \"new\": \"browser\" \
2276         }, \
2277         { \
2278             \"name\": \"Radio\", \
2279             \"new\": \"radio\" \
2280         }, \
2281         { \
2282             \"name\": \"Phone\", \
2283             \"new\": \"phone\" \
2284         }, \
2285         { \
2286             \"name\": \"Navigation\", \
2287             \"new\": \"map\" \
2288         }, \
2289         { \
2290             \"name\": \"HVAC\", \
2291             \"new\": \"hvac\" \
2292         }, \
2293         { \
2294             \"name\": \"Settings\", \
2295             \"new\": \"settings\" \
2296         }, \
2297         { \
2298             \"name\": \"Dashboard\", \
2299             \"new\": \"dashboard\" \
2300         }, \
2301         { \
2302             \"name\": \"POI\", \
2303             \"new\": \"poi\" \
2304         }, \
2305         { \
2306             \"name\": \"Mixer\", \
2307             \"new\": \"mixer\" \
2308         }, \
2309         { \
2310             \"name\": \"Restriction\", \
2311             \"new\": \"restriction\" \
2312         }, \
2313         { \
2314             \"name\": \"^OnScreen.*\", \
2315             \"new\": \"on_screen\" \
2316         } \
2317     ] \
2318 }";
2319
2320 } // namespace wm