From a1f7f7d2cd79c9391368d0c017452566a5edc44c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Bollo?= Date: Mon, 14 Nov 2016 11:43:46 +0100 Subject: [PATCH] afm-user-daemon: Adds method "once" MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Adds the method "once" that is intended to start an application in local mode if it doesn't already run. Returns the state of the running application. Change-Id: I4dfff06fa2d3e95f13a2436a2f1af9174799ddcf Signed-off-by: José Bollo --- docs/afm-user-daemon.md | 26 +++++++++++++++++++++++++- scripts/afm-util | 7 +++++++ src/afm-main-binding.c | 7 +++++++ src/afm-run.c | 36 ++++++++++++++++++++++++++++++++++++ src/afm-run.h | 1 + src/afm-user-daemon.c | 38 +++++++++++++++++++++++++++++++++++++- src/afm-user-daemon.xml | 4 ++++ 7 files changed, 117 insertions(+), 2 deletions(-) diff --git a/docs/afm-user-daemon.md b/docs/afm-user-daemon.md index cb54b10..37cf0e4 100644 --- a/docs/afm-user-daemon.md +++ b/docs/afm-user-daemon.md @@ -398,7 +398,7 @@ user sessions. The **afm-user-daemon** is listening on destination name ***org.AGL.afm.user*** at object path ***/org/AGL/afm/user*** on interface ***org.AGL.afm.user*** for following members: - ***runnables***, ***detail***, ***start***, ***terminate***, + ***runnables***, ***detail***, ***start***, ***once***, ***terminate***, ***pause***, ***resume***, ***runners***, ***state***, ***install*** and ***uninstall***. @@ -464,6 +464,10 @@ Here is the summary of ***afm-util***: start an instance of the widget of id + - **afm-util once id **: + + run once an instance of the widget of id + - **afm-util terminate rid **: terminate the running instance rid @@ -634,6 +638,26 @@ The field "mode" is a string equal to either "local" or "remote". --- +#### Method org.AGL.afm.user.once + +**Description**: + +**Input**: the *id* of the application + +Either just a string: + + "appli@x.y" + +Or an object containing field "id" of type string. + + {"id":"appli@x.y"} + +**output**: The *state* of the application retrieved or launched. +See *org.AGL.afm.user.state* to get a description of the returned +object. + +--- + #### Method org.AGL.afm.user.terminate **Description**: Terminates the application attached to *runid*. diff --git a/scripts/afm-util b/scripts/afm-util index 243b43c..eb800d9 100755 --- a/scripts/afm-util +++ b/scripts/afm-util @@ -52,6 +52,11 @@ case "$1" in send start "\"$i\"" ;; + once) + i=$2 + send once "\"$i\"" + ;; + terminate|kill) i=$2 send terminate "$i" @@ -96,6 +101,8 @@ The commands are: run id start id start an instance of the widget of id + once id run once an instance of the widget of id + kill rid terminate rid terminate the running instance rid diff --git a/src/afm-main-binding.c b/src/afm-main-binding.c index 5141888..e8e08db 100644 --- a/src/afm-main-binding.c +++ b/src/afm-main-binding.c @@ -34,6 +34,7 @@ static const char _id_[] = "id"; static const char _install_[] = "install"; static const char _local_[] = "local"; static const char _mode_[] = "mode"; +static const char _once_[] = "once"; static const char _pause_[] = "pause"; static const char _remote_[] = "remote"; static const char _resume_[] = "resume"; @@ -294,6 +295,11 @@ static void start(struct afb_req request) free(query); } +static void once(struct afb_req request) +{ + call_appid(request, _once_); +} + static void terminate(struct afb_req request) { call_runid(request, _terminate_); @@ -375,6 +381,7 @@ static const struct afb_verb_desc_v1 verbs[] = {_runnables_, AFB_SESSION_CHECK, runnables, "Get list of runnable applications"}, {_detail_ , AFB_SESSION_CHECK, detail, "Get the details for one application"}, {_start_ , AFB_SESSION_CHECK, start, "Start an application"}, + {_once_ , AFB_SESSION_CHECK, once, "Start once an application"}, {_terminate_, AFB_SESSION_CHECK, terminate, "Terminate a running application"}, {_pause_ , AFB_SESSION_CHECK, pause, "Pause a running application"}, {_resume_ , AFB_SESSION_CHECK, resume, "Resume a paused application"}, diff --git a/src/afm-run.c b/src/afm-run.c index 537ba62..f4f55e5 100644 --- a/src/afm-run.c +++ b/src/afm-run.c @@ -247,6 +247,25 @@ static struct apprun *getrunner(int runid) return result; } +/* + * Get first runner of 'appli' (NULL if not found) + */ +static struct apprun *getrunner_appli(json_object *appli) +{ + int i; + struct apprun *result; + + for (i = 0 ; i < ROOT_RUNNERS_COUNT ; i++) { + result = runners_by_pgid[i]; + while (result != NULL) { + if (result->appli == appli) + return result; + result = result->next_by_pgid; + } + } + return NULL; +} + /* * Free an existing 'runner' */ @@ -592,6 +611,23 @@ int afm_run_start(struct json_object *appli, enum afm_launch_mode mode, return rc; } +/* + * Returns the runid of a previously started application 'appli' + * or if none is running, starts the application described by 'appli' + * in local mode. + * + * A reference to 'appli' is kept during the live of the + * runner. This is made using json_object_get. Thus be aware + * that further modifications to 'appli' might create errors. + * + * Returns the runid in case of success or -1 in case of error + */ +int afm_run_once(struct json_object *appli) +{ + struct apprun *runner = getrunner_appli(appli); + return runner && is_alive(runner) ? runner->runid : afm_run_start(appli, mode_local, NULL); +} + /* * Terminates the runner of 'runid' * diff --git a/src/afm-run.h b/src/afm-run.h index 6e3469a..00ea4e8 100644 --- a/src/afm-run.h +++ b/src/afm-run.h @@ -17,6 +17,7 @@ */ extern int afm_run_start(struct json_object *appli, enum afm_launch_mode mode, char **uri); +extern int afm_run_once(struct json_object *appli); extern int afm_run_terminate(int runid); extern int afm_run_pause(int runid); extern int afm_run_resume(int runid); diff --git a/src/afm-user-daemon.c b/src/afm-user-daemon.c index e71e011..d4a9558 100644 --- a/src/afm-user-daemon.c +++ b/src/afm-user-daemon.c @@ -185,7 +185,6 @@ static void on_detail(struct sd_bus_message *smsg, struct json_object *obj, void json_object_put(resp); } - /* * On query "start" from 'smsg' with parameters of 'obj'. */ @@ -253,6 +252,42 @@ static void on_start(struct sd_bus_message *smsg, struct json_object *obj, void free(uri); } +/* + * On query "once" from 'smsg' with parameters of 'obj'. + */ +static void on_once(struct sd_bus_message *smsg, struct json_object *obj, void *unused) +{ + const char *appid; + struct json_object *appli, *resp; + int runid; + + /* get the parameters */ + if (!j_read_string(obj, &appid) && !j_read_string_at(obj, "id", &appid)) { + jbus_reply_error_s(smsg, error_bad_request); + return; + } + + /* get the application */ + INFO("method once called for %s", appid); + appli = afm_db_get_application(afdb, appid); + if (appli == NULL) { + jbus_reply_error_s(smsg, error_not_found); + return; + } + + /* launch the application */ + runid = afm_run_once(appli); + if (runid <= 0) { + jbus_reply_error_s(smsg, error_cant_start); + return; + } + + /* returns the state */ + resp = afm_run_state(runid); + reply(smsg, resp, error_not_found); + json_object_put(resp); +} + /* * On query "pause" from 'smsg' with parameters of 'obj'. */ @@ -600,6 +635,7 @@ int main(int ac, char **av) if (jbus_add_service_j(user_bus, "runnables", on_runnables, NULL) || jbus_add_service_j(user_bus, "detail", on_detail, NULL) || jbus_add_service_j(user_bus, "start", on_start, NULL) + || jbus_add_service_j(user_bus, "once", on_once, NULL) || jbus_add_service_j(user_bus, "terminate", on_terminate, NULL) || jbus_add_service_j(user_bus, "pause", on_pause, NULL) || jbus_add_service_j(user_bus, "resume", on_resume, NULL) diff --git a/src/afm-user-daemon.xml b/src/afm-user-daemon.xml index 772e45d..48ff7cd 100644 --- a/src/afm-user-daemon.xml +++ b/src/afm-user-daemon.xml @@ -13,6 +13,10 @@ + + + + -- 2.16.6