From 7f59e030f1fb2bcd3fd767ed0c386a9a31852feb Mon Sep 17 00:00:00 2001 From: Kazumasa Mitsunari Date: Wed, 12 Sep 2018 21:12:30 +0900 Subject: Implement set_role TODO: Test * register_surface_xdg * set_role Next: * attachApp * setRenderOrder * moveSurface Signed-off-by: Kazumasa Mitsunari --- src/window_manager.cpp | 148 ++++++++++++++++++++++++++++++++++++++----------- src/window_manager.hpp | 14 +++-- 2 files changed, 127 insertions(+), 35 deletions(-) diff --git a/src/window_manager.cpp b/src/window_manager.cpp index 58ae4bc..4efae89 100644 --- a/src/window_manager.cpp +++ b/src/window_manager.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "window_manager.hpp" #include "json_helper.hpp" @@ -106,7 +107,7 @@ int WindowManager::init() // Load old_role.db LayerControlCallbacks lmcb; lmcb.surfaceCreated = [&](unsigned pid, unsigned surface){ - this->surface_created(surface); + this->surface_created(pid, surface); }; lmcb.surfaceDestroyed = [&](unsigned surface){ this->surface_removed(surface); @@ -182,7 +183,7 @@ result WindowManager::api_request_surface(char const *appid, char const *dr { // name does not exist yet, allocate surface id... auto id = int(this->id_alloc.generate_id(role)); - this->tmp_surface2app[id] = s_appid; + this->tmp_surface2app[id] = {s_appid, 0}; // Set role map of (new, old) this->rolenew2old[role] = string(drawing_name); @@ -259,29 +260,58 @@ char const *WindowManager::api_request_surface(char const *appid, char const *dr return nullptr; } -bool WindowManager::api_set_role(char const *appid, char const *drawing_name, unsigned pid){ - string id = appid; - string role = drawing_name; - string l_name; - unsigned surface = 0; - WMError wm_err = WMError::UNKNOWN; +bool WindowManager::api_set_role(char const *appid, char const *drawing_name, unsigned pid) +{ bool ret = false; - // get layer ID which role should be in - // auto lid = this->layers.get_layer_id(role); - unsigned lid = this->lc->getNewLayerID(role, &l_name); - if (lid == 0) + // TODO: application requests by old role, + // so convert role old to new + const char *role = this->convertRoleOldToNew(drawing_name); + string s_role = role; + string s_appid = appid; + string l_name; + + // Create WMClient + if(!g_app_list.contains(s_appid)) { - // lid = this->layers.get_layer_id(string("fallback")); - HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role.c_str()); - if (lid == 0) + // auto lid = this->layers.get_layer_id(string(role)); + unsigned l_id = this->lc->getNewLayerID(s_role, &l_name); + if (l_id == 0) { - HMI_ERROR("Drawing name does not match any role, fallback is disabled"); - return ret; + /** + * register drawing_name as fallback and make it displayed. + */ + l_id = this->lc->getNewLayerID("fallback", &l_name); + HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role); + if (l_id == 0) + { + HMI_ERROR("Designated role does not match any role, fallback is disabled"); + return ret; + } + } + this->lc->createNewLayer(l_id); + // add client into the db + g_app_list.addClient(s_appid, l_id, s_role); + // Set role map of (new, old) + this->rolenew2old[role] = s_role; + } + + for(auto itr = this->tmp_surface2app.begin(); + itr != this->tmp_surface2app.end() ; ++itr) + { + // const auto& x : this->tmp_surface2app) + if(itr->second.appid == s_appid) + { + unsigned surface = itr->first; + auto client = g_app_list.lookUpClient(s_appid); + client->addSurface(surface); + this->tmp_surface2app.erase(surface); + this->id_alloc.register_name_id(s_role, surface); + break; } } - if(0 != pid){ +/* if(0 != pid){ // search floating surfaceID from pid if pid is designated. wm_err = g_app_list.popFloatingSurface(pid, &surface); } @@ -309,15 +339,11 @@ bool WindowManager::api_set_role(char const *appid, char const *drawing_name, un HMI_INFO("Create new client: %s, surface: %d into layer: %d with role: %s", id.c_str(), surface, lid, role.c_str()); g_app_list.addClient(id, lid, role); - } + } */ // register pair drawing_name and ivi_id - this->id_alloc.register_name_id(role.c_str(), surface); - - // this surface is already created - HMI_DEBUG("surface_id is %u, layer_id is %u", surface, lid); - return ret; + return true; } void WindowManager::api_activate_surface(char const *appid, char const *drawing_name, @@ -557,15 +583,14 @@ void WindowManager::send_event(char const *evname, char const *label, char const /** * proxied events */ -void WindowManager::surface_created(uint32_t surface_id) +void WindowManager::surface_created(unsigned pid, unsigned surface_id) { if(this->tmp_surface2app.count(surface_id) != 0) { - string appid = this->tmp_surface2app[surface_id]; - this->tmp_surface2app.erase(surface_id); - if(g_app_list.contains(appid)) + string appid = this->tmp_surface2app[surface_id].appid; + auto client = g_app_list.lookUpClient(appid); + if(client != nullptr) { - auto client = g_app_list.lookUpClient(appid); WMError ret = client->addSurface(surface_id); HMI_INFO("Add surface %d to \"%s\"", surface_id, appid.c_str()); if(ret != WMError::SUCCESS) @@ -573,15 +598,76 @@ void WindowManager::surface_created(uint32_t surface_id) HMI_ERROR("Failed to add surface to client %s", client->appID().c_str()); } } + this->tmp_surface2app.erase(surface_id); } else { HMI_NOTICE("Unknown surface %d", surface_id); - this->tmp_surface2app[surface_id] = ""; /* Store for requestSurfaceXDG */ + // retrieve ppid + std::ostringstream os; + os << pid ; + string path = "/proc/" + os.str() + "/stat"; + std::ifstream ifs(path.c_str()); + string str; + unsigned ppid = 0; + if(!ifs.fail() && std::getline(ifs, str)) + { + std::sscanf(str.data(), "%*d %*s %*c %*d %d", &ppid); + HMI_INFO("Retrieve ppid %d", ppid); + } + else + { + HMI_ERROR("Failed to open /proc/%d/stat", pid); + HMI_ERROR("File system may be different"); + return; + } + // search pid from surfaceID + json_object *response; + afb_service_call_sync("afm-main", "runners", nullptr, &response); + + // retrieve appid from pid from application manager + string appid = ""; + if(response == nullptr) + { + HMI_ERROR("No runners"); + } + else + { + // check appid then add it to the client + HMI_INFO("Runners:%s", json_object_get_string(response)); + int size = json_object_array_length(response); + for(int i = 0; i < size; i++) + { + json_object *j = json_object_array_get_idx(response, i); + const char* id = jh::getStringFromJson(j, "id"); + int runid = jh::getIntFromJson(j, "runid"); + if(id && (runid > 0)) + { + if(runid == ppid) + { + appid = id; + break; + } + } + } + if(appid == "") + { + HMI_ERROR("Not found"); + } + } + json_object_put(response); + auto client = g_app_list.lookUpClient(appid); + if(client != nullptr) + { + client->addSurface(surface_id); + this->id_alloc.register_name_id(client->role(), surface_id); + } + struct TmpClient tmp_cl = {appid, ppid}; + this->tmp_surface2app[surface_id] = tmp_cl; /* Store for requestSurfaceXDG */ } } -void WindowManager::surface_removed(uint32_t surface_id) +void WindowManager::surface_removed(unsigned surface_id) { HMI_DEBUG("Delete surface_id %u", surface_id); this->id_alloc.remove_id(surface_id); diff --git a/src/window_manager.hpp b/src/window_manager.hpp index 546e771..6527736 100644 --- a/src/window_manager.hpp +++ b/src/window_manager.hpp @@ -129,6 +129,12 @@ struct id_allocator } }; +struct TmpClient +{ + std::string appid; + unsigned pid; +}; + class WindowManager { public: @@ -177,8 +183,8 @@ class WindowManager void send_event(char const *evname, char const *label, char const *area, int x, int y, int w, int h); // Events from the compositor we are interested in - void surface_created(uint32_t surface_id); - void surface_removed(uint32_t surface_id); + void surface_created(unsigned pid, unsigned surface_id); + void surface_removed(unsigned surface_id); void removeClient(const std::string &appid); void exceptionProcessForTransition(); @@ -240,8 +246,8 @@ class WindowManager // Surface are info (x, y, w, h) rect_map area_info; // FOR CES DEMO - std::unordered_map tmp_surface2app; - + std::unordered_map tmp_surface2app; + std::vector tmp_apps; static const char* kDefaultOldRoleDb; }; -- cgit 1.2.3-korg