aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Bollo <jose.bollo@iot.bzh>2016-11-14 11:43:46 +0100
committerJosé Bollo <jose.bollo@iot.bzh>2016-11-14 13:54:22 +0100
commita1f7f7d2cd79c9391368d0c017452566a5edc44c (patch)
treee1f507900d7526fec3a3cf3c73671d8260045ad4
parentb6ac54640c918aecaf2f28edf82f8217154b12f3 (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.md26
-rwxr-xr-xscripts/afm-util7
-rw-r--r--src/afm-main-binding.c7
-rw-r--r--src/afm-run.c36
-rw-r--r--src/afm-run.h1
-rw-r--r--src/afm-user-daemon.c38
-rw-r--r--src/afm-user-daemon.xml4
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"/>