afm-user-daemon: Adds method "once"
authorJosé Bollo <jose.bollo@iot.bzh>
Mon, 14 Nov 2016 10:43:46 +0000 (11:43 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Mon, 14 Nov 2016 12:54:22 +0000 (13:54 +0100)
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>
docs/afm-user-daemon.md
scripts/afm-util
src/afm-main-binding.c
src/afm-run.c
src/afm-run.h
src/afm-user-daemon.c
src/afm-user-daemon.xml

index cb54b10..37cf0e4 100644 (file)
@@ -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*.
index 243b43c..eb800d9 100755 (executable)
@@ -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
 
index 5141888..e8e08db 100644 (file)
@@ -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"},
index 537ba62..f4f55e5 100644 (file)
@@ -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'
  *
index 6e3469a..00ea4e8 100644 (file)
@@ -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);
index e71e011..d4a9558 100644 (file)
@@ -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)
index 772e45d..48ff7cd 100644 (file)
       <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"/>