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