From 869c528ee82fc8c2e2877d67521e26c3a2ca47ca Mon Sep 17 00:00:00 2001 From: Kazumasa Mitsunari Date: Fri, 22 Dec 2017 12:28:21 +0900 Subject: [PATCH] Enable an application re-launch When an application dies after requestSurface, the application can't be launched because Window Manager doesn't know the application is dead and doesn't clean up its database. In other case, when Mixer app dies due to pulse audio crash just before Window Manager handles surface memory, the connection between weston and Window Manager is dead. So add following * Add context setting with window manager clients. Terminate the context and clean up WM database if a client application is dead. * Add layout_commit() after add surfaces to layer. [PatchSet 2] * Add layout_commit() after add surfaces to layer in api_request_surface Bug-AGL: SPEC-1086 Change-Id: I6ecae2606ac644e49a3383ba849390f8c235f187 Signed-off-by: Kazumasa Mitsunari --- src/app.cpp | 3 ++- src/main.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/app.cpp b/src/app.cpp index 74a114d..337b0ac 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -629,7 +629,7 @@ void App::surface_created(uint32_t surface_id) { this->controller->layers[*layer_id]->add_surface( this->controller->surfaces[surface_id].get()); - + this->layout_commit(); // activate the main_surface right away /*if (surface_id == static_cast(this->layers.main_surface)) { HMI_DEBUG("wm", "Activating main_surface (%d)", surface_id); @@ -736,6 +736,7 @@ char const *App::api_request_surface(char const *drawing_name, this->controller->layers[*lid]->add_surface( this->controller->surfaces[sid].get()); + this->layout_commit(); return nullptr; } diff --git a/src/main.cpp b/src/main.cpp index e8ae75a..0197c3c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,6 +30,13 @@ extern "C" { #include } +typedef struct wmClientCtxt{ + std::string name; + wmClientCtxt(const char* appName){ + name = appName; + } +} wmClientCtxt; + struct afb_instance { std::unique_ptr display; wm::App app; @@ -149,6 +156,30 @@ int binding_init() noexcept { return -1; } +static bool checkFirstReq(afb_req req){ + wmClientCtxt* ctxt = (wmClientCtxt*)afb_req_context_get(req); + return (ctxt) ? false : true; +} + +static void cbRemoveClientCtxt(void* data){ + wmClientCtxt* ctxt = (wmClientCtxt*)data; + if(ctxt == nullptr){ + return; + } + HMI_DEBUG("wm","remove app %s", ctxt->name.c_str()); + // Lookup surfaceID and remove it because App is dead. + auto pSid = g_afb_instance->app.id_alloc.lookup(ctxt->name.c_str()); + if(pSid){ + auto sid = *pSid; + g_afb_instance->app.id_alloc.remove_id(sid); + g_afb_instance->app.layers.remove_surface(sid); + g_afb_instance->app.controller->sprops.erase(sid); + g_afb_instance->app.controller->surfaces.erase(sid); + HMI_DEBUG("wm", "delete surfaceID %d", sid); + } + delete ctxt; +} + void windowmanager_requestsurface(afb_req req) noexcept { std::lock_guard guard(binding_m); #ifdef ST @@ -166,7 +197,30 @@ void windowmanager_requestsurface(afb_req req) noexcept { return; } + /* Create Security Context */ + bool isFirstReq = checkFirstReq(req); + if(!isFirstReq){ + wmClientCtxt* ctxt = (wmClientCtxt*)afb_req_context_get(req); + HMI_DEBUG("wm", "You're %s.", ctxt->name.c_str()); + if(ctxt->name != std::string(a_drawing_name)){ + afb_req_fail_f(req, "failed", "Dont request with other name: %s for now", a_drawing_name); + HMI_DEBUG("wm", "Don't request with other name: %s for now", a_drawing_name); + return; + } + } + auto ret = g_afb_instance->app.api_request_surface(a_drawing_name); + + if(isFirstReq){ + wmClientCtxt* ctxt = new wmClientCtxt(a_drawing_name); + HMI_DEBUG("wm", "create session for %s", ctxt->name.c_str()); + afb_req_session_set_LOA(req, 1); + afb_req_context_set(req, ctxt, cbRemoveClientCtxt); + } + else{ + HMI_DEBUG("wm", "session already created for %s", a_drawing_name); + } + if (ret.is_err()) { afb_req_fail(req, "failed", ret.unwrap_err()); return; -- 2.16.6