diff options
-rw-r--r-- | src/window_manager.cpp | 1138 | ||||
-rw-r--r-- | src/window_manager.hpp | 15 |
2 files changed, 575 insertions, 578 deletions
diff --git a/src/window_manager.cpp b/src/window_manager.cpp index 50e2f85..1582168 100644 --- a/src/window_manager.cpp +++ b/src/window_manager.cpp @@ -100,40 +100,6 @@ static int processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata } // namespace -void WindowManager::timerHandler() -{ - unsigned req_num = g_app_list.currentRequestNumber(); - HMI_SEQ_DEBUG(req_num, "Timer expired remove Request"); - g_app_list.reqDump(); - g_app_list.removeRequest(req_num); - this->processNextRequest(); -} - -void WindowManager::removeClient(const std::string &appid) -{ - HMI_DEBUG("wm", "Remove clinet %s from list", appid.c_str()); - g_app_list.removeClient(appid); -} - -void WindowManager::exceptionProcessForTransition() -{ - unsigned req_num = g_app_list.currentRequestNumber(); - HMI_SEQ_NOTICE(req_num, "Process exception handling for request. Remove current request %d", req_num); - g_app_list.removeRequest(req_num); - HMI_SEQ_NOTICE(g_app_list.currentRequestNumber(), "Process next request if exists"); - this->processNextRequest(); -} - -bool WindowManager::subscribeEventForApp(const std::string &appid, afb_req req, const std::string &evname) -{ - if(!g_app_list.contains(appid)){ - HMI_DEBUG("wm", "Client %s is not registered", appid.c_str()); - return false; - } - auto client = g_app_list.lookUpClient(appid); - return client->subscribe(req, evname); -} - /** * WindowManager Impl */ @@ -243,6 +209,391 @@ int WindowManager::dispatch_pending_events() return -1; } +void WindowManager::set_pending_events() +{ + this->pending_events.store(true, std::memory_order_release); +} + +result<int> WindowManager::api_request_surface(char const *appid, char const *drawing_name) +{ + auto lid = this->layers.get_layer_id(std::string(drawing_name)); + if (!lid) + { + /** + * register drawing_name as fallback and make it displayed. + */ + lid = this->layers.get_layer_id(std::string("Fallback")); + HMI_DEBUG("wm", "%s is not registered in layers.json, then fallback as normal app", drawing_name); + if (!lid) + { + return Err<int>("Drawing name does not match any role, Fallback is disabled"); + } + } + + auto rname = this->lookup_id(drawing_name); + if (!rname) + { + // name does not exist yet, allocate surface id... + auto id = int(this->id_alloc.generate_id(drawing_name)); + this->layers.add_surface(id, *lid); + + // set the main_surface[_name] here and now + if (!this->layers.main_surface_name.empty() && + this->layers.main_surface_name == drawing_name) + { + this->layers.main_surface = id; + HMI_DEBUG("wm", "Set main_surface id to %u", id); + } + + // add client into the db + std::string appid_str(appid); + std::string role(drawing_name); + //g_app_list.addClient(appid_str, role); + g_app_list.addClient(appid_str, *lid, id, role); + + return Ok<int>(id); + } + + // Check currently registered drawing names if it is already there. + return Err<int>("Surface already present"); +} + +char const *WindowManager::api_request_surface(char const *appid, char const *drawing_name, + char const *ivi_id) +{ + ST(); + + auto lid = this->layers.get_layer_id(std::string(drawing_name)); + unsigned sid = std::stol(ivi_id); + + if (!lid) + { + /** + * register drawing_name as fallback and make it displayed. + */ + lid = this->layers.get_layer_id(std::string("Fallback")); + HMI_DEBUG("wm", "%s is not registered in layers.json, then fallback as normal app", drawing_name); + if (!lid) + { + return "Drawing name does not match any role, Fallback is disabled"; + } + } + + auto rname = this->lookup_id(drawing_name); + + if (rname) + { + return "Surface already present"; + } + + // register pair drawing_name and ivi_id + this->id_alloc.register_name_id(drawing_name, sid); + this->layers.add_surface(sid, *lid); + + // this surface is already created + HMI_DEBUG("wm", "surface_id is %u, layer_id is %u", sid, *lid); + + this->controller->layers[*lid]->add_surface(sid); + this->layout_commit(); + + return nullptr; +} + +void WindowManager::api_activate_surface(char const *appid, char const *drawing_name, + char const *drawing_area, const reply_func &reply) +{ + ST(); + + std::string id = appid; + std::string role = drawing_name; + std::string area = drawing_area; + Task task = Task::TASK_ALLOCATE; + unsigned req_num = 0; + WMError ret = WMError::UNKNOWN; + + ret = this->setRequest(id, role, area, task, &req_num); + + if(ret != WMError::SUCCESS) + { + HMI_ERROR("wm", errorDescription(ret)); + reply("Failed to set request"); + return; + } + + reply(nullptr); + if (req_num != g_app_list.currentRequestNumber()) + { + // Add request, then invoked after the previous task is finished + HMI_SEQ_DEBUG(req_num, "request is accepted"); + return; + } + + /* + * Do allocate tasks + */ + ret = this->doTransition(req_num); + + if (ret != WMError::SUCCESS) + { + //this->emit_error() + HMI_SEQ_ERROR(req_num, errorDescription(ret)); + g_app_list.removeRequest(req_num); + this->processNextRequest(); + } +} + +void WindowManager::api_deactivate_surface(char const *appid, char const *drawing_name, + const reply_func &reply) +{ + ST(); + + /* + * Check Phase + */ + std::string id = appid; + std::string role = drawing_name; + std::string area = ""; //drawing_area; + Task task = Task::TASK_RELEASE; + unsigned req_num = 0; + WMError ret = WMError::UNKNOWN; + + ret = this->setRequest(id, role, area, task, &req_num); + + if (ret != WMError::SUCCESS) + { + HMI_ERROR("wm", errorDescription(ret)); + reply("Failed to set request"); + return; + } + + reply(nullptr); + if (req_num != g_app_list.currentRequestNumber()) + { + // Add request, then invoked after the previous task is finished + HMI_SEQ_DEBUG(req_num, "request is accepted"); + return; + } + + /* + * Do allocate tasks + */ + ret = this->doTransition(req_num); + + if (ret != WMError::SUCCESS) + { + //this->emit_error() + HMI_SEQ_ERROR(req_num, errorDescription(ret)); + g_app_list.removeRequest(req_num); + this->processNextRequest(); + } +} + +void WindowManager::api_enddraw(char const *appid, char const *drawing_name) +{ + std::string id = appid; + std::string role = drawing_name; + unsigned current_req = g_app_list.currentRequestNumber(); + bool result = g_app_list.setEndDrawFinished(current_req, id, role); + + if (!result) + { + HMI_ERROR("wm", "%s is not in transition state", id.c_str()); + return; + } + + if (g_app_list.endDrawFullfilled(current_req)) + { + // do task for endDraw + this->stopTimer(); + WMError ret = this->doEndDraw(current_req); + + if(ret != WMError::SUCCESS) + { + //this->emit_error(); + } + HMI_SEQ_INFO(current_req, "Finish request status: %s", errorDescription(ret)); + + g_app_list.removeRequest(current_req); + + this->processNextRequest(); + } + else + { + HMI_SEQ_INFO(current_req, "Wait other App call endDraw"); + return; + } +} + +result<json_object *> WindowManager::api_get_display_info() +{ + // Check controller + if (!this->controller) + { + return Err<json_object *>("ivi_controller global not available"); + } + + // Set display info + compositor::size o_size = this->controller->output_size; + compositor::size p_size = this->controller->physical_size; + + json_object *object = json_object_new_object(); + json_object_object_add(object, kKeyWidthPixel, json_object_new_int(o_size.w)); + json_object_object_add(object, kKeyHeightPixel, json_object_new_int(o_size.h)); + json_object_object_add(object, kKeyWidthMm, json_object_new_int(p_size.w)); + json_object_object_add(object, kKeyHeightMm, json_object_new_int(p_size.h)); + + return Ok<json_object *>(object); +} + +result<json_object *> WindowManager::api_get_area_info(char const *drawing_name) +{ + HMI_DEBUG("wm", "called"); + + // Check drawing name, surface/layer id + auto const &surface_id = this->lookup_id(drawing_name); + if (!surface_id) + { + return Err<json_object *>("Surface does not exist"); + } + + if (!this->controller->surface_exists(*surface_id)) + { + return Err<json_object *>("Surface does not exist in controller!"); + } + + auto layer_id = this->layers.get_layer_id(*surface_id); + if (!layer_id) + { + return Err<json_object *>("Surface is not on any layer!"); + } + + auto o_state = *this->layers.get_layout_state(*surface_id); + if (o_state == nullptr) + { + return Err<json_object *>("Could not find layer for surface"); + } + + struct LayoutState &state = *o_state; + if ((state.main != *surface_id) && (state.sub != *surface_id)) + { + return Err<json_object *>("Surface is inactive"); + } + + // Set area rectangle + compositor::rect area_info = this->area_info[*surface_id]; + json_object *object = json_object_new_object(); + json_object_object_add(object, kKeyX, json_object_new_int(area_info.x)); + json_object_object_add(object, kKeyY, json_object_new_int(area_info.y)); + json_object_object_add(object, kKeyWidth, json_object_new_int(area_info.w)); + json_object_object_add(object, kKeyHeight, json_object_new_int(area_info.h)); + + return Ok<json_object *>(object); +} + +void WindowManager::api_ping() { this->dispatch_pending_events(); } + +void WindowManager::send_event(char const *evname, char const *label) +{ + HMI_DEBUG("wm", "%s: %s(%s)", __func__, evname, label); + + json_object *j = json_object_new_object(); + json_object_object_add(j, kKeyDrawingName, json_object_new_string(label)); + + int ret = afb_event_push(this->map_afb_event[evname], j); + if (ret != 0) + { + HMI_DEBUG("wm", "afb_event_push failed: %m"); + } +} + +void WindowManager::send_event(char const *evname, char const *label, char const *area, + int x, int y, int w, int h) +{ + HMI_DEBUG("wm", "%s: %s(%s, %s) x:%d y:%d w:%d h:%d", + __func__, evname, label, area, x, y, w, h); + + json_object *j_rect = json_object_new_object(); + json_object_object_add(j_rect, kKeyX, json_object_new_int(x)); + json_object_object_add(j_rect, kKeyY, json_object_new_int(y)); + json_object_object_add(j_rect, kKeyWidth, json_object_new_int(w)); + json_object_object_add(j_rect, kKeyHeight, json_object_new_int(h)); + + json_object *j = json_object_new_object(); + json_object_object_add(j, kKeyDrawingName, json_object_new_string(label)); + json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area)); + json_object_object_add(j, kKeyDrawingRect, j_rect); + + int ret = afb_event_push(this->map_afb_event[evname], j); + if (ret != 0) + { + HMI_DEBUG("wm", "afb_event_push failed: %m"); + } +} + +/** + * proxied events + */ +void WindowManager::surface_created(uint32_t surface_id) +{ + auto layer_id = this->layers.get_layer_id(surface_id); + if (!layer_id) + { + HMI_DEBUG("wm", "Newly created surfce %d is not associated with any layer!", + surface_id); + return; + } + + HMI_DEBUG("wm", "surface_id is %u, layer_id is %u", surface_id, *layer_id); + + this->controller->layers[*layer_id]->add_surface(surface_id); + this->layout_commit(); +} + +void WindowManager::surface_removed(uint32_t surface_id) +{ + HMI_DEBUG("wm", "surface_id is %u", surface_id); + + g_app_list.removeSurface(surface_id); +} + +void WindowManager::removeClient(const std::string &appid) +{ + HMI_DEBUG("wm", "Remove clinet %s from list", appid.c_str()); + g_app_list.removeClient(appid); +} + +void WindowManager::exceptionProcessForTransition() +{ + unsigned req_num = g_app_list.currentRequestNumber(); + HMI_SEQ_NOTICE(req_num, "Process exception handling for request. Remove current request %d", req_num); + g_app_list.removeRequest(req_num); + HMI_SEQ_NOTICE(g_app_list.currentRequestNumber(), "Process next request if exists"); + this->processNextRequest(); +} + +bool WindowManager::subscribeEventForApp(const std::string &appid, afb_req req, const std::string &evname) +{ + if(!g_app_list.contains(appid)){ + HMI_DEBUG("wm", "Client %s is not registered", appid.c_str()); + return false; + } + auto client = g_app_list.lookUpClient(appid); + return client->subscribe(req, evname); +} + +void WindowManager::timerHandler() +{ + unsigned req_num = g_app_list.currentRequestNumber(); + HMI_SEQ_DEBUG(req_num, "Timer expired remove Request"); + g_app_list.reqDump(); + g_app_list.removeRequest(req_num); + this->processNextRequest(); +} + +/* + ******* Private Functions ******* + */ + bool WindowManager::pop_pending_events() { bool x{true}; @@ -250,11 +601,6 @@ bool WindowManager::pop_pending_events() x, false, std::memory_order_consume); } -void WindowManager::set_pending_events() -{ - this->pending_events.store(true, std::memory_order_release); -} - optional<int> WindowManager::lookup_id(char const *name) { return this->id_alloc.lookup(std::string(name)); @@ -381,36 +727,161 @@ void WindowManager::layout_commit() this->display->flush(); } -void WindowManager::setTimer() +void WindowManager::emit_activated(char const *label) { - HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "Timer set activate"); - if (g_timer_ev_src == nullptr) + this->send_event(kListEventName[Event_Active], label); +} + +void WindowManager::emit_deactivated(char const *label) +{ + this->send_event(kListEventName[Event_Inactive], label); +} + +void WindowManager::emit_syncdraw(char const *label, char const *area, int x, int y, int w, int h) +{ + this->send_event(kListEventName[Event_SyncDraw], label, area, x, y, w, h); +} + +void WindowManager::emit_syncdraw(const std::string &role, const std::string &area) +{ + compositor::rect rect = this->layers.getAreaSize(area); + //this->lm_get_area_info(area, &x, &y, &w, &h); + this->send_event(kListEventName[Event_SyncDraw], + role.c_str(), area.c_str(), rect.x, rect.y, rect.w, rect.h); +} + +void WindowManager::emit_flushdraw(char const *label) +{ + this->send_event(kListEventName[Event_FlushDraw], label); +} + +void WindowManager::emit_visible(char const *label, bool is_visible) +{ + this->send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], label); +} + +void WindowManager::emit_invisible(char const *label) +{ + return emit_visible(label, false); +} + +void WindowManager::emit_visible(char const *label) { return emit_visible(label, true); } + +void WindowManager::activate(int id) +{ + auto ip = this->controller->sprops.find(id); + if (ip != this->controller->sprops.end()) { - // firsttime set into sd_event - int ret = sd_event_add_time(afb_daemon_get_event_loop(), &g_timer_ev_src, - CLOCK_REALTIME, time(NULL) * (1000000UL) + kTimeOut, 1, processTimerHandler, this); - if (ret < 0) + this->controller->surfaces[id]->set_visibility(1); + char const *label = + this->lookup_name(id).value_or("unknown-name").c_str(); + + // FOR CES DEMO >>> + if ((0 == strcmp(label, "Radio")) || + (0 == strcmp(label, "MediaPlayer")) || + (0 == strcmp(label, "Music")) || + (0 == strcmp(label, "Navigation"))) { - HMI_ERROR("wm", "Could't set timer"); + for (auto i = surface_bg.begin(); i != surface_bg.end(); ++i) + { + if (id == *i) + { + // Remove id + this->surface_bg.erase(i); + + // Remove from BG layer (999) + HMI_DEBUG("wm", "Remove %s(%d) from BG layer", label, id); + this->controller->layers[999]->remove_surface(id); + + // Add to FG layer (1001) + HMI_DEBUG("wm", "Add %s(%d) to FG layer", label, id); + this->controller->layers[1001]->add_surface(id); + + for (int j : this->surface_bg) + { + HMI_DEBUG("wm", "Stored id:%d", j); + } + break; + } + } } + // <<< FOR CES DEMO + this->layout_commit(); + + this->emit_visible(label); + this->emit_activated(label); } - else +} + +void WindowManager::deactivate(int id) +{ + auto ip = this->controller->sprops.find(id); + if (ip != this->controller->sprops.end()) { - // update timer limitation after second time - sd_event_source_set_time(g_timer_ev_src, time(NULL) * (1000000UL) + kTimeOut); - sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_ONESHOT); + char const *label = + this->lookup_name(id).value_or("unknown-name").c_str(); + + // FOR CES DEMO >>> + if ((0 == strcmp(label, "Radio")) || (0 == strcmp(label, "MediaPlayer")) || (0 == strcmp(label, "Music")) || (0 == strcmp(label, "Navigation"))) + { + + // Store id + this->surface_bg.push_back(id); + + // Remove from FG layer (1001) + HMI_DEBUG("wm", "Remove %s(%d) from FG layer", label, id); + this->controller->layers[1001]->remove_surface(id); + + // Add to BG layer (999) + HMI_DEBUG("wm", "Add %s(%d) to BG layer", label, id); + this->controller->layers[999]->add_surface(id); + + for (int j : surface_bg) + { + HMI_DEBUG("wm", "Stored id:%d", j); + } + } + else + { + this->controller->surfaces[id]->set_visibility(0); + } + // <<< FOR CES DEMO + + this->emit_deactivated(label); + this->emit_invisible(label); } } -void WindowManager::stopTimer() +WMError WindowManager::setRequest(const std::string& appid, const std::string &role, const std::string &area, + Task task, unsigned* req_num) { - unsigned req_num = g_app_list.currentRequestNumber(); - HMI_SEQ_DEBUG(req_num, "Timer stop"); - int rc = sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_OFF); - if (rc < 0) + if (!g_app_list.contains(appid)) { - HMI_SEQ_ERROR(req_num, "Timer stop failed"); + return WMError::NOT_REGISTERED; } + + auto client = g_app_list.lookUpClient(appid); + + /* + * Queueing Phase + */ + unsigned current = g_app_list.currentRequestNumber(); + unsigned requested_num = g_app_list.getRequestNumber(appid); + if (requested_num != 0) + { + HMI_SEQ_INFO(requested_num, + "%s %s %s request is already queued", appid.c_str(), role.c_str(), area.c_str()); + return REQ_REJECTED; + } + + WMRequest req = WMRequest(appid, role, area, task); + unsigned new_req = g_app_list.addRequest(req); + *req_num = new_req; + g_app_list.reqDump(); + + HMI_SEQ_DEBUG(current, "%s start sequence with %s, %s", appid.c_str(), role.c_str(), area.c_str()); + + return WMError::SUCCESS; } WMError WindowManager::doTransition(unsigned req_num) @@ -722,163 +1193,6 @@ WMError WindowManager::setInvisibleTask(const std::string &role, bool split) return WMError::SUCCESS; } -const char *WindowManager::check_surface_exist(const char *drawing_name) -{ - auto const &surface_id = this->lookup_id(drawing_name); - if (!surface_id) - { - //reply("Surface does not exist"); - return "Surface does not exist"; - } - - if (!this->controller->surface_exists(*surface_id)) - { - //reply("Surface does not exist in controller!"); - return "Surface does not exist in controller!"; - } - - auto layer_id = this->layers.get_layer_id(*surface_id); - - if (!layer_id) - { - //reply("Surface is not on any layer!"); - return "Surface is not on any layer!"; - } - - auto o_state = *this->layers.get_layout_state(*surface_id); - - if (o_state == nullptr) - { - //reply("Could not find layer for surface"); - return "Could not find layer for surface"; - } - - HMI_DEBUG("wm", "surface %d is detected", *surface_id); - return nullptr; - //reply(nullptr); -} - -WMError WindowManager::setRequest(const std::string& appid, const std::string &role, const std::string &area, - Task task, unsigned* req_num) -{ - if (!g_app_list.contains(appid)) - { - return WMError::NOT_REGISTERED; - } - - auto client = g_app_list.lookUpClient(appid); - - /* - * Queueing Phase - */ - unsigned current = g_app_list.currentRequestNumber(); - unsigned requested_num = g_app_list.getRequestNumber(appid); - if (requested_num != 0) - { - HMI_SEQ_INFO(requested_num, - "%s %s %s request is already queued", appid.c_str(), role.c_str(), area.c_str()); - return REQ_REJECTED; - } - - WMRequest req = WMRequest(appid, role, area, task); - unsigned new_req = g_app_list.addRequest(req); - *req_num = new_req; - g_app_list.reqDump(); - - HMI_SEQ_DEBUG(current, "%s start sequence with %s, %s", appid.c_str(), role.c_str(), area.c_str()); - - return WMError::SUCCESS; -} - -void WindowManager::api_activate_surface(char const *appid, char const *drawing_name, - char const *drawing_area, const reply_func &reply) -{ - ST(); - - std::string id = appid; - std::string role = drawing_name; - std::string area = drawing_area; - Task task = Task::TASK_ALLOCATE; - unsigned req_num = 0; - WMError ret = WMError::UNKNOWN; - - ret = this->setRequest(id, role, area, task, &req_num); - - if(ret != WMError::SUCCESS) - { - HMI_ERROR("wm", errorDescription(ret)); - reply("Failed to set request"); - return; - } - - reply(nullptr); - if (req_num != g_app_list.currentRequestNumber()) - { - // Add request, then invoked after the previous task is finished - HMI_SEQ_DEBUG(req_num, "request is accepted"); - return; - } - - /* - * Do allocate tasks - */ - ret = this->doTransition(req_num); - - if (ret != WMError::SUCCESS) - { - //this->emit_error() - HMI_SEQ_ERROR(req_num, errorDescription(ret)); - g_app_list.removeRequest(req_num); - this->processNextRequest(); - } -} - -void WindowManager::api_deactivate_surface(char const *appid, char const *drawing_name, - const reply_func &reply) -{ - ST(); - - /* - * Check Phase - */ - std::string id = appid; - std::string role = drawing_name; - std::string area = ""; //drawing_area; - Task task = Task::TASK_RELEASE; - unsigned req_num = 0; - WMError ret = WMError::UNKNOWN; - - ret = this->setRequest(id, role, area, task, &req_num); - - if (ret != WMError::SUCCESS) - { - HMI_ERROR("wm", errorDescription(ret)); - reply("Failed to set request"); - return; - } - - reply(nullptr); - if (req_num != g_app_list.currentRequestNumber()) - { - // Add request, then invoked after the previous task is finished - HMI_SEQ_DEBUG(req_num, "request is accepted"); - return; - } - - /* - * Do allocate tasks - */ - ret = this->doTransition(req_num); - - if (ret != WMError::SUCCESS) - { - //this->emit_error() - HMI_SEQ_ERROR(req_num, errorDescription(ret)); - g_app_list.removeRequest(req_num); - this->processNextRequest(); - } -} - WMError WindowManager::doEndDraw(unsigned req_num) { // get actions @@ -934,13 +1248,6 @@ WMError WindowManager::doEndDraw(unsigned req_num) return ret; } -WMError WindowManager::setSurfaceSize(unsigned surface, const std::string &area) -{ - this->surface_set_layout(surface, area); - - return WMError::SUCCESS; -} - WMError WindowManager::layoutChange(const WMAction &action) { if (action.visible == TaskVisible::INVISIBLE) @@ -987,6 +1294,13 @@ WMError WindowManager::visibilityChange(const WMAction &action) return WMError::SUCCESS; } +WMError WindowManager::setSurfaceSize(unsigned surface, const std::string &area) +{ + this->surface_set_layout(surface, area); + + return WMError::SUCCESS; +} + WMError WindowManager::changeCurrentState(unsigned req_num) { HMI_SEQ_DEBUG(req_num, "Change current layout state"); @@ -1055,39 +1369,35 @@ WMError WindowManager::changeCurrentState(unsigned req_num) return WMError::SUCCESS; } -void WindowManager::api_enddraw(char const *appid, char const *drawing_name) +void WindowManager::setTimer() { - std::string id = appid; - std::string role = drawing_name; - unsigned current_req = g_app_list.currentRequestNumber(); - bool result = g_app_list.setEndDrawFinished(current_req, id, role); - - if (!result) - { - HMI_ERROR("wm", "%s is not in transition state", id.c_str()); - return; - } - - if (g_app_list.endDrawFullfilled(current_req)) + HMI_SEQ_DEBUG(g_app_list.currentRequestNumber(), "Timer set activate"); + if (g_timer_ev_src == nullptr) { - // do task for endDraw - this->stopTimer(); - WMError ret = this->doEndDraw(current_req); - - if(ret != WMError::SUCCESS) + // firsttime set into sd_event + int ret = sd_event_add_time(afb_daemon_get_event_loop(), &g_timer_ev_src, + CLOCK_REALTIME, time(NULL) * (1000000UL) + kTimeOut, 1, processTimerHandler, this); + if (ret < 0) { - //this->emit_error(); + HMI_ERROR("wm", "Could't set timer"); } - HMI_SEQ_INFO(current_req, "Finish request status: %s", errorDescription(ret)); - - g_app_list.removeRequest(current_req); - - this->processNextRequest(); } else { - HMI_SEQ_INFO(current_req, "Wait other App call endDraw"); - return; + // update timer limitation after second time + sd_event_source_set_time(g_timer_ev_src, time(NULL) * (1000000UL) + kTimeOut); + sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_ONESHOT); + } +} + +void WindowManager::stopTimer() +{ + unsigned req_num = g_app_list.currentRequestNumber(); + HMI_SEQ_DEBUG(req_num, "Timer stop"); + int rc = sd_event_source_set_enabled(g_timer_ev_src, SD_EVENT_OFF); + if (rc < 0) + { + HMI_SEQ_ERROR(req_num, "Timer stop failed"); } } @@ -1111,346 +1421,40 @@ void WindowManager::processNextRequest() } } -void WindowManager::api_ping() { this->dispatch_pending_events(); } - -void WindowManager::send_event(char const *evname, char const *label) -{ - HMI_DEBUG("wm", "%s: %s(%s)", __func__, evname, label); - - json_object *j = json_object_new_object(); - json_object_object_add(j, kKeyDrawingName, json_object_new_string(label)); - - int ret = afb_event_push(this->map_afb_event[evname], j); - if (ret != 0) - { - HMI_DEBUG("wm", "afb_event_push failed: %m"); - } -} - -void WindowManager::send_event(char const *evname, char const *label, char const *area, - int x, int y, int w, int h) -{ - HMI_DEBUG("wm", "%s: %s(%s, %s) x:%d y:%d w:%d h:%d", - __func__, evname, label, area, x, y, w, h); - - json_object *j_rect = json_object_new_object(); - json_object_object_add(j_rect, kKeyX, json_object_new_int(x)); - json_object_object_add(j_rect, kKeyY, json_object_new_int(y)); - json_object_object_add(j_rect, kKeyWidth, json_object_new_int(w)); - json_object_object_add(j_rect, kKeyHeight, json_object_new_int(h)); - - json_object *j = json_object_new_object(); - json_object_object_add(j, kKeyDrawingName, json_object_new_string(label)); - json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area)); - json_object_object_add(j, kKeyDrawingRect, j_rect); - - int ret = afb_event_push(this->map_afb_event[evname], j); - if (ret != 0) - { - HMI_DEBUG("wm", "afb_event_push failed: %m"); - } -} - -/** - * proxied events - */ -void WindowManager::surface_created(uint32_t surface_id) -{ - auto layer_id = this->layers.get_layer_id(surface_id); - if (!layer_id) - { - HMI_DEBUG("wm", "Newly created surfce %d is not associated with any layer!", - surface_id); - return; - } - - HMI_DEBUG("wm", "surface_id is %u, layer_id is %u", surface_id, *layer_id); - - this->controller->layers[*layer_id]->add_surface(surface_id); - this->layout_commit(); -} - -void WindowManager::surface_removed(uint32_t surface_id) -{ - HMI_DEBUG("wm", "surface_id is %u", surface_id); - - g_app_list.removeSurface(surface_id); -} - -void WindowManager::emit_activated(char const *label) -{ - this->send_event(kListEventName[Event_Active], label); -} - -void WindowManager::emit_deactivated(char const *label) -{ - this->send_event(kListEventName[Event_Inactive], label); -} - -void WindowManager::emit_syncdraw(char const *label, char const *area, int x, int y, int w, int h) -{ - this->send_event(kListEventName[Event_SyncDraw], label, area, x, y, w, h); -} - -void WindowManager::emit_syncdraw(const std::string &role, const std::string &area) -{ - compositor::rect rect = this->layers.getAreaSize(area); - //this->lm_get_area_info(area, &x, &y, &w, &h); - this->send_event(kListEventName[Event_SyncDraw], - role.c_str(), area.c_str(), rect.x, rect.y, rect.w, rect.h); -} - -void WindowManager::emit_flushdraw(char const *label) -{ - this->send_event(kListEventName[Event_FlushDraw], label); -} - -void WindowManager::emit_visible(char const *label, bool is_visible) -{ - this->send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], label); -} - -void WindowManager::emit_invisible(char const *label) -{ - return emit_visible(label, false); -} - -void WindowManager::emit_visible(char const *label) { return emit_visible(label, true); } - -result<int> WindowManager::api_request_surface(char const *appid, char const *drawing_name) -{ - auto lid = this->layers.get_layer_id(std::string(drawing_name)); - if (!lid) - { - /** - * register drawing_name as fallback and make it displayed. - */ - lid = this->layers.get_layer_id(std::string("Fallback")); - HMI_DEBUG("wm", "%s is not registered in layers.json, then fallback as normal app", drawing_name); - if (!lid) - { - return Err<int>("Drawing name does not match any role, Fallback is disabled"); - } - } - - auto rname = this->lookup_id(drawing_name); - if (!rname) - { - // name does not exist yet, allocate surface id... - auto id = int(this->id_alloc.generate_id(drawing_name)); - this->layers.add_surface(id, *lid); - - // set the main_surface[_name] here and now - if (!this->layers.main_surface_name.empty() && - this->layers.main_surface_name == drawing_name) - { - this->layers.main_surface = id; - HMI_DEBUG("wm", "Set main_surface id to %u", id); - } - - // add client into the db - std::string appid_str(appid); - std::string role(drawing_name); - //g_app_list.addClient(appid_str, role); - g_app_list.addClient(appid_str, *lid, id, role); - - return Ok<int>(id); - } - - // Check currently registered drawing names if it is already there. - return Err<int>("Surface already present"); -} - -char const *WindowManager::api_request_surface(char const *appid, char const *drawing_name, - char const *ivi_id) -{ - ST(); - - auto lid = this->layers.get_layer_id(std::string(drawing_name)); - unsigned sid = std::stol(ivi_id); - - if (!lid) - { - /** - * register drawing_name as fallback and make it displayed. - */ - lid = this->layers.get_layer_id(std::string("Fallback")); - HMI_DEBUG("wm", "%s is not registered in layers.json, then fallback as normal app", drawing_name); - if (!lid) - { - return "Drawing name does not match any role, Fallback is disabled"; - } - } - - auto rname = this->lookup_id(drawing_name); - - if (rname) - { - return "Surface already present"; - } - - // register pair drawing_name and ivi_id - this->id_alloc.register_name_id(drawing_name, sid); - this->layers.add_surface(sid, *lid); - - // this surface is already created - HMI_DEBUG("wm", "surface_id is %u, layer_id is %u", sid, *lid); - - this->controller->layers[*lid]->add_surface(sid); - this->layout_commit(); - - return nullptr; -} - -result<json_object *> WindowManager::api_get_display_info() -{ - // Check controller - if (!this->controller) - { - return Err<json_object *>("ivi_controller global not available"); - } - - // Set display info - compositor::size o_size = this->controller->output_size; - compositor::size p_size = this->controller->physical_size; - - json_object *object = json_object_new_object(); - json_object_object_add(object, kKeyWidthPixel, json_object_new_int(o_size.w)); - json_object_object_add(object, kKeyHeightPixel, json_object_new_int(o_size.h)); - json_object_object_add(object, kKeyWidthMm, json_object_new_int(p_size.w)); - json_object_object_add(object, kKeyHeightMm, json_object_new_int(p_size.h)); - - return Ok<json_object *>(object); -} - -result<json_object *> WindowManager::api_get_area_info(char const *drawing_name) +const char *WindowManager::check_surface_exist(const char *drawing_name) { - HMI_DEBUG("wm", "called"); - - // Check drawing name, surface/layer id auto const &surface_id = this->lookup_id(drawing_name); if (!surface_id) { - return Err<json_object *>("Surface does not exist"); + //reply("Surface does not exist"); + return "Surface does not exist"; } if (!this->controller->surface_exists(*surface_id)) { - return Err<json_object *>("Surface does not exist in controller!"); + //reply("Surface does not exist in controller!"); + return "Surface does not exist in controller!"; } auto layer_id = this->layers.get_layer_id(*surface_id); + if (!layer_id) { - return Err<json_object *>("Surface is not on any layer!"); + //reply("Surface is not on any layer!"); + return "Surface is not on any layer!"; } auto o_state = *this->layers.get_layout_state(*surface_id); - if (o_state == nullptr) - { - return Err<json_object *>("Could not find layer for surface"); - } - - struct LayoutState &state = *o_state; - if ((state.main != *surface_id) && (state.sub != *surface_id)) - { - return Err<json_object *>("Surface is inactive"); - } - // Set area rectangle - compositor::rect area_info = this->area_info[*surface_id]; - json_object *object = json_object_new_object(); - json_object_object_add(object, kKeyX, json_object_new_int(area_info.x)); - json_object_object_add(object, kKeyY, json_object_new_int(area_info.y)); - json_object_object_add(object, kKeyWidth, json_object_new_int(area_info.w)); - json_object_object_add(object, kKeyHeight, json_object_new_int(area_info.h)); - - return Ok<json_object *>(object); -} - -void WindowManager::activate(int id) -{ - auto ip = this->controller->sprops.find(id); - if (ip != this->controller->sprops.end()) + if (o_state == nullptr) { - this->controller->surfaces[id]->set_visibility(1); - char const *label = - this->lookup_name(id).value_or("unknown-name").c_str(); - - // FOR CES DEMO >>> - if ((0 == strcmp(label, "Radio")) || - (0 == strcmp(label, "MediaPlayer")) || - (0 == strcmp(label, "Music")) || - (0 == strcmp(label, "Navigation"))) - { - for (auto i = surface_bg.begin(); i != surface_bg.end(); ++i) - { - if (id == *i) - { - // Remove id - this->surface_bg.erase(i); - - // Remove from BG layer (999) - HMI_DEBUG("wm", "Remove %s(%d) from BG layer", label, id); - this->controller->layers[999]->remove_surface(id); - - // Add to FG layer (1001) - HMI_DEBUG("wm", "Add %s(%d) to FG layer", label, id); - this->controller->layers[1001]->add_surface(id); - - for (int j : this->surface_bg) - { - HMI_DEBUG("wm", "Stored id:%d", j); - } - break; - } - } - } - // <<< FOR CES DEMO - this->layout_commit(); - - this->emit_visible(label); - this->emit_activated(label); + //reply("Could not find layer for surface"); + return "Could not find layer for surface"; } -} -void WindowManager::deactivate(int id) -{ - auto ip = this->controller->sprops.find(id); - if (ip != this->controller->sprops.end()) - { - char const *label = - this->lookup_name(id).value_or("unknown-name").c_str(); - - // FOR CES DEMO >>> - if ((0 == strcmp(label, "Radio")) || (0 == strcmp(label, "MediaPlayer")) || (0 == strcmp(label, "Music")) || (0 == strcmp(label, "Navigation"))) - { - - // Store id - this->surface_bg.push_back(id); - - // Remove from FG layer (1001) - HMI_DEBUG("wm", "Remove %s(%d) from FG layer", label, id); - this->controller->layers[1001]->remove_surface(id); - - // Add to BG layer (999) - HMI_DEBUG("wm", "Add %s(%d) to BG layer", label, id); - this->controller->layers[999]->add_surface(id); - - for (int j : surface_bg) - { - HMI_DEBUG("wm", "Stored id:%d", j); - } - } - else - { - this->controller->surfaces[id]->set_visibility(0); - } - // <<< FOR CES DEMO - - this->emit_deactivated(label); - this->emit_invisible(label); - } + HMI_DEBUG("wm", "surface %d is detected", *surface_id); + return nullptr; + //reply(nullptr); } bool WindowManager::can_split(struct LayoutState const &state, int new_id) diff --git a/src/window_manager.hpp b/src/window_manager.hpp index 99a30e0..06967c0 100644 --- a/src/window_manager.hpp +++ b/src/window_manager.hpp @@ -201,9 +201,7 @@ class WindowManager WindowManager &operator=(WindowManager &&) = delete; int init(); - int dispatch_pending_events(); - void set_pending_events(); result<int> api_request_surface(char const *appid, char const *drawing_name); @@ -225,21 +223,17 @@ class WindowManager void exceptionProcessForTransition(); bool subscribeEventForApp(const std::string &appid, afb_req req, const std::string &evname); // Do not use this function - //static int processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata); void timerHandler(); private: + bool pop_pending_events(); optional<int> lookup_id(char const *name); optional<std::string> lookup_name(int id); - - bool pop_pending_events(); - int init_layers(); - void surface_set_layout(int surface_id, const std::string& area = ""); void layout_commit(); - // TMC WM Events to clients + // WM Events to clients void emit_activated(char const *label); void emit_deactivated(char const *label); void emit_syncdraw(char const *label, char const *area, int x, int y, int w, int h); @@ -249,6 +243,8 @@ class WindowManager void emit_invisible(char const *label); void emit_visible(char const *label); + void activate(int id); + void deactivate(int id); WMError setRequest(const std::string &appid, const std::string &role, const std::string &area, Task task, unsigned *req_num); WMError doTransition(unsigned sequence_number); @@ -268,9 +264,6 @@ class WindowManager const char *check_surface_exist(const char *drawing_name); - void activate(int id); - void deactivate(int id); - bool can_split(struct LayoutState const &state, int new_id); private: |