4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
24 #include <sys/types.h>
31 struct json_object *pubarr;
32 struct json_object *direct;
33 struct json_object *byapp;
40 struct afapps applications;
41 struct json_object *runners;
44 struct appfwk *appfwk_create()
46 struct appfwk *appfwk = malloc(sizeof * appfwk);
50 appfwk->runners = json_object_new_object();
51 if (appfwk->runners == NULL) {
59 appfwk->applications.pubarr = NULL;
60 appfwk->applications.direct = NULL;
61 appfwk->applications.byapp = NULL;
67 void appfwk_addref(struct appfwk *appfwk)
73 void appfwk_unref(struct appfwk *appfwk)
76 if (!--appfwk->refcount) {
77 json_object_put(appfwk->applications.pubarr);
78 json_object_put(appfwk->applications.direct);
79 json_object_put(appfwk->applications.byapp);
80 json_object_put(appfwk->runners);
81 while (appfwk->nrroots)
82 free(appfwk->roots[--appfwk->nrroots]);
88 int appfwk_add_root(struct appfwk *appfwk, const char *path)
95 /* don't depend on the cwd and unique name */
96 r = realpath(path, NULL);
100 /* avoiding duplications */
102 roots = appfwk->roots;
103 for (i = 0 ; i < n ; i++) {
104 if (!strcmp(r, roots[i])) {
111 roots = realloc(roots, (n + 1) * sizeof(roots[0]));
118 appfwk->roots = roots;
123 static int json_add(struct json_object *obj, const char *key, struct json_object *val)
125 json_object_object_add(obj, key, val);
129 static int json_add_str(struct json_object *obj, const char *key, const char *val)
131 struct json_object *str = json_object_new_string (val ? val : "");
132 return str ? json_add(obj, key, str) : -1;
135 static int json_add_int(struct json_object *obj, const char *key, int val)
137 struct json_object *v = json_object_new_int (val);
138 return v ? json_add(obj, key, v) : -1;
141 static int addapp(struct afapps *apps, const char *path)
143 struct wgt_info *info;
144 const struct wgt_desc *desc;
145 const struct wgt_desc_feature *feat;
146 struct json_object *priv = NULL, *pub, *bya, *plugs, *str;
149 /* connect to the widget */
150 info = wgt_info_createat(AT_FDCWD, path, 0, 1, 0);
153 desc = wgt_info_desc(info);
155 /* create the application id */
156 appid = alloca(2 + strlen(desc->id) + strlen(desc->version));
157 end = stpcpy(appid, desc->id);
159 strcpy(end, desc->version);
161 /* create the application structure */
162 priv = json_object_new_object();
166 pub = json_object_new_object();
170 if (json_add(priv, "public", pub)) {
171 json_object_put(pub);
175 plugs = json_object_new_array();
179 if (json_add(priv, "plugins", plugs)) {
180 json_object_put(plugs);
184 if(json_add_str(pub, "id", appid)
185 || json_add_str(priv, "id", desc->id)
186 || json_add_str(pub, "version", desc->version)
187 || json_add_str(priv, "path", path)
188 || json_add_int(pub, "width", desc->width)
189 || json_add_int(pub, "height", desc->height)
190 || json_add_str(pub, "name", desc->name)
191 || json_add_str(pub, "description", desc->description)
192 || json_add_str(pub, "shortname", desc->name_short)
193 || json_add_str(pub, "author", desc->author))
196 feat = desc->features;
198 static const char prefix[] = FWK_PREFIX_PLUGIN;
199 if (!memcmp(feat->name, prefix, sizeof prefix - 1)) {
200 str = json_object_new_string (feat->name + sizeof prefix - 1);
203 if (json_object_array_add(plugs, str)) {
204 json_object_put(str);
211 /* record the application structure */
212 if (!json_object_object_get_ex(apps->byapp, desc->id, &bya)) {
213 bya = json_object_new_object();
216 if (json_add(apps->byapp, desc->id, bya)) {
217 json_object_put(bya);
222 if (json_add(apps->direct, appid, priv))
224 json_object_get(priv);
226 if (json_add(bya, desc->version, priv)) {
227 json_object_put(priv);
231 if (json_object_array_add(apps->pubarr, pub))
234 wgt_info_unref(info);
238 json_object_put(priv);
239 wgt_info_unref(info);
250 static int enumentries(struct enumdata *data, int (*callto)(struct enumdata *))
255 struct dirent entry, *e;
257 /* opens the directory */
258 dir = opendir(data->path);
262 /* prepare appending entry names */
263 beg = data->path + data->length;
266 /* enumerate entries */
267 rc = readdir_r(dir, &entry, &e);
269 if (entry.d_name[0] != '.' || (entry.d_name[1] && (entry.d_name[1] != '.' || entry.d_name[2]))) {
271 end = stpcpy(beg, entry.d_name);
272 data->length = end - data->path;
273 /* call the function */
278 rc = readdir_r(dir, &entry, &e);
284 static int recordapp(struct enumdata *data)
286 return addapp(&data->apps, data->path);
289 /* enumerate the versions */
290 static int enumvers(struct enumdata *data)
292 int rc = enumentries(data, recordapp);
293 return !rc || errno != ENOTDIR ? 0 : rc;
296 /* regenerate the list of applications */
297 int appfwk_update_applications(struct appfwk *af)
300 struct enumdata edata;
301 struct afapps oldapps;
303 /* create the result */
304 edata.apps.pubarr = json_object_new_array();
305 edata.apps.direct = json_object_new_object();
306 edata.apps.byapp = json_object_new_object();
307 if (edata.apps.pubarr == NULL || edata.apps.direct == NULL || edata.apps.byapp == NULL) {
312 for (iroot = 0 ; iroot < af->nrroots ; iroot++) {
313 edata.length = stpcpy(edata.path, af->roots[iroot]) - edata.path;
314 assert(edata.length < sizeof edata.path);
315 /* enumerate the applications */
316 rc = enumentries(&edata, enumvers);
320 /* commit the result */
321 oldapps = af->applications;
322 af->applications = edata.apps;
323 json_object_put(oldapps.pubarr);
324 json_object_put(oldapps.direct);
325 json_object_put(oldapps.byapp);
329 json_object_put(edata.apps.pubarr);
330 json_object_put(edata.apps.direct);
331 json_object_put(edata.apps.byapp);
335 int appfwk_ensure_applications(struct appfwk *af)
337 return af->applications.pubarr ? 0 : appfwk_update_applications(af);
340 struct json_object *appfwk_application_list(struct appfwk *af)
342 return appfwk_ensure_applications(af) ? NULL : af->applications.pubarr;
345 struct json_object *appfwk_get_application(struct appfwk *af, const char *id)
347 struct json_object *result;
348 if (!appfwk_ensure_applications(af) && json_object_object_get_ex(obj, id, &result))
354 struct json_object *appfwk_get_application_public(struct appfwk *af, const char *id)
356 struct json_object *result = appfwk_get_application(af, id);
357 return result && json_object_object_get_ex(result, "public", &result) ? result : NULL;
360 static struct json_object *mkrunner(const char *appid, const char *runid)
362 struct json_object *result = json_object_new_object();
364 if(json_add_str(result, "id", appid)
365 || json_add_str(result, "runid", runid)
366 || json_add_str(result, "state", NULL)) {
367 json_object_put(result);
374 const char *appfwk_start(struct appfwk *af, const char *appid)
376 struct json_object *appli;
377 struct json_object *runner;
380 /* get the application description */
381 appli = appfwk_get_application(af, appid);
387 /* prepare the execution */
388 snprintf(buffer, sizeof buffer, "{\"id\":\"%s\",\"runid\":\"%s\"
391 int appfwk_stop(struct appfwk *af, const char *runid)
393 struct json_object *runner;
394 runner = appfwk_state(af, runid);
395 if (runner == NULL) {
399 json_object_get(runner);
400 json_object_object_del(af->runners, runid);
414 json_object_put(runner);
417 int appfwk_suspend(struct appfwk *af, const char *runid)
421 int appfwk_resume(struct appfwk *af, const char *runid)
425 struct json_object *appfwk_running_list(struct appfwk *af)
430 struct json_object *appfwk_state(struct appfwk *af, const char *runid)
432 struct json_object *result;
433 int status = json_object_object_get_ex(af->runners, runid, &result);
434 return status ? result : NULL;
443 #if defined(TESTAPPFWK)
447 struct appfwk *af = appfwk_create();
448 appfwk_add_root(af,FWK_APP_DIR);
449 appfwk_update_applications(af);
450 printf("array = %s\n", json_object_to_json_string_ext(af->applications.pubarr, 3));
451 printf("direct = %s\n", json_object_to_json_string_ext(af->applications.direct, 3));
452 printf("byapp = %s\n", json_object_to_json_string_ext(af->applications.byapp, 3));