POI: AGL LifeCycle Management
[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
20 #include "window_manager.hpp"
21 #include "json_helper.hpp"
22 #include "applist.hpp"
23
24 extern "C"
25 {
26 #include <systemd/sd-event.h>
27 }
28
29 using std::string;
30 using std::vector;
31
32 namespace wm
33 {
34
35 static const uint64_t kTimeOut = 3ULL; /* 3s */
36
37 /* DrawingArea name used by "{layout}.{area}" */
38 const char kNameLayoutNormal[] = "normal";
39 const char kNameLayoutSplit[]  = "split";
40 const char kNameAreaFull[]     = "full";
41 const char kNameAreaMain[]     = "main";
42 const char kNameAreaSub[]      = "sub";
43
44 /* Key for json obejct */
45 const char kKeyDrawingName[] = "drawing_name";
46 const char kKeyDrawingArea[] = "drawing_area";
47 const char kKeyDrawingRect[] = "drawing_rect";
48 const char kKeyX[]           = "x";
49 const char kKeyY[]           = "y";
50 const char kKeyWidth[]       = "width";
51 const char kKeyHeight[]      = "height";
52 const char kKeyWidthPixel[]  = "width_pixel";
53 const char kKeyHeightPixel[] = "height_pixel";
54 const char kKeyWidthMm[]     = "width_mm";
55 const char kKeyHeightMm[]    = "height_mm";
56 const char kKeyScale[]       = "scale";
57 const char kKeyIds[]         = "ids";
58
59 static const vector<string> kListEventName{
60         "active",
61         "inactive",
62         "visible",
63         "invisible",
64         "syncDraw",
65         "flushDraw",
66         "screenUpdated",
67         "error"};
68
69 static sd_event_source *g_timer_ev_src = nullptr;
70 static AppList g_app_list;
71 static WindowManager *g_context;
72
73 namespace
74 {
75
76 static int processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata)
77 {
78     HMI_NOTICE("Time out occurs because the client replys endDraw slow, so revert the request");
79     reinterpret_cast<wm::WindowManager *>(userdata)->timerHandler();
80     return 0;
81 }
82
83 static void onStateTransitioned(vector<WMAction> actions)
84 {
85     g_context->startTransitionWrapper(actions);
86 }
87
88 static void onError()
89 {
90     g_context->processError(WMError::LAYOUT_CHANGE_FAIL);
91 }
92 } // namespace
93
94 /**
95  * WindowManager Impl
96  */
97 WindowManager::WindowManager()
98     : id_alloc{}
99 {
100     const char *path = getenv("AFM_APP_INSTALL_DIR");
101     if (!path)
102     {
103         HMI_ERROR("AFM_APP_INSTALL_DIR is not defined");
104     }
105     string root = path;
106
107     this->lc = std::make_shared<LayerControl>(root);
108
109     HMI_DEBUG("Layer Controller initialized");
110 }
111
112 int WindowManager::init()
113 {
114     LayerControlCallbacks lmcb;
115     lmcb.surfaceCreated = [&](unsigned pid, unsigned surface){
116         this->surface_created(surface);
117         };
118     lmcb.surfaceDestroyed = [&](unsigned surface){
119         this->surface_removed(surface);
120     };
121
122     if(this->lc->init(lmcb) != WMError::SUCCESS)
123     {
124         return -1;
125     }
126
127     // Store my context for calling callback from PolicyManager
128     g_context = this;
129
130     // Initialize PMWrapper
131     this->pmw.initialize();
132
133     // Register callback to PolicyManager
134     this->pmw.registerCallback(onStateTransitioned, onError);
135
136     // Make afb event
137     for (int i = Event_Val_Min; i <= Event_Val_Max; i++)
138     {
139         map_afb_event[kListEventName[i]] = afb_api_make_event(afbBindingV3root, kListEventName[i].c_str());
140     }
141
142     const struct rect css_bg = this->lc->getAreaSize("fullscreen");
143     Screen screen = this->lc->getScreenInfo();
144     rectangle dp_bg(screen.width(), screen.height());
145
146     dp_bg.set_aspect(static_cast<double>(css_bg.w) / css_bg.h);
147     dp_bg.fit(screen.width(), screen.height());
148     dp_bg.center(screen.width(), screen.height());
149     HMI_DEBUG("SCALING: CSS BG(%dx%d) -> DDP %dx%d,(%dx%d)",
150               css_bg.w, css_bg.h, dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
151
152     double scale = static_cast<double>(dp_bg.height()) / css_bg.h;
153     this->lc->setupArea(dp_bg, scale);
154
155     return 0;
156 }
157
158 result<int> WindowManager::api_request_surface(char const *appid, char const *drawing_name)
159 {
160     string str_id = appid;
161     string role = drawing_name;
162     unsigned lid = 0;
163
164     if(!g_app_list.contains(str_id))
165     {
166         lid = this->lc->getNewLayerID(role);
167         if (lid == 0)
168         {
169             // register drawing_name as fallback and make it displayed.
170             lid = this->lc->getNewLayerID(string("fallback"));
171             HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
172             if (lid == 0)
173             {
174                 return Err<int>("Designated role does not match any role, fallback is disabled");
175             }
176         }
177         this->lc->createNewLayer(lid);
178         // add client into the db
179         g_app_list.addClient(str_id, lid, role);
180     }
181
182     // generate surface ID for ivi-shell application
183     auto rname = this->id_alloc.lookup(role);
184     if (!rname)
185     {
186         // name does not exist yet, allocate surface id...
187         auto id = int(this->id_alloc.generate_id(role));
188         this->tmp_surface2app[id] = {str_id, lid};
189
190         // POI: AGL LifeCycle Management
191         this->amgr.states[str_id] = lcm::CREATED;
192         this->amgr.emit_activity_status_changed(str_id.c_str(),
193                                                 this->amgr.states_s[lcm::CREATED]);
194
195         return Ok<int>(id);
196     }
197
198     // Check currently registered drawing names if it is already there.
199     return Err<int>("Surface already present");
200 }
201
202 char const *WindowManager::api_request_surface(char const *appid, char const *drawing_name,
203                                      char const *ivi_id)
204 {
205     string str_id   = appid;
206     string role = drawing_name;
207
208     unsigned sid = std::stol(ivi_id);
209     HMI_DEBUG("This API(requestSurfaceXDG) is for XDG Application using runXDG");
210     /*
211      * IVI-shell doesn't send surface_size event via ivi-wm protocol
212      * if the application is using XDG surface.
213      * So WM has to set surface size with original size here
214      */
215     WMError ret = this->lc->setXDGSurfaceOriginSize(sid);
216     if(ret != SUCCESS)
217     {
218         HMI_ERROR("%s", errorDescription(ret));
219         HMI_WARNING("The main user of this API is runXDG");
220         return "fail";
221     }
222
223     if(!g_app_list.contains(str_id))
224     {
225         unsigned l_id = this->lc->getNewLayerID(role);
226         if (l_id == 0)
227         {
228             // register drawing_name as fallback and make it displayed.
229             l_id = this->lc->getNewLayerID("fallback");
230             HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
231             if (l_id == 0)
232             {
233                 return "Designated role does not match any role, fallback is disabled";
234             }
235         }
236         this->lc->createNewLayer(l_id);
237         // add client into the db
238         g_app_list.addClient(str_id, l_id, role);
239     }
240
241     auto rname = this->id_alloc.lookup(role);
242
243     if (rname)
244     {
245         return "Surface already present";
246     }
247
248     // register pair drawing_name and ivi_id
249     this->id_alloc.register_name_id(role, sid);
250
251     auto client = g_app_list.lookUpClient(str_id);
252     client->addSurface(sid);
253
254     // POI: AGL LifeCycle Management
255     this->amgr.states[str_id] = lcm::CREATED;
256     this->amgr.emit_activity_status_changed(str_id.c_str(),
257                                             this->amgr.states_s[lcm::CREATED]);
258
259     return nullptr;
260 }
261
262 void WindowManager::api_activate_window(char const *appid, char const *drawing_name,
263                                char const *drawing_area, const reply_func &reply)
264 {
265     string id = appid;
266     string role = drawing_name;
267     string area = drawing_area;
268
269     if(!g_app_list.contains(id))
270     {
271         reply("app doesn't request 'requestSurface' or 'setRole' yet");
272         return;
273     }
274     auto client = g_app_list.lookUpClient(id);
275
276     Task task = Task::TASK_ALLOCATE;
277     unsigned req_num = 0;
278     WMError ret = WMError::UNKNOWN;
279
280     ret = this->setRequest(id, role, area, task, &req_num);
281
282     if(ret != WMError::SUCCESS)
283     {
284         HMI_ERROR(errorDescription(ret));
285         reply("Failed to set request");
286         return;
287     }
288
289     reply(nullptr);
290     if (req_num != g_app_list.currentRequestNumber())
291     {
292         // Add request, then invoked after the previous task is finished
293         HMI_SEQ_DEBUG(req_num, "request is accepted");
294         return;
295     }
296
297      // Do allocate tasks
298
299     ret = this->checkPolicy(req_num);
300
301     if (ret != WMError::SUCCESS)
302     {
303         //this->emit_error()
304         HMI_SEQ_ERROR(req_num, errorDescription(ret));
305         g_app_list.removeRequest(req_num);
306         this->processNextRequest();
307     } else {
308       // POI: AGL LifeCycle Management
309       if (this->amgr.states[id] == lcm::CREATED) {
310         this->amgr.states[id] = lcm::STARTED;
311         this->amgr.emit_activity_status_changed(id.c_str(),
312                                                 this->amgr.states_s[lcm::STARTED]);
313       }
314     }
315 }
316
317 void WindowManager::api_deactivate_window(char const *appid, char const *drawing_name,
318                                  const reply_func &reply)
319 {
320     // Check Phase
321     string id = appid;
322     string role = drawing_name;
323     string area = ""; //drawing_area;
324     Task task = Task::TASK_RELEASE;
325     unsigned req_num = 0;
326     WMError ret = WMError::UNKNOWN;
327
328     ret = this->setRequest(id, role, area, task, &req_num);
329
330     if (ret != WMError::SUCCESS)
331     {
332         HMI_ERROR(errorDescription(ret));
333         reply("Failed to set request");
334         return;
335     }
336
337     reply(nullptr);
338     if (req_num != g_app_list.currentRequestNumber())
339     {
340         // Add request, then invoked after the previous task is finished
341         HMI_SEQ_DEBUG(req_num, "request is accepted");
342         return;
343     }
344
345     // Do allocate tasks
346     ret = this->checkPolicy(req_num);
347
348     if (ret != WMError::SUCCESS)
349     {
350         //this->emit_error()
351         HMI_SEQ_ERROR(req_num, errorDescription(ret));
352         g_app_list.removeRequest(req_num);
353         this->processNextRequest();
354     } else {
355       // POI: AGL LifeCycle Management
356       int state = this->amgr.states[id];
357       if (state == lcm::STARTED || state == lcm::BACKGROUND) {
358         this->amgr.states[id] = lcm::STOPPED;
359         this->amgr.emit_activity_status_changed(id.c_str(),
360                                                 this->amgr.states_s[lcm::STOPPED]);
361       }
362     }
363 }
364
365 void WindowManager::api_enddraw(char const *appid, char const *drawing_name)
366 {
367     string id = appid;
368     string role = drawing_name;
369     unsigned current_req = g_app_list.currentRequestNumber();
370     bool result = g_app_list.setEndDrawFinished(current_req, id, role);
371
372     if (!result)
373     {
374         HMI_ERROR("%s is not in transition state", id.c_str());
375         return;
376     }
377
378     if (g_app_list.endDrawFullfilled(current_req))
379     {
380         // do task for endDraw
381         this->stopTimer();
382         WMError ret = this->doEndDraw(current_req);
383
384         if(ret != WMError::SUCCESS)
385         {
386             //this->emit_error();
387
388             // Undo state of PolicyManager
389             this->pmw.undoState();
390             this->lc->undoUpdate();
391         }
392         this->emitScreenUpdated(current_req);
393         HMI_SEQ_INFO(current_req, "Finish request status: %s", errorDescription(ret));
394
395         g_app_list.removeRequest(current_req);
396
397         this->processNextRequest();
398     }
399     else
400     {
401         HMI_SEQ_INFO(current_req, "Wait other App call endDraw");
402         return;
403     }
404 }
405
406 int WindowManager::api_subscribe(afb_req_t req, int event_id)
407 {
408     afb_event_t event = this->map_afb_event[kListEventName[event_id]];
409     return afb_req_subscribe(req, event);
410 }
411
412 result<json_object *> WindowManager::api_get_display_info()
413 {
414     Screen screen = this->lc->getScreenInfo();
415
416     json_object *object = json_object_new_object();
417     json_object_object_add(object, kKeyWidthPixel, json_object_new_int(screen.width()));
418     json_object_object_add(object, kKeyHeightPixel, json_object_new_int(screen.height()));
419     // TODO: set size
420     json_object_object_add(object, kKeyWidthMm, json_object_new_int(0));
421     json_object_object_add(object, kKeyHeightMm, json_object_new_int(0));
422     json_object_object_add(object, kKeyScale, json_object_new_double(this->lc->scale()));
423
424     return Ok<json_object *>(object);
425 }
426
427 result<json_object *> WindowManager::api_get_area_info(char const *drawing_name)
428 {
429     HMI_DEBUG("called");
430
431     string role = drawing_name;
432
433     // Check drawing name, surface/layer id
434     auto const &surface_id = this->id_alloc.lookup(role);
435     if (!surface_id)
436     {
437         return Err<json_object *>("Surface does not exist");
438     }
439
440     // Set area rectangle
441     struct rect area_info = this->area_info[*surface_id];
442     json_object *object = json_object_new_object();
443     json_object_object_add(object, kKeyX, json_object_new_int(area_info.x));
444     json_object_object_add(object, kKeyY, json_object_new_int(area_info.y));
445     json_object_object_add(object, kKeyWidth, json_object_new_int(area_info.w));
446     json_object_object_add(object, kKeyHeight, json_object_new_int(area_info.h));
447
448     return Ok<json_object *>(object);
449 }
450
451 void WindowManager::send_event(const string& evname, const string& role)
452 {
453     json_object *j = json_object_new_object();
454     json_object_object_add(j, kKeyDrawingName, json_object_new_string(role.c_str()));
455
456     int ret = afb_event_push(this->map_afb_event[evname], j);
457     if (ret != 0)
458     {
459         HMI_DEBUG("afb_event_push failed: %m");
460     }
461 }
462
463 void WindowManager::send_event(const string& evname, const string& role, const string& area,
464                      int x, int y, int w, int h)
465 {
466     json_object *j_rect = json_object_new_object();
467     json_object_object_add(j_rect, kKeyX, json_object_new_int(x));
468     json_object_object_add(j_rect, kKeyY, json_object_new_int(y));
469     json_object_object_add(j_rect, kKeyWidth, json_object_new_int(w));
470     json_object_object_add(j_rect, kKeyHeight, json_object_new_int(h));
471
472     json_object *j = json_object_new_object();
473     json_object_object_add(j, kKeyDrawingName, json_object_new_string(role.c_str()));
474     json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area.c_str()));
475     json_object_object_add(j, kKeyDrawingRect, j_rect);
476
477     int ret = afb_event_push(this->map_afb_event[evname], j);
478     if (ret != 0)
479     {
480         HMI_DEBUG("afb_event_push failed: %m");
481     }
482 }
483
484 /**
485  * proxied events
486  */
487 void WindowManager::surface_created(unsigned surface_id)
488 {
489     // requestSurface
490     if(this->tmp_surface2app.count(surface_id) != 0)
491     {
492         string appid = this->tmp_surface2app[surface_id].appid;
493         auto client = g_app_list.lookUpClient(appid);
494         if(client != nullptr)
495         {
496             WMError ret = client->addSurface(surface_id);
497             HMI_INFO("Add surface %d to \"%s\"", surface_id, appid.c_str());
498             if(ret != WMError::SUCCESS)
499             {
500                 HMI_ERROR("Failed to add surface to client %s", client->appID().c_str());
501             }
502         }
503         this->tmp_surface2app.erase(surface_id);
504     }
505 }
506
507 void WindowManager::surface_removed(unsigned surface_id)
508 {
509     HMI_DEBUG("Delete surface_id %u", surface_id);
510     this->id_alloc.remove_id(surface_id);
511     g_app_list.removeSurface(surface_id);
512 }
513
514 void WindowManager::removeClient(const string &appid)
515 {
516     HMI_DEBUG("Remove clinet %s from list", appid.c_str());
517     auto client = g_app_list.lookUpClient(appid);
518     this->lc->appTerminated(client);
519     g_app_list.removeClient(appid);
520     // POI: AGL LifeCycle Management
521     if (this->amgr.states[appid] != lcm::DESTROYED) {
522       this->amgr.states[appid] = lcm::DESTROYED;
523       this->amgr.emit_activity_status_changed(appid.c_str(),
524                                               this->amgr.states_s[lcm::DESTROYED]);
525     }
526 }
527
528 void WindowManager::exceptionProcessForTransition()
529 {
530     unsigned req_num = g_app_list.currentRequestNumber();
531     HMI_SEQ_NOTICE(req_num, "Process exception handling for request. Remove current request %d", req_num);
532     g_app_list.removeRequest(req_num);
533     HMI_SEQ_NOTICE(g_app_list.currentRequestNumber(), "Process next request if exists");
534     this->processNextRequest();
535 }
536
537 void WindowManager::timerHandler()
538 {
539     unsigned req_num = g_app_list.currentRequestNumber();
540     HMI_SEQ_DEBUG(req_num, "Timer expired remove Request");
541     g_app_list.reqDump();
542     g_app_list.removeRequest(req_num);
543     this->processNextRequest();
544 }
545
546 void WindowManager::startTransitionWrapper(vector<WMAction> &actions)
547 {
548     WMError ret;
549     unsigned req_num = g_app_list.currentRequestNumber();
550
551     if (actions.empty())
552     {
553         if (g_app_list.haveRequest())
554         {
555             HMI_SEQ_DEBUG(req_num, "There is no WMAction for this request");
556             goto proc_remove_request;
557         }
558         else
559         {
560             HMI_SEQ_DEBUG(req_num, "There is no request");
561             return;
562         }
563     }
564
565     for (auto &act : actions)
566     {
567         if ("" != act.role)
568         {
569             bool found;
570             auto const &surface_id = this->id_alloc.lookup(act.role);
571             if(surface_id == nullopt)
572             {
573                 goto proc_remove_request;
574             }
575             string appid = g_app_list.getAppID(*surface_id, &found);
576             if (!found)
577             {
578                 if (TaskVisible::INVISIBLE == act.visible)
579                 {
580                     // App is killed, so do not set this action
581                     continue;
582                 }
583                 else
584                 {
585                     HMI_SEQ_ERROR(req_num, "appid which is visible is not found");
586                     ret = WMError::FAIL;
587                     goto error;
588                 }
589             }
590             auto client = g_app_list.lookUpClient(appid);
591             act.req_num = req_num;
592             act.client = client;
593         }
594
595         ret = g_app_list.setAction(req_num, act);
596         if (ret != WMError::SUCCESS)
597         {
598             HMI_SEQ_ERROR(req_num, "Setting action is failed");
599             goto error;
600         }
601     }
602
603     HMI_SEQ_DEBUG(req_num, "Start transition.");
604     ret = this->startTransition(req_num);
605     if (ret != WMError::SUCCESS)
606     {
607         if (ret == WMError::NO_LAYOUT_CHANGE)
608         {
609             goto proc_remove_request;
610         }
611         else
612         {
613             HMI_SEQ_ERROR(req_num, "Transition state is failed");
614             goto error;
615         }
616     }
617
618     return;
619
620 error:
621     //this->emit_error()
622     HMI_SEQ_ERROR(req_num, errorDescription(ret));
623     this->pmw.undoState();
624
625 proc_remove_request:
626     g_app_list.removeRequest(req_num);
627     this->processNextRequest();
628 }
629
630 void WindowManager::processError(WMError error)
631 {
632     unsigned req_num = g_app_list.currentRequestNumber();
633
634     //this->emit_error()
635     HMI_SEQ_ERROR(req_num, errorDescription(error));
636     g_app_list.removeRequest(req_num);
637     this->processNextRequest();
638 }
639
640 /*
641  ******* Private Functions *******
642  */
643
644 void WindowManager::emit_activated(const string& role)
645 {
646     this->send_event(kListEventName[Event_Active], role);
647 }
648
649 void WindowManager::emit_deactivated(const string& role)
650 {
651     this->send_event(kListEventName[Event_Inactive], role);
652 }
653
654 void WindowManager::emit_syncdraw(const string& role, char const *area, int x, int y, int w, int h)
655 {
656     this->send_event(kListEventName[Event_SyncDraw], role, area, x, y, w, h);
657 }
658
659 void WindowManager::emit_syncdraw(const string &role, const string &area)
660 {
661     struct rect rect = this->lc->getAreaSize(area);
662     this->send_event(kListEventName[Event_SyncDraw],
663         role, area, rect.x, rect.y, rect.w, rect.h);
664 }
665
666 void WindowManager::emit_flushdraw(const string& role)
667 {
668     this->send_event(kListEventName[Event_FlushDraw], role);
669 }
670
671 void WindowManager::emit_visible(const string& role, bool is_visible)
672 {
673     this->send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], role);
674 }
675
676 void WindowManager::emit_invisible(const string& role)
677 {
678     return emit_visible(role, false);
679 }
680
681 void WindowManager::emit_visible(const string& role) { return emit_visible(role, true); }
682
683 WMError WindowManager::setRequest(const string& appid, const string &role, const string &area,
684                             Task task, unsigned* req_num)
685 {
686     if (!g_app_list.contains(appid))
687     {
688         return WMError::NOT_REGISTERED;
689     }
690
691     auto client = g_app_list.lookUpClient(appid);
692
693     /*
694      * Queueing Phase
695      */
696     unsigned current = g_app_list.currentRequestNumber();
697     unsigned requested_num = g_app_list.getRequestNumber(appid);
698     if (requested_num != 0)
699     {
700         HMI_SEQ_INFO(requested_num,
701             "%s %s %s request is already queued", appid.c_str(), role.c_str(), area.c_str());
702         return REQ_REJECTED;
703     }
704
705     WMRequest req = WMRequest(appid, role, area, task);
706     unsigned new_req = g_app_list.addRequest(req);
707     *req_num = new_req;
708     g_app_list.reqDump();
709
710     HMI_SEQ_DEBUG(current, "%s start sequence with %s, %s", appid.c_str(), role.c_str(), area.c_str());
711
712     return WMError::SUCCESS;
713 }
714
715 WMError WindowManager::checkPolicy(unsigned req_num)
716 {
717     /*
718     * Check Policy
719     */
720     // get current trigger
721     bool found = false;
722     WMError ret = WMError::LAYOUT_CHANGE_FAIL;
723     auto trigger = g_app_list.getRequest(req_num, &found);
724     if (!found)
725     {
726         ret = WMError::NO_ENTRY;
727         return ret;
728     }
729     string req_area = trigger.area;
730
731     // Input event data to PolicyManager
732     if (0 > this->pmw.setInputEventData(trigger.task, trigger.role, trigger.area))
733     {
734         HMI_SEQ_ERROR(req_num, "Failed to set input event data to PolicyManager");
735         return ret;
736     }
737
738     // Execute state transition of PolicyManager
739     if (0 > this->pmw.executeStateTransition())
740     {
741         HMI_SEQ_ERROR(req_num, "Failed to execute state transition of PolicyManager");
742         return ret;
743     }
744
745     ret = WMError::SUCCESS;
746
747     g_app_list.reqDump();
748
749     return ret;
750 }
751
752 WMError WindowManager::startTransition(unsigned req_num)
753 {
754     bool sync_draw_happen = false;
755     bool found = false;
756     WMError ret = WMError::SUCCESS;
757     auto actions = g_app_list.getActions(req_num, &found);
758     if (!found)
759     {
760         ret = WMError::NO_ENTRY;
761         HMI_SEQ_ERROR(req_num,
762             "Window Manager bug :%s : Action is not set", errorDescription(ret));
763         return ret;
764     }
765
766     g_app_list.reqDump();
767     for (const auto &action : actions)
768     {
769         if (action.visible == TaskVisible::VISIBLE)
770         {
771             sync_draw_happen = true;
772             this->emit_syncdraw(action.role, action.area);
773             /* TODO: emit event for app not subscriber
774             if(g_app_list.contains(y.appid))
775                 g_app_list.lookUpClient(y.appid)->emit_syncdraw(y.role, y.area); */
776         }
777     }
778
779     if (sync_draw_happen)
780     {
781         this->setTimer();
782     }
783     else
784     {
785         // deactivate only, no syncDraw
786         // Make it deactivate here
787         for (const auto &x : actions)
788         {
789             this->lc->visibilityChange(x);
790             emit_deactivated(x.role);
791             /* if (g_app_list.contains(x.client->appID()))
792             {
793                 auto client = g_app_list.lookUpClient(x.client->appID());
794                 this->deactivate(client->surfaceID(x.role));
795             } */
796         }
797         this->lc->renderLayers();
798         ret = WMError::NO_LAYOUT_CHANGE;
799     }
800     return ret;
801 }
802
803 WMError WindowManager::doEndDraw(unsigned req_num)
804 {
805     // get actions
806     bool found;
807     auto actions = g_app_list.getActions(req_num, &found);
808     WMError ret = WMError::SUCCESS;
809     if (!found)
810     {
811         ret = WMError::NO_ENTRY;
812         return ret;
813     }
814
815     HMI_SEQ_INFO(req_num, "do endDraw");
816
817     // layout change and make it visible
818     for (const auto &act : actions)
819     {
820         if(act.visible != TaskVisible::NO_CHANGE)
821         {
822             // layout change
823             ret = this->lc->layoutChange(act);
824             if(ret != WMError::SUCCESS)
825             {
826                 HMI_SEQ_WARNING(req_num,
827                     "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
828                 return ret;
829             }
830             ret = this->lc->visibilityChange(act);
831
832             if(act.visible == VISIBLE)
833             {
834                 emit_visible(act.role);
835                 emit_activated(act.role);
836             }
837             else
838             {
839                 emit_invisible(act.role);
840                 emit_deactivated(act.role);
841             }
842
843             if (ret != WMError::SUCCESS)
844             {
845                 HMI_SEQ_WARNING(req_num,
846                     "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
847                 return ret;
848             }
849             HMI_SEQ_DEBUG(req_num, "visible %s", act.role.c_str());
850         }
851     }
852     this->lc->renderLayers();
853
854     HMI_SEQ_INFO(req_num, "emit flushDraw");
855
856     for(const auto &act_flush : actions)
857     {
858         if(act_flush.visible == TaskVisible::VISIBLE)
859         {
860             this->emit_flushdraw(act_flush.role);
861         }
862     }
863
864     return ret;
865 }
866
867 void WindowManager::emitScreenUpdated(unsigned req_num)
868 {
869     // Get visible apps
870     HMI_SEQ_DEBUG(req_num, "emit screen updated");
871     bool found = false;
872     auto actions = g_app_list.getActions(req_num, &found);
873     if (!found)
874     {
875         HMI_SEQ_ERROR(req_num,
876                       "Window Manager bug :%s : Action is not set",
877                       errorDescription(WMError::NO_ENTRY));
878         return;
879     }
880
881     // create json object
882     json_object *j = json_object_new_object();
883     json_object *jarray = json_object_new_array();
884
885     for(const auto& action: actions)
886     {
887         std::string appid = action.client->appID();
888
889         if(action.visible != TaskVisible::INVISIBLE)
890         {
891             json_object_array_add(jarray, json_object_new_string(appid.c_str()));
892             // POI: AGL LifeCycle Management
893             if (this->amgr.states[appid] != lcm::FOREGROUND) {
894               this->amgr.states[appid] = lcm::FOREGROUND;
895               this->amgr.emit_activity_status_changed(appid.c_str(), this->amgr.states_s[lcm::FOREGROUND]);
896             }
897         } else {
898             // POI: AGL LifeCycle Management
899             if (this->amgr.states[appid] != lcm::BACKGROUND) {
900                 this->amgr.states[appid] = lcm::BACKGROUND;
901                 this->amgr.emit_activity_status_changed(appid.c_str(), this->amgr.states_s[lcm::BACKGROUND]);
902             }
903         }
904     }
905     json_object_object_add(j, kKeyIds, jarray);
906     HMI_SEQ_INFO(req_num, "Visible app: %s", json_object_get_string(j));
907
908     int ret = afb_event_push(
909         this->map_afb_event[kListEventName[Event_ScreenUpdated]], j);
910     if (ret != 0)
911     {
912         HMI_DEBUG("afb_event_push failed: %m");
913     }
914 }
915
916 void WindowManager::setTimer()
917 {
918     struct timespec ts;
919     if (clock_gettime(CLOCK_BOOTTIME, &ts) != 0) {
920         HMI_ERROR("Could't set time (clock_gettime() returns with error");
921         return;
922     }
923
924     HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "Timer set activate");
925     if (g_timer_ev_src == nullptr)
926     {
927         // firsttime set into sd_event
928         int ret = sd_event_add_time(afb_api_get_event_loop(afbBindingV3root), &g_timer_ev_src,
929             CLOCK_BOOTTIME, (uint64_t)(ts.tv_sec + kTimeOut) * 1000000ULL, 1, processTimerHandler, this);
930         if (ret < 0)
931         {
932             HMI_ERROR("Could't set timer");
933         }
934     }
935     else
936     {
937         // update timer limitation after second time
938         sd_event_source_set_time(g_timer_ev_src, (uint64_t)(ts.tv_sec + kTimeOut) * 1000000ULL);
939         sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_ONESHOT);
940     }
941 }
942
943 void WindowManager::stopTimer()
944 {
945     unsigned req_num = g_app_list.currentRequestNumber();
946     HMI_SEQ_DEBUG(req_num, "Timer stop");
947     int rc = sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_OFF);
948     if (rc < 0)
949     {
950         HMI_SEQ_ERROR(req_num, "Timer stop failed");
951     }
952 }
953
954 void WindowManager::processNextRequest()
955 {
956     g_app_list.next();
957     g_app_list.reqDump();
958     unsigned req_num = g_app_list.currentRequestNumber();
959     if (g_app_list.haveRequest())
960     {
961         HMI_SEQ_DEBUG(req_num, "Process next request");
962         WMError rc = checkPolicy(req_num);
963         if (rc != WMError::SUCCESS)
964         {
965             HMI_SEQ_ERROR(req_num, errorDescription(rc));
966         }
967     }
968     else
969     {
970         HMI_SEQ_DEBUG(req_num, "Nothing Request. Waiting Request");
971     }
972 }
973
974 } // namespace wm
975
976 namespace lcm
977 {
978
979 ActivityManager::ActivityManager (void)
980     : states_s { "NOTEXISTS",
981                  "CREATED",
982                  "DESTROYED",
983                  "STARTED",
984                  "STOPPED",
985                  "FOREGROUND",
986                  "BACKGROUND" }
987 {
988   ;
989 }
990
991 void ActivityManager::api_register_activity_observer (afb_req_t req, void* &lcm_ctx)
992 {
993   //std::string observer = afb_req_get_application_id(req);
994   observer* obs = static_cast<observer *>(lcm_ctx);
995
996   json_object *j_data = afb_req_json(req);
997   json_object *j_target;
998   if (!json_object_object_get_ex(j_data, LCM_TARGET, &j_target)) {
999     afb_req_fail(req, "failed", "Need char const* argument target");
1000     return;
1001   }
1002   std::string target(json_object_get_string(j_target));
1003
1004   if (obs == nullptr) {
1005     // New observer
1006     afb_event_t event = afb_daemon_make_event(LCM_EVENT_STATUS_CHANGED);
1007     //afb_event_t event = afb_daemon_make_event(LCM_EVENT_STATUS_CHANGED);
1008     obs = new observer({
1009         event,
1010         std::bitset<NUM_STATUS>(ACTIVITY_FILTER_ALL_SET)
1011       });
1012
1013     if (afb_req_subscribe(req, event) != 0) {
1014       afb_req_fail(req, "failed", "cannot subscribe event");
1015       return;
1016     }
1017     HMI_DEBUG("observer(%p, target=\"%s\") is created.[NEW]", obs, target.c_str());
1018
1019     lcm_ctx = static_cast<observer *>(obs);
1020   }
1021
1022   if (this->map_observers.count(target)) {
1023     // already registered
1024     HMI_DEBUG("observer(%p, target=\"%s\") is already exist", obs, target.c_str());
1025     std::vector<observer*> obs_v = this->map_observers[target];
1026     auto result = std::find(obs_v.begin(), obs_v.end(), obs);
1027     if (result != obs_v.end()) {
1028       HMI_DEBUG("observer(%p, target=\"%s\") is already registered", obs, target.c_str());
1029       return;
1030     }
1031   }
1032   HMI_DEBUG("observer(%p, target=\"%s\") is registered", obs, target.c_str());
1033   (this->map_observers[target]).push_back(obs);
1034 }
1035
1036 void ActivityManager::remove_observer (observer *obs, std::vector<observer*>& obs_v)
1037 {
1038   auto obs_itr = obs_v.begin();
1039   while (obs_itr != obs_v.end()) {
1040     if (*obs_itr == obs) {
1041       obs_itr = obs_v.erase(obs_itr);
1042     } else {
1043       obs_itr++;
1044     }
1045   }
1046 }
1047
1048 void ActivityManager::api_unregister_activity_observer (afb_req_t req, void* &lcm_ctx)
1049 {
1050   observer *obs = static_cast<observer *>(lcm_ctx);
1051
1052   json_object *j_data = afb_req_json(req);
1053   json_object *j_target;
1054
1055   if (!json_object_object_get_ex(j_data, LCM_TARGET, &j_target)) {
1056     afb_req_fail(req, "failed", "Need char const* argument target");
1057     return;
1058   }
1059   std::string target(json_object_get_string(j_target));
1060
1061   HMI_DEBUG("observer(%p->\"%s\") is unregistered.", obs, target.c_str());
1062
1063   if (this->map_observers.count(target) != 0) {
1064     remove_observer(obs, this->map_observers[target]);
1065   }
1066 }
1067
1068 void ActivityManager::lcm_clear_context (void* &lcm_ctx)
1069 {
1070   observer *obs = static_cast<observer *>(lcm_ctx);
1071
1072   for (auto itr = this->map_observers.begin(); itr != this->map_observers.end(); itr++) {
1073     remove_observer(obs, itr->second);
1074   }
1075
1076   HMI_DEBUG("observer(%p) is removed.", obs);
1077
1078   delete obs;
1079 }
1080
1081 wm::result<json_object *> ActivityManager::api_get_activity_status (const char *appid)
1082 {
1083   std::string id = appid;
1084   int st = NOTEXISTS;
1085
1086   if (this->states.count(id)) {
1087     st = this->states[id];
1088
1089     if (st < 0 || st >= NUM_STATUS) {
1090       HMI_ERROR("Illegal lifecycle state (%d) of [%s]", st, appid);
1091       return wm::Err<json_object *>("Illegal lifecycle state");
1092     }
1093   }
1094
1095   const char * state = this->states_s[st];
1096
1097   json_object *object = json_object_new_object();
1098   json_object_object_add(object, LCM_API, json_object_new_string(LCM_API_GET_ACTIVITY_STATUS));
1099   json_object_object_add(object, LCM_TARGET, json_object_new_string(appid));
1100   json_object_object_add(object, LCM_STATE, json_object_new_string(state));
1101
1102   return wm::Ok<json_object *>(object);
1103 }
1104
1105 void ActivityManager::emit_activity_status_changed (const char* appid, const char* state)
1106 {
1107   // POI: AGL LifeCycle Management
1108   // E.g. statusChanged(CREATED->STARTED)
1109   HMI_DEBUG("emit_activity_status_changed(%s, %s)", appid, state);
1110
1111   std::string id = appid;
1112
1113   if (this->map_observers.count(id)) {
1114     std::vector<observer*>& obs_v = this->map_observers[id];
1115
1116     for (auto itr = obs_v.begin(); itr != obs_v.end(); ++itr) {
1117       auto obs = *itr;
1118       afb_event_t event = obs->event;
1119       if (afb_event_is_valid(event)) {
1120         json_object *data = json_object_new_object();
1121         json_object_object_add(data, LCM_STATE, json_object_new_string(state));
1122         json_object_object_add(data, LCM_TARGET, json_object_new_string(appid));
1123
1124         HMI_DEBUG("send Event_statusChanged(%s, %s)", appid, state);
1125
1126         afb_event_push(event, json_object_get(data));
1127         json_object_put(data);
1128       } else {
1129         HMI_ERROR("afb_event is not valid");
1130       }
1131     }
1132   }
1133 }
1134
1135 } // namespace lcm