diff options
author | José Bollo <jose.bollo@iot.bzh> | 2016-11-14 11:43:46 +0100 |
---|---|---|
committer | José Bollo <jose.bollo@iot.bzh> | 2016-11-14 13:54:22 +0100 |
commit | a1f7f7d2cd79c9391368d0c017452566a5edc44c (patch) | |
tree | e1f507900d7526fec3a3cf3c73671d8260045ad4 | |
parent | b6ac54640c918aecaf2f28edf82f8217154b12f3 (diff) |
afm-user-daemon: Adds method "once"
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 <jose.bollo@iot.bzh>
-rw-r--r-- | docs/afm-user-daemon.md | 26 | ||||
-rwxr-xr-x | scripts/afm-util | 7 | ||||
-rw-r--r-- | src/afm-main-binding.c | 7 | ||||
-rw-r--r-- | src/afm-run.c | 36 | ||||
-rw-r--r-- | src/afm-run.h | 1 | ||||
-rw-r--r-- | src/afm-user-daemon.c | 38 | ||||
-rw-r--r-- | 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 @@ -248,6 +248,25 @@ static struct apprun *getrunner(int runid) } /* + * 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' */ static void freerunner(struct apprun *runner) @@ -593,6 +612,23 @@ int afm_run_start(struct json_object *appli, enum afm_launch_mode mode, } /* + * 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' * * Returns 0 in case of success or -1 in case of error 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'. */ @@ -254,6 +253,42 @@ static void on_start(struct sd_bus_message *smsg, struct json_object *obj, void } /* + * 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'. */ static void on_pause(struct sd_bus_message *smsg, struct json_object *obj, void *unused) @@ -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 @@ <arg name="in" type="s" direction="in"/> <arg name="out" type="s" direction="out"/> </method> + <method name="once"> + <arg name="in" type="s" direction="in"/> + <arg name="out" type="s" direction="out"/> + </method> <method name="terminate"> <arg name="in" type="s" direction="in"/> <arg name="out" type="s" direction="out"/> |