diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/hs-clientmanager.cpp | 1 | ||||
-rw-r--r-- | src/hs-proxy.cpp | 62 |
2 files changed, 60 insertions, 3 deletions
diff --git a/src/hs-clientmanager.cpp b/src/hs-clientmanager.cpp index 7c2adc5..beac816 100644 --- a/src/hs-clientmanager.cpp +++ b/src/hs-clientmanager.cpp @@ -184,6 +184,7 @@ int HS_ClientManager::handleRequest(afb_req_t request, const char *verb, const c 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 ret = ip->second->handleRequest(request, verb); } else { diff --git a/src/hs-proxy.cpp b/src/hs-proxy.cpp index a7236b4..33e5d53 100644 --- a/src/hs-proxy.cpp +++ b/src/hs-proxy.cpp @@ -17,6 +17,12 @@ #include "homescreen.h" #include "hs-proxy.h" +struct closure_data { + std::string appid; + HS_ClientCtxt *clientCtx; + struct hs_instance *hs_instance; +}; + const char _afm_main[] = "afm-main"; @@ -37,6 +43,24 @@ const char _afm_main[] = "afm-main"; static void api_callback(void *closure, struct json_object *object, const char *error, const char *info, afb_api_t api) { AFB_INFO("asynchronous call, error=%s, info=%s, object=%s.", error, info, json_object_get_string(object)); + struct closure_data *cdata = static_cast<struct closure_data *>(closure); + + if (!cdata->hs_instance) { + return; + } + + struct HS_ClientManager *clientManager = cdata->hs_instance->client_manager; + if (!clientManager) { + return; + } + + /* if we have an error then we couldn't start the application so we remove it */ + if (error) { + clientManager->removeClientCtxt(cdata->clientCtx); + clientManager->removeClient(cdata->appid); + } + + free(cdata); } /** @@ -52,10 +76,10 @@ static void api_callback(void *closure, struct json_object *object, const char * * None * */ -static void api_call(afb_api_t api, const char *service, const char *verb, struct json_object *args) +static void api_call(afb_api_t api, const char *service, const char *verb, struct json_object *args, struct closure_data *cdata) { AFB_INFO("service=%s verb=%s, args=%s.", service, verb, json_object_get_string(args)); - afb_api_call(api, service, verb, args, api_callback, nullptr); + afb_api_call(api, service, verb, args, api_callback, cdata); } /** @@ -131,5 +155,37 @@ int HS_AfmMainProxy::detail(afb_api_t api, const std::string &id, struct json_ob void HS_AfmMainProxy::start(struct hs_instance *instance, afb_req_t request, const std::string &id) { struct json_object *args = json_object_new_string(id.c_str()); - api_call(request->api, _afm_main, __FUNCTION__, args); + struct closure_data *cdata; + + /* tentatively store the client and client context, as the afb_req_t + * request will no longer be available in the async callback handler. This + * is similar to that is done showWindow(), handleRequest() in + * homescreen.cpp, but allows to fake the subscription here as well to + * avoid clients create/install dummy event handlers as to 'register' (or + * to keep track of applications started). + * + * In case api_callback() does return an error we'll remove then the client + * and client context there. We pass the closure_data with the client context + * and the application id to remove it. + */ + if (!instance) + return; + + cdata = static_cast<struct closure_data *>(calloc(1, sizeof(*cdata))); + cdata->hs_instance = instance; + cdata->appid = id; + + struct HS_ClientManager *clientManager = instance->client_manager; + if (!clientManager) { + return; + } + + cdata->clientCtx = clientManager->createClientCtxt(request, id); + HS_Client *client = clientManager->addClient(request, id); + if (client) { + if (client->handleRequest(request, "subscribe")) + AFB_WARNING("Failed to handle subcribe\n"); + } + + api_call(request->api, _afm_main, __FUNCTION__, args, cdata); } |