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