2 * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
3 * Copyright (c) 2019 Konsulko Group
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
21 #include "window_manager.hpp"
22 #include "json_helper.hpp"
23 #include "applist.hpp"
27 #include <systemd/sd-event.h>
32 using std::unordered_map;
37 static const uint64_t kTimeOut = 3ULL; /* 3s */
39 /* DrawingArea name used by "{layout}.{area}" */
40 const char kNameLayoutNormal[] = "normal";
41 const char kNameLayoutSplit[] = "split";
42 const char kNameAreaFull[] = "full";
43 const char kNameAreaMain[] = "main";
44 const char kNameAreaSub[] = "sub";
46 /* Key for json obejct */
47 const char kKeyDrawingName[] = "drawing_name";
48 const char kKeyDrawingArea[] = "drawing_area";
49 const char kKeyDrawingRect[] = "drawing_rect";
50 const char kKeyX[] = "x";
51 const char kKeyY[] = "y";
52 const char kKeyWidth[] = "width";
53 const char kKeyHeight[] = "height";
54 const char kKeyWidthPixel[] = "width_pixel";
55 const char kKeyHeightPixel[] = "height_pixel";
56 const char kKeyWidthMm[] = "width_mm";
57 const char kKeyHeightMm[] = "height_mm";
58 const char kKeyScale[] = "scale";
59 const char kKeyIds[] = "ids";
61 static const vector<string> kListEventName{
71 static sd_event_source *g_timer_ev_src = nullptr;
72 static AppList g_app_list;
73 static WindowManager *g_context;
74 static vector<string> white_list_area_size_change = {
75 "homescreen", "settings"
81 static int processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata)
83 HMI_NOTICE("Time out occurs because the client replys endDraw slow, so revert the request");
84 reinterpret_cast<wm::WindowManager *>(userdata)->timerHandler();
88 static void onStateTransitioned(vector<WMAction> actions)
90 g_context->startTransitionWrapper(actions);
95 g_context->processError(WMError::LAYOUT_CHANGE_FAIL);
102 WindowManager::WindowManager()
105 const char *path = getenv("AFM_APP_INSTALL_DIR");
108 HMI_ERROR("AFM_APP_INSTALL_DIR is not defined");
112 this->lc = std::make_shared<LayerControl>(root);
114 HMI_DEBUG("Layer Controller initialized");
117 int WindowManager::init()
119 LayerControlCallbacks lmcb;
120 lmcb.surfaceCreated = [&](unsigned pid, unsigned surface){
121 this->surface_created(surface);
123 lmcb.surfaceDestroyed = [&](unsigned surface){
124 this->surface_removed(surface);
127 if(this->lc->init(lmcb) != WMError::SUCCESS)
132 // Store my context for calling callback from PolicyManager
135 // Initialize PMWrapper
136 this->pmw.initialize();
138 // Register callback to PolicyManager
139 this->pmw.registerCallback(onStateTransitioned, onError);
141 // Make afb event for subscriber
142 for (int i = Event_ScreenUpdated; i < Event_Error; i++)
144 map_afb_event[kListEventName[i]] = afb_api_make_event(afbBindingV3root, kListEventName[i].c_str());
147 const struct rect css_bg = this->lc->getAreaSize("fullscreen");
148 Screen screen = this->lc->getScreenInfo();
149 rectangle dp_bg(screen.width(), screen.height());
151 dp_bg.set_aspect(static_cast<double>(css_bg.w) / css_bg.h);
152 dp_bg.fit(screen.width(), screen.height());
153 dp_bg.center(screen.width(), screen.height());
154 HMI_DEBUG("SCALING: CSS BG(%dx%d) -> DDP %dx%d,(%dx%d)",
155 css_bg.w, css_bg.h, dp_bg.left(), dp_bg.top(), dp_bg.width(), dp_bg.height());
157 double scale = static_cast<double>(dp_bg.height()) / css_bg.h;
158 this->lc->setupArea(dp_bg, scale);
163 result<int> WindowManager::api_request_surface(char const *appid, char const *drawing_name)
165 string str_id = appid;
166 string role = drawing_name;
169 if(!g_app_list.contains(str_id))
171 lid = this->generateLayerForClient(role);
174 return Err<int>("Designated role does not match any role, fallback is disabled");
176 // add client into the db
177 g_app_list.addClient(str_id, lid, role);
181 // This case occurs when an client calls "subscribe" before request_surface.
182 // Then application doesn't have layer and role yet.
183 auto client = g_app_list.lookUpClient(str_id);
184 if(client->layerID() == 0)
186 client->setLayerID(this->generateLayerForClient(role));
188 client->setRole(role);
191 // generate surface ID for ivi-shell application
192 auto rname = this->id_alloc.lookup(role);
195 // name does not exist yet, allocate surface id...
196 auto id = int(this->id_alloc.generate_id(role));
197 this->tmp_surface2app[id] = {str_id, lid};
199 auto client = g_app_list.lookUpClient(str_id);
200 client->registerSurface(id);
205 // Check currently registered drawing names if it is already there.
206 return Err<int>("Surface already present");
209 char const *WindowManager::api_request_surface(char const *appid, char const *drawing_name,
212 string str_id = appid;
213 string role = drawing_name;
215 unsigned sid = std::stol(ivi_id);
216 HMI_DEBUG("This API(requestSurfaceXDG) is for XDG Application using runXDG");
218 * IVI-shell doesn't send surface_size event via ivi-wm protocol
219 * if the application is using XDG surface.
220 * So WM has to set surface size with original size here
222 WMError ret = this->lc->setXDGSurfaceOriginSize(sid);
225 HMI_ERROR("%s", errorDescription(ret));
226 HMI_WARNING("The main user of this API is runXDG");
230 if(!g_app_list.contains(str_id))
232 unsigned l_id = this->generateLayerForClient(role);
235 return "Designated role does not match any role, fallback is disabled";
237 // add client into the db
238 g_app_list.addClient(str_id, l_id, role);
242 // This case occurs when an client calls "subscribe" before request_surface.
243 // Then application doesn't have layer and role yet.
244 auto client = g_app_list.lookUpClient(str_id);
245 if(client->layerID() == 0)
247 client->setLayerID(this->generateLayerForClient(role));
249 client->setRole(role);
252 auto rname = this->id_alloc.lookup(role);
256 return "Surface already present";
259 // register pair drawing_name and ivi_id
260 this->id_alloc.register_name_id(role, sid);
262 auto client = g_app_list.lookUpClient(str_id);
263 client->addSurface(sid);
268 void WindowManager::api_activate_window(char const *appid, char const *drawing_name,
269 char const *drawing_area, const reply_func &reply)
272 string role = drawing_name;
273 string area = drawing_area;
275 if(!g_app_list.contains(id))
277 reply("app doesn't request 'requestSurface' or 'setRole' yet");
280 auto client = g_app_list.lookUpClient(id);
282 Task task = Task::TASK_ALLOCATE;
283 unsigned req_num = 0;
284 WMError ret = WMError::UNKNOWN;
286 ret = this->setRequest(id, role, area, task, &req_num);
288 if(ret != WMError::SUCCESS)
290 HMI_ERROR(errorDescription(ret));
291 reply("Failed to set request");
296 if (req_num != g_app_list.currentRequestNumber())
298 // Add request, then invoked after the previous task is finished
299 HMI_SEQ_DEBUG(req_num, "request is accepted");
304 ret = this->checkPolicy(req_num);
306 if (ret != WMError::SUCCESS)
309 HMI_SEQ_ERROR(req_num, errorDescription(ret));
310 g_app_list.removeRequest(req_num);
311 this->processNextRequest();
315 void WindowManager::api_deactivate_window(char const *appid, char const *drawing_name,
316 const reply_func &reply)
320 string role = drawing_name;
321 string area = ""; //drawing_area;
322 Task task = Task::TASK_RELEASE;
323 unsigned req_num = 0;
324 WMError ret = WMError::UNKNOWN;
326 ret = this->setRequest(id, role, area, task, &req_num);
328 if (ret != WMError::SUCCESS)
330 HMI_ERROR(errorDescription(ret));
331 reply("Failed to set request");
336 if (req_num != g_app_list.currentRequestNumber())
338 // Add request, then invoked after the previous task is finished
339 HMI_SEQ_DEBUG(req_num, "request is accepted");
344 ret = this->checkPolicy(req_num);
346 if (ret != WMError::SUCCESS)
349 HMI_SEQ_ERROR(req_num, errorDescription(ret));
350 g_app_list.removeRequest(req_num);
351 this->processNextRequest();
355 void WindowManager::api_enddraw(char const *appid, char const *drawing_name)
358 string role = drawing_name;
359 unsigned current_req = g_app_list.currentRequestNumber();
360 bool result = g_app_list.setEndDrawFinished(current_req, id, role);
364 HMI_ERROR("%s is not in transition state", id.c_str());
368 if (g_app_list.endDrawFullfilled(current_req))
370 // do task for endDraw
372 WMError ret = this->doEndDraw(current_req);
374 if(ret != WMError::SUCCESS)
376 //this->emit_error();
378 // Undo state of PolicyManager
379 this->pmw.undoState();
380 this->lc->undoUpdate();
382 this->emitScreenUpdated(current_req);
383 HMI_SEQ_INFO(current_req, "Finish request status: %s", errorDescription(ret));
385 g_app_list.removeRequest(current_req);
387 this->processNextRequest();
391 HMI_SEQ_INFO(current_req, "Wait other App call endDraw");
396 json_object* WindowManager::api_get_area_list()
398 json_object* ret = json_object_new_object();
399 json_object* jarray = json_object_new_array();
400 unordered_map<string, struct rect> area2size = this->lc->getAreaList();
401 for(const auto& area : area2size)
403 json_object* j = json_object_new_object();
404 json_object_object_add(j, "name", json_object_new_string(area.first.c_str()));
405 json_object* jrect = json_object_new_object();
406 json_object_object_add(jrect, "x", json_object_new_int(area.second.x));
407 json_object_object_add(jrect, "y", json_object_new_int(area.second.y));
408 json_object_object_add(jrect, "w", json_object_new_int(area.second.w));
409 json_object_object_add(jrect, "h", json_object_new_int(area.second.h));
410 json_object_object_add(j, "rect", jrect);
411 json_object_array_add(jarray, j);
413 json_object_object_add(ret, "areas", jarray);
414 HMI_DEBUG("area_list: %s", json_object_get_string(ret));
418 void WindowManager::api_change_area_size(ChangeAreaReq &areas)
422 auto client = g_app_list.lookUpClient(areas.appname);
424 if(client == nullptr)
426 HMI_ERROR("Call register your role with setRole or requestSurface");
429 if(std::find(white_list_area_size_change.begin(),
430 white_list_area_size_change.end(), client->role()) == white_list_area_size_change.end())
432 HMI_ERROR("Application %s which has the role %s is not allowed to change area size", client->appID().c_str(), client->role().c_str());
437 ret = this->lc->updateAreaList(areas);
438 if(ret != WMError::SUCCESS)
440 HMI_ERROR("%d : %s", ret, errorDescription(ret));
443 ret = this->lc->getUpdateAreaList(&areas);
445 if(ret != WMError::SUCCESS)
447 HMI_ERROR("%d : %s", ret, errorDescription(ret));
454 ret = this->setRequest(client->appID(), client->role(), "-", Task::TASK_CHANGE_AREA, &req_num); // area is null
455 if(ret != WMError::SUCCESS)
457 HMI_SEQ_ERROR(req_num, "%d : %s", ret, errorDescription(ret));
460 for(const auto &update: areas.update_app2area)
463 auto client = g_app_list.lookUpClient(update.first);
464 if(client == nullptr)
466 HMI_SEQ_ERROR(req_num, "%s : %s", update.first.c_str(), errorDescription(ret));
467 g_app_list.removeRequest(req_num);
468 this->processNextRequest();
471 ret = g_app_list.setAction(req_num, client, client->role(), update.second, TaskVisible::VISIBLE);
472 if(ret != WMError::SUCCESS)
474 HMI_SEQ_ERROR(req_num, "Failed to set request");
478 HMI_SEQ_INFO(req_num, "Area change request");
479 g_app_list.reqDump();
481 // Request change size to applications
482 for(const auto &action : g_app_list.getActions(req_num, &found))
484 struct rect r = this->lc->getAreaSize(action.area);
485 action.client->emitSyncDraw(action.area, r);
489 bool WindowManager::api_subscribe(afb_req_t req, EventType event_id)
492 char* appid = afb_req_get_application_id(req);
493 if(event_id < Event_Val_Min || event_id > Event_Val_Max)
495 HMI_ERROR("not defined in Window Manager", event_id);
499 HMI_INFO("%s subscribe %s : %d", appid, kListEventName[event_id].c_str(), event_id);
500 if(event_id == Event_ScreenUpdated)
502 // Event_ScreenUpdated should be emitted to subscriber
503 afb_event_t event = this->map_afb_event[kListEventName[event_id]];
504 int rc = afb_req_subscribe(req, event);
513 if(!g_app_list.contains(id))
515 g_app_list.addClient(id);
517 ret = g_app_list.lookUpClient(id)->subscribe(req, kListEventName[event_id]);
521 HMI_ERROR("appid is not set");
527 result<json_object *> WindowManager::api_get_display_info()
529 Screen screen = this->lc->getScreenInfo();
531 json_object *object = json_object_new_object();
532 json_object_object_add(object, kKeyWidthPixel, json_object_new_int(screen.width()));
533 json_object_object_add(object, kKeyHeightPixel, json_object_new_int(screen.height()));
535 json_object_object_add(object, kKeyWidthMm, json_object_new_int(0));
536 json_object_object_add(object, kKeyHeightMm, json_object_new_int(0));
537 json_object_object_add(object, kKeyScale, json_object_new_double(this->lc->scale()));
539 return Ok<json_object *>(object);
542 result<json_object *> WindowManager::api_get_area_info(char const *drawing_name)
546 string role = drawing_name;
548 // Check drawing name, surface/layer id
549 auto const &surface_id = this->id_alloc.lookup(role);
552 return Err<json_object *>("Surface does not exist");
555 // Set area rectangle
556 struct rect area_info = this->area_info[*surface_id];
557 json_object *object = json_object_new_object();
558 json_object_object_add(object, kKeyX, json_object_new_int(area_info.x));
559 json_object_object_add(object, kKeyY, json_object_new_int(area_info.y));
560 json_object_object_add(object, kKeyWidth, json_object_new_int(area_info.w));
561 json_object_object_add(object, kKeyHeight, json_object_new_int(area_info.h));
563 return Ok<json_object *>(object);
569 void WindowManager::surface_created(unsigned surface_id)
572 if(this->tmp_surface2app.count(surface_id) != 0)
574 string appid = this->tmp_surface2app[surface_id].appid;
575 auto client = g_app_list.lookUpClient(appid);
576 if(client != nullptr)
578 WMError ret = client->addSurface(surface_id);
579 HMI_INFO("Add surface %d to \"%s\"", surface_id, appid.c_str());
580 if(ret != WMError::SUCCESS)
582 HMI_ERROR("Failed to add surface to client %s", client->appID().c_str());
585 this->tmp_surface2app.erase(surface_id);
589 void WindowManager::surface_removed(unsigned surface_id)
591 HMI_DEBUG("Delete surface_id %u", surface_id);
592 this->id_alloc.remove_id(surface_id);
593 g_app_list.removeSurface(surface_id);
596 void WindowManager::removeClient(const string &appid)
598 HMI_DEBUG("Remove clinet %s from list", appid.c_str());
599 auto client = g_app_list.lookUpClient(appid);
600 this->lc->appTerminated(client);
601 g_app_list.removeClient(appid);
604 void WindowManager::exceptionProcessForTransition()
606 unsigned req_num = g_app_list.currentRequestNumber();
607 HMI_SEQ_NOTICE(req_num, "Process exception handling for request. Remove current request %d", req_num);
608 g_app_list.removeRequest(req_num);
609 HMI_SEQ_NOTICE(g_app_list.currentRequestNumber(), "Process next request if exists");
610 this->processNextRequest();
613 void WindowManager::timerHandler()
615 unsigned req_num = g_app_list.currentRequestNumber();
616 HMI_SEQ_DEBUG(req_num, "Timer expired remove Request");
617 g_app_list.reqDump();
618 g_app_list.removeRequest(req_num);
619 this->processNextRequest();
622 void WindowManager::startTransitionWrapper(vector<WMAction> &actions)
625 unsigned req_num = g_app_list.currentRequestNumber();
629 if (g_app_list.haveRequest())
631 HMI_SEQ_DEBUG(req_num, "There is no WMAction for this request");
632 goto proc_remove_request;
636 HMI_SEQ_DEBUG(req_num, "There is no request");
641 for (auto &act : actions)
646 auto const &surface_id = this->id_alloc.lookup(act.role);
647 if(surface_id == nullopt)
649 goto proc_remove_request;
651 string appid = g_app_list.getAppID(*surface_id, &found);
654 if (TaskVisible::INVISIBLE == act.visible)
656 // App is killed, so do not set this action
661 HMI_SEQ_ERROR(req_num, "appid which is visible is not found");
666 auto client = g_app_list.lookUpClient(appid);
667 act.req_num = req_num;
671 ret = g_app_list.setAction(req_num, act);
672 if (ret != WMError::SUCCESS)
674 HMI_SEQ_ERROR(req_num, "Setting action is failed");
679 HMI_SEQ_DEBUG(req_num, "Start transition.");
680 ret = this->startTransition(req_num);
681 if (ret != WMError::SUCCESS)
683 if (ret == WMError::NO_LAYOUT_CHANGE)
685 goto proc_remove_request;
689 HMI_SEQ_ERROR(req_num, "Transition state is failed");
698 HMI_SEQ_ERROR(req_num, errorDescription(ret));
699 this->pmw.undoState();
702 g_app_list.removeRequest(req_num);
703 this->processNextRequest();
706 void WindowManager::processError(WMError error)
708 unsigned req_num = g_app_list.currentRequestNumber();
711 HMI_SEQ_ERROR(req_num, errorDescription(error));
712 g_app_list.removeRequest(req_num);
713 this->processNextRequest();
716 unsigned WindowManager::generateLayerForClient(const string& role)
719 unsigned lid = this->lc->getNewLayerID(role, &l_name);
722 // register drawing_name as fallback and make it displayed.
723 lid = this->lc->getNewLayerID(string("fallback"));
724 HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role.c_str());
731 // TODO: remote layer name is fixed
732 this->lc->createNewLayer(lid, ("Remote" == l_name));
734 // add client into the db
738 WMError WindowManager::setRequest(const string& appid, const string &role, const string &area,
739 Task task, unsigned* req_num)
741 if (!g_app_list.contains(appid))
743 return WMError::NOT_REGISTERED;
746 auto client = g_app_list.lookUpClient(appid);
751 unsigned current = g_app_list.currentRequestNumber();
752 unsigned requested_num = g_app_list.getRequestNumber(appid);
753 if (requested_num != 0)
755 HMI_SEQ_INFO(requested_num,
756 "%s %s %s request is already queued", appid.c_str(), role.c_str(), area.c_str());
760 WMRequest req = WMRequest(appid, role, area, task);
761 unsigned new_req = g_app_list.addRequest(req);
763 g_app_list.reqDump();
765 HMI_SEQ_DEBUG(current, "%s start sequence with %s, %s", appid.c_str(), role.c_str(), area.c_str());
767 return WMError::SUCCESS;
770 WMError WindowManager::checkPolicy(unsigned req_num)
775 // get current trigger
777 WMError ret = WMError::LAYOUT_CHANGE_FAIL;
778 auto trigger = g_app_list.getRequest(req_num, &found);
781 ret = WMError::NO_ENTRY;
784 string req_area = trigger.area;
786 // Input event data to PolicyManager
787 if (0 > this->pmw.setInputEventData(trigger.task, trigger.role, trigger.area))
789 HMI_SEQ_ERROR(req_num, "Failed to set input event data to PolicyManager");
793 // Execute state transition of PolicyManager
794 if (0 > this->pmw.executeStateTransition())
796 HMI_SEQ_ERROR(req_num, "Failed to execute state transition of PolicyManager");
800 ret = WMError::SUCCESS;
802 g_app_list.reqDump();
807 WMError WindowManager::startTransition(unsigned req_num)
809 bool sync_draw_happen = false;
811 WMError ret = WMError::SUCCESS;
812 auto actions = g_app_list.getActions(req_num, &found);
815 ret = WMError::NO_ENTRY;
816 HMI_SEQ_ERROR(req_num,
817 "Window Manager bug :%s : Action is not set", errorDescription(ret));
821 g_app_list.reqDump();
822 for (const auto &action : actions)
824 if (action.visible == TaskVisible::VISIBLE)
826 sync_draw_happen = true;
827 struct rect r = this->lc->getAreaSize(action.area);
828 action.client->emitSyncDraw(action.area, r);
832 if (sync_draw_happen)
838 // deactivate only, no syncDraw
839 // Make it deactivate here
840 for (const auto &x : actions)
842 this->lc->visibilityChange(x);
843 x.client->emitVisible(false);
845 this->lc->renderLayers();
846 ret = WMError::NO_LAYOUT_CHANGE;
851 WMError WindowManager::doEndDraw(unsigned req_num)
855 auto actions = g_app_list.getActions(req_num, &found);
856 WMError ret = WMError::SUCCESS;
859 ret = WMError::NO_ENTRY;
863 HMI_SEQ_INFO(req_num, "do endDraw");
865 // layout change and make it visible
866 for (const auto &act : actions)
868 if(act.visible != TaskVisible::NO_CHANGE)
871 ret = this->lc->layoutChange(act);
872 if(ret != WMError::SUCCESS)
874 HMI_SEQ_WARNING(req_num,
875 "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
878 ret = this->lc->visibilityChange(act);
879 act.client->emitVisible((act.visible == VISIBLE));
881 if (ret != WMError::SUCCESS)
883 HMI_SEQ_WARNING(req_num,
884 "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
887 HMI_SEQ_DEBUG(req_num, "visible %s", act.role.c_str());
890 this->lc->renderLayers();
892 HMI_SEQ_INFO(req_num, "emit flushDraw");
894 for(const auto &act_flush : actions)
896 if(act_flush.visible == TaskVisible::VISIBLE)
898 act_flush.client->emitFlushDraw();
905 void WindowManager::emitScreenUpdated(unsigned req_num)
908 HMI_SEQ_DEBUG(req_num, "emit screen updated");
910 auto actions = g_app_list.getActions(req_num, &found);
913 HMI_SEQ_ERROR(req_num,
914 "Window Manager bug :%s : Action is not set",
915 errorDescription(WMError::NO_ENTRY));
919 // create json object
920 json_object *j = json_object_new_object();
921 json_object *jarray = json_object_new_array();
923 for(const auto& action: actions)
925 if(action.visible != TaskVisible::INVISIBLE)
927 json_object_array_add(jarray, json_object_new_string(action.client->appID().c_str()));
930 json_object_object_add(j, kKeyIds, jarray);
931 HMI_SEQ_INFO(req_num, "Visible app: %s", json_object_get_string(j));
933 int ret = afb_event_push(
934 this->map_afb_event[kListEventName[Event_ScreenUpdated]], j);
937 HMI_DEBUG("afb_event_push failed: %m");
941 void WindowManager::setTimer()
944 if (clock_gettime(CLOCK_BOOTTIME, &ts) != 0) {
945 HMI_ERROR("Could't set time (clock_gettime() returns with error");
949 HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "Timer set activate");
950 if (g_timer_ev_src == nullptr)
952 // firsttime set into sd_event
953 int ret = sd_event_add_time(afb_api_get_event_loop(afbBindingV3root), &g_timer_ev_src,
954 CLOCK_BOOTTIME, (uint64_t)(ts.tv_sec + kTimeOut) * 1000000ULL, 1, processTimerHandler, this);
957 HMI_ERROR("Could't set timer");
962 // update timer limitation after second time
963 sd_event_source_set_time(g_timer_ev_src, (uint64_t)(ts.tv_sec + kTimeOut) * 1000000ULL);
964 sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_ONESHOT);
968 void WindowManager::stopTimer()
970 unsigned req_num = g_app_list.currentRequestNumber();
971 HMI_SEQ_DEBUG(req_num, "Timer stop");
972 int rc = sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_OFF);
975 HMI_SEQ_ERROR(req_num, "Timer stop failed");
979 void WindowManager::processNextRequest()
982 g_app_list.reqDump();
983 unsigned req_num = g_app_list.currentRequestNumber();
984 if (g_app_list.haveRequest())
986 HMI_SEQ_DEBUG(req_num, "Process next request");
987 WMError rc = checkPolicy(req_num);
988 if (rc != WMError::SUCCESS)
990 HMI_SEQ_ERROR(req_num, errorDescription(rc));
995 HMI_SEQ_DEBUG(req_num, "Nothing Request. Waiting Request");