Add ability to manage all widget/applications 61/20761/1
authorJosé Bollo <jose.bollo@iot.bzh>
Tue, 19 Mar 2019 22:21:35 +0000 (23:21 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Thu, 21 Mar 2019 09:47:35 +0000 (10:47 +0100)
For system uses -like automatic testing-, it is
needed to include tha ability to list ALL installed
widgets and ALL running instance of installed
widgets.

This change adds the option -a or --all to the
commands 'list' and 'runners' for the purpose
of listing any installed widgets, even those
requiring to be hidden.

Example: afm-util ps -a

Bug-AGL: SPEC-2272
Bug-AGL: SPEC-1850

Change-Id: I216ec9c63efea1b3af58e1d2d7723d986e04551e
Signed-off-by: Jose Bollo <jose.bollo@iot.bzh>
conf/unit/afm-unit-debug.conf.in
conf/unit/afm-unit.conf.in
conf/unit/generate-unit-conf/service.inc
scripts/afm-util.in
src/afm-binding.c
src/afm-udb.c
src/afm-udb.h
src/afm-urun.c
src/afm-urun.h

index 49eb826..0042d3e 100644 (file)
@@ -104,6 +104,7 @@ X-AFM--content={{content.src}}
 X-AFM--type={{content.type}}
 X-AFM--wgtdir={{:#metadata.install-dir}}
 X-AFM--workdir=/home/%i/app-data/{{:id}}
+X-AFM--visibility={{#required-permission.urn:AGL:permission::public:hidden}}hidden{{/required-permission.urn:AGL:permission::public:hidden}}{{^required-permission.urn:AGL:permission::public:hidden}}visible{{/required-permission.urn:AGL:permission::public:hidden}}
 %nl
 Requires=afm-user-session@%i.target
 After=user@%i.service
index 50fd957..09befb6 100644 (file)
@@ -104,6 +104,7 @@ X-AFM--content={{content.src}}
 X-AFM--type={{content.type}}
 X-AFM--wgtdir={{:#metadata.install-dir}}
 X-AFM--workdir=/home/%i/app-data/{{:id}}
+X-AFM--visibility={{#required-permission.urn:AGL:permission::public:hidden}}hidden{{/required-permission.urn:AGL:permission::public:hidden}}{{^required-permission.urn:AGL:permission::public:hidden}}visible{{/required-permission.urn:AGL:permission::public:hidden}}
 %nl
 Requires=afm-user-session@%i.target
 After=user@%i.service
index 961a262..6620243 100644 (file)
@@ -30,6 +30,7 @@ X-AFM--content={{content.src}}
 X-AFM--type={{content.type}}
 X-AFM--wgtdir={{:#metadata.install-dir}}
 X-AFM--workdir=APP_DATA_DIR/{{:id}}
+X-AFM--visibility=ON_PERM(`:public:hidden', `hidden', `visible')
 %nl
 
 Requires=afm-user-session@%i.target
index 3f47d97..978f000 100755 (executable)
@@ -5,10 +5,17 @@ send() {
        awk '$1=="ON-REPLY" && $3!="success"{$1="ERROR:";$2="";print > "/dev/stderr";exit 1;}NR>1'
 }
 
+getall() {
+  case "$1" in
+    -a|--all) echo -n '{"all":true}';;
+    *) echo -n true;;
+  esac
+}
+
 case "$1" in
 
   list|runnables)
-    send runnables true
+    send runnables $(getall $2)
     ;;
 
   add|install)
@@ -29,7 +36,7 @@ case "$1" in
     ;;
 
   ps|runners)
-    send runners true
+    send runners  $(getall $2)
     ;;
 
   run|start)
@@ -75,6 +82,7 @@ The commands are:
 
   list
   runnables      list the runnable widgets installed
+                 option -a or --all for all instances
 
   add wgt
   install wgt    install the wgt file
@@ -87,6 +95,7 @@ The commands are:
 
   ps
   runners        list the running instance
+                 option -a or --all for all instances
 
   run id
   start id       start an instance of the widget of id
index 42d2baa..7716dec 100644 (file)
@@ -41,6 +41,7 @@
  * constant strings
  */
 static const char _added_[]     = "added";
+static const char _all_[]       = "all";
 static const char _a_l_c_[]     = "application-list-changed";
 static const char _bad_request_[] = "bad-request";
 static const char _cannot_start_[] = "cannot-start";
@@ -226,6 +227,18 @@ static const char *get_lang(afb_req_t req)
        return lang;
 }
 
+/*
+ * Retrieve whether all is required from 'req'.
+ */
+static int get_all(afb_req_t req)
+{
+       struct json_object *val;
+
+       /* get the optional language */
+       return json_object_object_get_ex(afb_req_json(req), _all_, &val)
+               && json_object_get_boolean(val);
+}
+
 
 /*
  * retrieves the 'appid' in parameters received with the
@@ -328,14 +341,18 @@ static void reply_status(afb_req_t req, int status)
  */
 static void runnables(afb_req_t req)
 {
+       int all;
        const char *lang;
        struct json_object *resp;
 
        /* get the language */
        lang = get_lang(req);
 
+       /* get the all */
+       all = get_all(req);
+
        /* get the details */
-       resp = afm_udb_applications_public(afudb, afb_req_get_uid(req), lang);
+       resp = afm_udb_applications_public(afudb, all, afb_req_get_uid(req), lang);
        afb_req_success(req, resp, NULL);
 }
 
@@ -473,8 +490,10 @@ static void terminate(afb_req_t req)
  */
 static void runners(afb_req_t req)
 {
+       int all;
        struct json_object *resp;
-       resp = afm_urun_list(afudb, afb_req_get_uid(req));
+       all = get_all(req);
+       resp = afm_urun_list(afudb, all, afb_req_get_uid(req));
        afb_req_success(req, resp, NULL);
 }
 
@@ -585,7 +604,7 @@ static int init(afb_api_t api)
        json_true = json_object_new_boolean(1);
 
        /* init database */
-       afudb = afm_udb_create(1, 0, "afm-appli-");
+       afudb = afm_udb_create(1, 0, "afm-");
        if (!afudb) {
                ERROR("afm_udb_create failed");
                return -1;
index 221bc11..d804704 100644 (file)
@@ -42,6 +42,8 @@ static const char key_unit_scope[] = "-unit-scope";
 static const char scope_user[] = "user";
 static const char scope_system[] = "system";
 static const char key_id[] = "id";
+static const char key_visibility[] = "visibility";
+static const char value_visible[] = "visible";
 
 #define x_afm_prefix_length  (sizeof x_afm_prefix - 1)
 #define service_extension_length  (sizeof service_extension - 1)
@@ -51,10 +53,11 @@ static const char key_id[] = "id";
  * for several accesses.
  */
 struct afm_apps {
-       struct json_object *prvarr; /* array of the private data of apps */
-       struct json_object *pubarr; /* array of the public data of apps */
-       struct json_object *pubobj; /* hash of application's publics */
-       struct json_object *prvobj; /* hash of application's privates */
+       struct {
+               struct json_object *visibles; /* array of the private data of visible apps */
+               struct json_object *all; /* array of the private data of all apps */
+               struct json_object *byname; /* hash of application's privates */
+       } privates, publics;
 };
 
 /*
@@ -83,15 +86,39 @@ struct afm_updt {
  */
 static char *default_lang;
 
+/*
+ * initilize object 'apps'.
+ * returns 1 if okay or 0 on case of memory depletion
+ */
+static int apps_init(struct afm_apps *apps)
+{
+       apps->publics.all = json_object_new_array();
+       apps->publics.visibles = json_object_new_array();
+       apps->publics.byname = json_object_new_object();
+
+       apps->privates.all = json_object_new_array();
+       apps->privates.visibles = json_object_new_array();
+       apps->privates.byname = json_object_new_object();
+
+       return apps->publics.all
+          && apps->publics.visibles
+          && apps->publics.byname
+          && apps->privates.all
+          && apps->privates.visibles
+          && apps->privates.byname;
+}
+
 /*
  * Release the data of the afm_apps object 'apps'.
  */
 static void apps_put(struct afm_apps *apps)
 {
-       json_object_put(apps->prvarr);
-       json_object_put(apps->pubarr);
-       json_object_put(apps->pubobj);
-       json_object_put(apps->prvobj);
+       json_object_put(apps->publics.all);
+       json_object_put(apps->publics.visibles);
+       json_object_put(apps->publics.byname);
+       json_object_put(apps->privates.all);
+       json_object_put(apps->privates.visibles);
+       json_object_put(apps->privates.byname);
 }
 
 /*
@@ -161,8 +188,10 @@ static int add_field(
 
        /* add the value */
        if (name[0] == '-') {
+               /* private value */
                append_field(priv, &name[1], v);
        } else {
+               /* public value */
                append_field(priv, name, json_object_get(v));
                append_field(pub, name, v);
        }
@@ -236,7 +265,7 @@ static int addunit(
                size_t length
 )
 {
-       struct json_object *priv, *pub, *id;
+       struct json_object *priv, *pub, *id, *visi;
        const char *strid;
        size_t len;
 
@@ -270,11 +299,19 @@ static int addunit(
 
        /* record the application structure */
        json_object_get(pub);
-       json_object_array_add(apps->pubarr, pub);
-       json_object_object_add(apps->pubobj, strid, pub);
+       json_object_array_add(apps->publics.all, pub);
+       json_object_object_add(apps->publics.byname, strid, pub);
        json_object_get(priv);
-       json_object_array_add(apps->prvarr, priv);
-       json_object_object_add(apps->prvobj, strid, priv);
+       json_object_array_add(apps->privates.all, priv);
+       json_object_object_add(apps->privates.byname, strid, priv);
+
+       /* handle visibility */
+       if (json_object_object_get_ex(priv, key_visibility, &visi)
+               && !strcasecmp(json_object_get_string(visi), value_visible)) {
+               json_object_array_add(apps->publics.visibles, json_object_get(pub));
+               json_object_array_add(apps->privates.visibles, json_object_get(priv));
+       }
+
        return 0;
 
 error:
@@ -406,10 +443,7 @@ struct afm_udb *afm_udb_create(int sys, int usr, const char *prefix)
                errno = ENOMEM;
        else {
                afudb->refcount = 1;
-               afudb->applications.prvarr = NULL;
-               afudb->applications.pubarr = NULL;
-               afudb->applications.pubobj = NULL;
-               afudb->applications.prvobj = NULL;
+               memset(&afudb->applications, 0, sizeof afudb->applications);
                afudb->system = sys;
                afudb->user = usr;
                afudb->prefixlen = length;
@@ -456,43 +490,33 @@ int afm_udb_update(struct afm_udb *afudb)
 {
        struct afm_updt updt;
        struct afm_apps tmp;
+       int result;
 
        /* lock the db */
        afm_udb_addref(afudb);
        updt.afudb = afudb;
 
-       /* create the result */
-       updt.applications.prvarr = json_object_new_array();
-       updt.applications.pubarr = json_object_new_array();
-       updt.applications.pubobj = json_object_new_object();
-       updt.applications.prvobj = json_object_new_object();
-       if (updt.applications.pubarr == NULL
-        || updt.applications.prvarr == NULL
-        || updt.applications.pubobj == NULL
-        || updt.applications.prvobj == NULL) {
-               errno = ENOMEM;
-               goto error;
+       /* create the apps */
+       if (!apps_init(&updt.applications))
+               result = -1;
+       else {
+               /* scan the units */
+               if (afudb->user && systemd_unit_list(1, update_cb, &updt) < 0)
+                       result = -1;
+               else if (afudb->system && systemd_unit_list(0, update_cb, &updt) < 0)
+                       result = -1;
+               else {
+                       /* commit the result */
+                       tmp = afudb->applications;
+                       afudb->applications = updt.applications;
+                       updt.applications = tmp;
+                       result = 0;
+               }
+               apps_put(&updt.applications);
        }
-
-       /* scan the units */
-       if (afudb->user)
-               if (systemd_unit_list(1, update_cb, &updt) < 0)
-                       goto error;
-       if (afudb->system)
-               if (systemd_unit_list(0, update_cb, &updt) < 0)
-                       goto error;
-
-       /* commit the result */
-       tmp = afudb->applications;
-       afudb->applications = updt.applications;
-       apps_put(&tmp);
+       /* unlock the db and return status */
        afm_udb_unref(afudb);
-       return 0;
-
-error:
-       apps_put(&updt.applications);
-       afm_udb_unref(afudb);
-       return -1;
+       return result;
 }
 
 /*
@@ -511,9 +535,9 @@ void afm_udb_set_default_lang(const char *lang)
  * 'json_object_put'.
  * Returns NULL in case of error.
  */
-struct json_object *afm_udb_applications_private(struct afm_udb *afudb, int uid)
+struct json_object *afm_udb_applications_private(struct afm_udb *afudb, int all, int uid)
 {
-       return json_object_get(afudb->applications.prvarr);
+       return json_object_get(all ? afudb->applications.privates.all : afudb->applications.privates.visibles);
 }
 
 /*
@@ -522,9 +546,9 @@ struct json_object *afm_udb_applications_private(struct afm_udb *afudb, int uid)
  * 'json_object_put'.
  * Returns NULL in case of error.
  */
-struct json_object *afm_udb_applications_public(struct afm_udb *afudb, int uid, const char *lang)
+struct json_object *afm_udb_applications_public(struct afm_udb *afudb, int all, int uid, const char *lang)
 {
-       return json_object_get(afudb->applications.pubarr);
+       return json_object_get(all ? afudb->applications.publics.all : afudb->applications.publics.visibles);
 }
 
 /*
@@ -556,7 +580,7 @@ static struct json_object *get_no_case(struct json_object *object, const char *i
  */
 struct json_object *afm_udb_get_application_private(struct afm_udb *afudb, const char *id, int uid)
 {
-       return get_no_case(afudb->applications.prvobj, id, uid, NULL);
+       return get_no_case(afudb->applications.privates.byname, id, uid, NULL);
 }
 
 /*
@@ -567,7 +591,7 @@ struct json_object *afm_udb_get_application_private(struct afm_udb *afudb, const
 struct json_object *afm_udb_get_application_public(struct afm_udb *afudb,
                                                        const char *id, int uid, const char *lang)
 {
-       return get_no_case(afudb->applications.pubobj, id, uid, lang);
+       return get_no_case(afudb->applications.publics.byname, id, uid, lang);
 }
 
 
@@ -577,9 +601,9 @@ struct json_object *afm_udb_get_application_public(struct afm_udb *afudb,
 int main()
 {
 struct afm_udb *afudb = afm_udb_create(1, 1, NULL);
-printf("array = %s\n", json_object_to_json_string_ext(afudb->applications.pubarr, 3));
-printf("pubobj = %s\n", json_object_to_json_string_ext(afudb->applications.pubobj, 3));
-printf("prvobj = %s\n", json_object_to_json_string_ext(afudb->applications.prvobj, 3));
+printf("publics.all = %s\n", json_object_to_json_string_ext(afudb->applications.publics.all, 3));
+printf("publics.byname = %s\n", json_object_to_json_string_ext(afudb->applications.publics.byname, 3));
+printf("privates.byname = %s\n", json_object_to_json_string_ext(afudb->applications.privates.byname, 3));
 return 0;
 }
 #endif
index 3e24b14..fc1a155 100644 (file)
@@ -24,8 +24,8 @@ extern void afm_udb_addref(struct afm_udb *afdb);
 extern void afm_udb_unref(struct afm_udb *afdb);
 extern int afm_udb_update(struct afm_udb *afdb);
 extern void afm_udb_set_default_lang(const char *lang);
-extern struct json_object *afm_udb_applications_private(struct afm_udb *afdb, int uid);
+extern struct json_object *afm_udb_applications_private(struct afm_udb *afdb, int all, int uid);
 extern struct json_object *afm_udb_get_application_private(struct afm_udb *afdb, const char *id, int uid);
-extern struct json_object *afm_udb_applications_public(struct afm_udb *afdb, int uid, const char *lang);
+extern struct json_object *afm_udb_applications_public(struct afm_udb *afdb, int all, int uid, const char *lang);
 extern struct json_object *afm_udb_get_application_public(struct afm_udb *afdb, const char *id, int uid, const char *lang);
 
index 467b7d2..534f84c 100644 (file)
@@ -326,7 +326,7 @@ int afm_urun_resume(int runid, int uid)
  *
  * Returns the list or NULL in case of error.
  */
-struct json_object *afm_urun_list(struct afm_udb *db, int uid)
+struct json_object *afm_urun_list(struct afm_udb *db, int all, int uid)
 {
        int i, n, isuser, pid;
        const char *udpath;
@@ -342,7 +342,7 @@ struct json_object *afm_urun_list(struct afm_udb *db, int uid)
        if (result == NULL)
                goto error;
 
-       apps = afm_udb_applications_private(db, uid);
+       apps = afm_udb_applications_private(db, all, uid);
        n = json_object_array_length(apps);
        for (i = 0 ; i < n ; i++) {
                appli = json_object_array_get_idx(apps, i);
@@ -393,7 +393,7 @@ struct json_object *afm_urun_state(struct afm_udb *db, int runid, int uid)
                WARNING("searched runid %d not found", runid);
        } else {
                /* search in the base */
-               apps = afm_udb_applications_private(db, uid);
+               apps = afm_udb_applications_private(db, 1, uid);
                n = json_object_array_length(apps);
                for (i = 0 ; i < n ; i++) {
                        appli = json_object_array_get_idx(apps, i);
index e584688..4579015 100644 (file)
@@ -23,7 +23,7 @@ extern int afm_urun_once(struct json_object *appli, int uid);
 extern int afm_urun_terminate(int runid, int uid);
 extern int afm_urun_pause(int runid, int uid);
 extern int afm_urun_resume(int runid, int uid);
-extern struct json_object *afm_urun_list(struct afm_udb *db, int uid);
+extern struct json_object *afm_urun_list(struct afm_udb *db, int all, int uid);
 extern struct json_object *afm_urun_state(struct afm_udb *db, int runid, int uid);
 extern int afm_urun_search_runid(struct afm_udb *db, const char *id, int uid);