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