X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fwindow_manager.cpp;h=f9070f6d2ca4ecc37e66221f8eb3ce39a55cf775;hb=refs%2Fchanges%2F63%2F20863%2F1;hp=9537be75403d39d233b9af33c4aff0102c780bd1;hpb=fb861c2f05e5f49f4009d0d7c91101259f904f1d;p=apps%2Fagl-service-windowmanager.git diff --git a/src/window_manager.cpp b/src/window_manager.cpp index 9537be7..f9070f6 100644 --- a/src/window_manager.cpp +++ b/src/window_manager.cpp @@ -28,6 +28,7 @@ extern "C" using std::string; using std::vector; +using std::unordered_map; namespace wm { @@ -69,6 +70,9 @@ static const vector kListEventName{ static sd_event_source *g_timer_ev_src = nullptr; static AppList g_app_list; static WindowManager *g_context; +static vector white_list_area_size_change = { + "homescreen", "settings" +}; namespace { @@ -163,21 +167,25 @@ result WindowManager::api_request_surface(char const *appid, char const *dr if(!g_app_list.contains(str_id)) { - lid = this->lc->getNewLayerID(role); + lid = this->generateLayerForClient(role); if (lid == 0) { - // register drawing_name as fallback and make it displayed. - lid = this->lc->getNewLayerID(string("fallback")); - HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role); - if (lid == 0) - { - return Err("Designated role does not match any role, fallback is disabled"); - } + return Err("Designated role does not match any role, fallback is disabled"); } - this->lc->createNewLayer(lid); // add client into the db g_app_list.addClient(str_id, lid, role); } + else + { + // This case occurs when an client calls "subscribe" before request_surface. + // Then application doesn't have layer and role yet. + auto client = g_app_list.lookUpClient(str_id); + if(client->layerID() == 0) + { + client->setLayerID(this->generateLayerForClient(role)); + } + client->setRole(role); + } // generate surface ID for ivi-shell application auto rname = this->id_alloc.lookup(role); @@ -220,21 +228,25 @@ char const *WindowManager::api_request_surface(char const *appid, char const *dr if(!g_app_list.contains(str_id)) { - unsigned l_id = this->lc->getNewLayerID(role); + unsigned l_id = this->generateLayerForClient(role); if (l_id == 0) { - // register drawing_name as fallback and make it displayed. - l_id = this->lc->getNewLayerID("fallback"); - HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role); - if (l_id == 0) - { - return "Designated role does not match any role, fallback is disabled"; - } + return "Designated role does not match any role, fallback is disabled"; } - this->lc->createNewLayer(l_id); // add client into the db g_app_list.addClient(str_id, l_id, role); } + else + { + // This case occurs when an client calls "subscribe" before request_surface. + // Then application doesn't have layer and role yet. + auto client = g_app_list.lookUpClient(str_id); + if(client->layerID() == 0) + { + client->setLayerID(this->generateLayerForClient(role)); + } + client->setRole(role); + } auto rname = this->id_alloc.lookup(role); @@ -380,6 +392,99 @@ void WindowManager::api_enddraw(char const *appid, char const *drawing_name) } } +json_object* WindowManager::api_get_area_list() +{ + json_object* ret = json_object_new_object(); + json_object* jarray = json_object_new_array(); + unordered_map area2size = this->lc->getAreaList(); + for(const auto& area : area2size) + { + json_object* j = json_object_new_object(); + json_object_object_add(j, "name", json_object_new_string(area.first.c_str())); + json_object* jrect = json_object_new_object(); + json_object_object_add(jrect, "x", json_object_new_int(area.second.x)); + json_object_object_add(jrect, "y", json_object_new_int(area.second.y)); + json_object_object_add(jrect, "w", json_object_new_int(area.second.w)); + json_object_object_add(jrect, "h", json_object_new_int(area.second.h)); + json_object_object_add(j, "rect", jrect); + json_object_array_add(jarray, j); + } + json_object_object_add(ret, "areas", jarray); + HMI_DEBUG("area_list: %s", json_object_get_string(ret)); + return ret; +} + +void WindowManager::api_change_area_size(ChangeAreaReq &areas) +{ + // Error check + areas.dump(); + auto client = g_app_list.lookUpClient(areas.appname); + WMError ret; + if(client == nullptr) + { + HMI_ERROR("Call register your role with setRole or requestSurface"); + return; + } + if(std::find(white_list_area_size_change.begin(), + white_list_area_size_change.end(), client->role()) == white_list_area_size_change.end()) + { + HMI_ERROR("Application %s which has the role %s is not allowed to change area size", client->appID().c_str(), client->role().c_str()); + return; + } + + // Update + ret = this->lc->updateAreaList(areas); + if(ret != WMError::SUCCESS) + { + HMI_ERROR("%d : %s", ret, errorDescription(ret)); + return; + } + ret = this->lc->getUpdateAreaList(&areas); + areas.dump(); + if(ret != WMError::SUCCESS) + { + HMI_ERROR("%d : %s", ret, errorDescription(ret)); + return; + } + + // Create Action + unsigned req_num; + bool found = false; + ret = this->setRequest(client->appID(), client->role(), "-", Task::TASK_CHANGE_AREA, &req_num); // area is null + if(ret != WMError::SUCCESS) + { + HMI_SEQ_ERROR(req_num, "%d : %s", ret, errorDescription(ret)); + return; + } + for(const auto &update: areas.update_app2area) + { + // create action + auto client = g_app_list.lookUpClient(update.first); + if(client == nullptr) + { + HMI_SEQ_ERROR(req_num, "%s : %s", update.first.c_str(), errorDescription(ret)); + g_app_list.removeRequest(req_num); + this->processNextRequest(); + return; + } + ret = g_app_list.setAction(req_num, client, client->role(), update.second, TaskVisible::VISIBLE); + if(ret != WMError::SUCCESS) + { + HMI_SEQ_ERROR(req_num, "Failed to set request"); + return; + } + } + HMI_SEQ_INFO(req_num, "Area change request"); + g_app_list.reqDump(); + + // Request change size to applications + for(const auto &action : g_app_list.getActions(req_num, &found)) + { + struct rect r = this->lc->getAreaSize(action.area); + action.client->emitSyncDraw(action.area, r); + } +} + bool WindowManager::api_subscribe(afb_req_t req, EventType event_id) { bool ret = false; @@ -389,7 +494,7 @@ bool WindowManager::api_subscribe(afb_req_t req, EventType event_id) HMI_ERROR("not defined in Window Manager", event_id); return ret; } - HMI_INFO("%s subscribe %s : %d", appid, kListEventName[event_id], event_id); + HMI_INFO("%s subscribe %s : %d", appid, kListEventName[event_id].c_str(), event_id); if(event_id == Event_ScreenUpdated) { // Event_ScreenUpdated should be emitted to subscriber @@ -404,11 +509,15 @@ bool WindowManager::api_subscribe(afb_req_t req, EventType event_id) { string id = appid; free(appid); - auto client = g_app_list.lookUpClient(id); - if(client != nullptr) + if(!g_app_list.contains(id)) { - ret = client->subscribe(req, kListEventName[event_id]); + g_app_list.addClient(id); } + g_app_list.lookUpClient(id)->subscribe(req, kListEventName[event_id]); + } + else + { + HMI_ERROR("appid is not set"); } return ret; } @@ -602,6 +711,24 @@ void WindowManager::processError(WMError error) this->processNextRequest(); } +unsigned WindowManager::generateLayerForClient(const string& role) +{ + unsigned lid = this->lc->getNewLayerID(role); + if (lid == 0) + { + // register drawing_name as fallback and make it displayed. + lid = this->lc->getNewLayerID(string("fallback")); + HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role.c_str()); + if (lid == 0) + { + return lid; + } + } + this->lc->createNewLayer(lid); + // add client into the db + return lid; +} + WMError WindowManager::setRequest(const string& appid, const string &role, const string &area, Task task, unsigned* req_num) { @@ -707,7 +834,6 @@ WMError WindowManager::startTransition(unsigned req_num) for (const auto &x : actions) { this->lc->visibilityChange(x); - x.client->emitActive(false); x.client->emitVisible(false); } this->lc->renderLayers(); @@ -744,8 +870,6 @@ WMError WindowManager::doEndDraw(unsigned req_num) return ret; } ret = this->lc->visibilityChange(act); - - act.client->emitActive((act.visible == VISIBLE)); act.client->emitVisible((act.visible == VISIBLE)); if (ret != WMError::SUCCESS) @@ -802,7 +926,7 @@ void WindowManager::emitScreenUpdated(unsigned req_num) int ret = afb_event_push( this->map_afb_event[kListEventName[Event_ScreenUpdated]], j); - if (ret != 0) + if (ret < 0) { HMI_DEBUG("afb_event_push failed: %m"); }