diff options
author | Marius Vlad <marius.vlad@collabora.com> | 2021-02-15 17:50:30 +0200 |
---|---|---|
committer | Marius Vlad <marius.vlad@collabora.com> | 2021-03-03 16:50:07 +0200 |
commit | 31eeddf43beed3dd5f6b85eb8f8c2f3e46f3e34c (patch) | |
tree | b8f428e39d720187ea06f41fc65c3b31edc2d75e /src/hs-clientmanager.cpp | |
parent | 2101ce76906836e8337eacab5ee8ecff2cbcff9f (diff) |
hs-proxy,hs-clientmanager: Handle correctly the shutdown of apps
The fake subscribe mechanism failed to account for the client context,
which is bound to the afb_req_t of the client itself, and only
dealing with the client list. This effectively means we can't
really register (a/an automated) callback function to remove the
appid from the client list once the application has been legally
terminated/stopped.
This adds a check to verify, for the showWindow verb, if the application
is still found to be running, and return the appropriate value in case
that is not case. This should determine to start the application and fix
the issue.
Bug-AGL: SPEC-3796
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Change-Id: Ia828e1ec374bf3bed21c52814721074c01f16691
Diffstat (limited to 'src/hs-clientmanager.cpp')
-rw-r--r-- | src/hs-clientmanager.cpp | 59 |
1 files changed, 57 insertions, 2 deletions
diff --git a/src/hs-clientmanager.cpp b/src/hs-clientmanager.cpp index e880c62..8f02953 100644 --- a/src/hs-clientmanager.cpp +++ b/src/hs-clientmanager.cpp @@ -17,6 +17,8 @@ #include <cstring> #include <algorithm> +#include <cassert> +#include "hs-proxy.h" #include "hs-clientmanager.h" static const char _homescreen[] = "homescreen"; @@ -158,6 +160,46 @@ void HS_ClientManager::removeClientCtxt(void *data) appid2ctxt.erase(ctxt->id); } +static int +is_application_running(afb_req_t request, std::string id) +{ + bool app_still_running = false; + struct json_object *jobj = nullptr; + + HS_AfmMainProxy afm_proxy; + + // note this is sync, so this might block if afm-system-daemon is down + afm_proxy.ps(request->api, &jobj); + + if (jobj) { + const int len = json_object_array_length(jobj); + for (int i = 0; i < len; i++) { + struct json_object *aid; + struct json_object *item = + json_object_array_get_idx(jobj, i); + + bool isFound = json_object_object_get_ex(item, "id", &aid); + if (isFound) { + const char *str_appid = json_object_get_string(aid); + if (strcmp(str_appid, id.c_str()) == 0) { + app_still_running = true; + break; + } + } + } + } + + if (!app_still_running) { + // we don't remove it from the context list as we're haven't really subscribed, + // and we just need to remove it from client_list, which happens here. We also + // return AFB_REQ_NOT_STARTED_APPLICATION which will attempt to start it (again). + HS_ClientManager::instance()->removeClient(id); + return AFB_REQ_NOT_STARTED_APPLICATION; + } + + return 0; +} + /** * handle homescreen request * @@ -184,8 +226,21 @@ int HS_ClientManager::handleRequest(afb_req_t request, const char *verb, const c else { std::string id(appid); auto ip = client_list.find(id); - if(ip != client_list.end()) { - // FIXME: do another verification here in case the application died + if(ip != client_list.end()) { + // for showWindow verb we need to verify if the app is (still) + // running, and return the appropriate value to attempt to start it + // again. This 'problem' is avoided if the application itself + // subscribes and with that process, to install a callback that + // automatically removes the application from client_list. + // That is exactly how "subscribe" verb is handled below. + if (strcasecmp(verb, "showWindow") == 0) { + ret = is_application_running(request, id); + if (ret == AFB_REQ_NOT_STARTED_APPLICATION) { + AFB_INFO("%s is not running. Will attempt to start it"); + return ret; + } + } + AFB_INFO("%s found to be running. Forwarding request to the client"); ret = ip->second->handleRequest(request, verb); } else { |