1. apply systemd unit files
[framework/appfw/aul-1.git] / am_daemon / amd_appinfo.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <assert.h>
6 #include <glib.h>
7 #include <dirent.h>
8
9 #include <pkgmgr-info.h>
10 #include <vconf.h>
11 #include "amd_config.h"
12 #include "simple_util.h"
13 #include "amd_appinfo.h"
14
15
16 #define SERVICE_GROUP "Service"
17
18 struct appinfomgr {
19         GHashTable *tbl; /* key is filename, value is struct appinfo */
20 };
21
22 enum _appinfo_idx {
23         _AI_FILE = 0, /* service filename */
24         _AI_NAME,
25         _AI_COMP,
26         _AI_EXEC,
27         _AI_TYPE,
28         _AI_ONBOOT,
29         _AI_RESTART,
30         _AI_MULTI,
31         _AI_MAX,
32 };
33 #define _AI_START _AI_NAME /* start index */
34
35 struct appinfo_t {
36         char *name;
37         enum appinfo_type type;
38 };
39
40 static struct appinfo_t _appinfos[] = {
41         [_AI_NAME] = { "Name", AIT_NAME, },
42         [_AI_COMP] = { "Component", AIT_COMP, },
43         [_AI_EXEC] = { "Exec", AIT_EXEC, },
44         [_AI_TYPE] = { "PkgType", AIT_TYPE, },
45         [_AI_ONBOOT] = { "StartOnBoot", AIT_ONBOOT, },
46         [_AI_RESTART] = { "AutoRestart", AIT_RESTART, },
47         [_AI_MULTI] = { "Multiple", AIT_MULTI, },
48 };
49
50 struct appinfo {
51         char *val[_AI_MAX];
52 };
53
54 static void _free_appinfo(gpointer data)
55 {
56         struct appinfo *c = data;
57         int i;
58
59         if (!c)
60                 return;
61
62         for (i = 0; i < sizeof(c->val)/sizeof(c->val[0]); i++)
63                 free(c->val[i]);
64
65         free(c);
66 }
67
68 static void _fini(struct appinfomgr *cf)
69 {
70         assert(cf);
71
72         g_hash_table_destroy(cf->tbl);
73         free(cf);
74 }
75
76 pkgmgrinfo_pkginfo_h p_handle;
77
78 static int __svc_app_info_insert_handler (const pkgmgrinfo_appinfo_h handle, void *data)
79 {
80         struct appinfo *c;
81         struct appinfomgr *cf = (struct appinfomgr *)data;
82         gboolean r;
83         char *exec;
84         char *type;
85         bool onboot;
86         bool restart;
87         char *appid;
88
89         pkgmgrinfo_appinfo_get_appid(handle, &appid);
90
91         g_hash_table_remove(cf->tbl, appid);
92
93         c = calloc(1, sizeof(*c));
94         if (!c) {
95                 _E("create appinfo: %s", strerror(errno));
96                 return -1;
97         }
98
99         memset(c, 0, sizeof(struct appinfo));
100
101         c->val[_AI_FILE] = strdup(appid);
102         if (!c->val[_AI_FILE]) {
103                 _E("create appinfo: %s", strerror(errno));
104                 _free_appinfo(c);
105                 return -1;
106         }
107
108         c->val[_AI_NAME] = strdup(appid); //TODO :
109
110         c->val[_AI_COMP] = strdup("svc"); //TODO :
111
112         r = pkgmgrinfo_appinfo_get_exec(handle, &exec);
113         c->val[_AI_EXEC] = strdup(exec);
114
115         r = pkgmgrinfo_pkginfo_get_type(p_handle, &type);
116         c->val[_AI_TYPE] = strdup(type);
117
118         r = pkgmgrinfo_appinfo_is_onboot(handle, &onboot);
119         if(onboot == true)
120                 c->val[_AI_ONBOOT] = strdup("true");
121         else c->val[_AI_ONBOOT] = strdup("false");
122
123         r = pkgmgrinfo_appinfo_is_autorestart(handle, &restart);
124         if(restart == true)
125                 c->val[_AI_RESTART] = strdup("true");
126         else c->val[_AI_RESTART] = strdup("false");
127
128         _D("%s : %s : %s : %s : %s", c->val[_AI_FILE], c->val[_AI_COMP], c->val[_AI_TYPE], c->val[_AI_ONBOOT], c->val[_AI_RESTART]);
129
130         g_hash_table_insert(cf->tbl, c->val[_AI_FILE], c);
131
132         return 0;
133 }
134
135 static int __ui_app_info_insert_handler (const pkgmgrinfo_appinfo_h handle, void *data)
136 {
137         struct appinfo *c;
138         struct appinfomgr *cf = (struct appinfomgr *)data;
139         gboolean r;
140         char *exec;
141         char *type;
142         bool multiple;
143         char *appid;
144
145         pkgmgrinfo_appinfo_get_appid(handle, &appid);
146
147         g_hash_table_remove(cf->tbl, appid);
148
149         c = calloc(1, sizeof(*c));
150         if (!c) {
151                 _E("create appinfo: %s", strerror(errno));
152                 return -1;
153         }
154
155         memset(c, 0, sizeof(struct appinfo));
156
157         c->val[_AI_FILE] = strdup(appid);
158         if (!c->val[_AI_FILE]) {
159                 _E("create appinfo: %s", strerror(errno));
160                 _free_appinfo(c);
161                 return -1;
162         }
163
164         c->val[_AI_NAME] = strdup(appid); //TODO :
165
166         c->val[_AI_COMP] = strdup("ui"); //TODO :
167
168         r = pkgmgrinfo_appinfo_get_exec(handle, &exec);
169         c->val[_AI_EXEC] = strdup(exec);
170
171         r = pkgmgrinfo_pkginfo_get_type(p_handle, &type);
172         c->val[_AI_TYPE] = strdup(type);
173
174         r = pkgmgrinfo_appinfo_is_multiple(handle, &multiple);
175         if(multiple == true)
176                 c->val[_AI_MULTI] = strdup("true");
177         else c->val[_AI_MULTI] = strdup("false");
178
179         _D("%s : %s : %s : %s", c->val[_AI_FILE], c->val[_AI_COMP], c->val[_AI_TYPE], c->val[_AI_MULTI]);
180
181         g_hash_table_insert(cf->tbl, c->val[_AI_FILE], c);
182
183         return 0;
184 }
185
186 static int __app_info_delete_handler (const pkgmgrinfo_appinfo_h handle, void *data)
187 {
188         struct appinfomgr *cf = (struct appinfomgr *)data;
189         char *appid;
190
191         pkgmgrinfo_appinfo_get_appid(handle, &appid);
192
193         g_hash_table_remove(cf->tbl, appid);
194
195         return 0;
196 }
197
198 static int __pkg_info_handler(const pkgmgrinfo_pkginfo_h handle, void *data)
199 {
200         int r;
201
202         p_handle = handle;
203         r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_SVC_APP, __svc_app_info_insert_handler, data);
204         r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP, __ui_app_info_insert_handler, data);
205
206         return 0;
207 }
208
209 static int _read_pkg_info(struct appinfomgr *cf)
210 {
211         int r;
212
213         r = pkgmgrinfo_pkginfo_get_list(__pkg_info_handler, cf);
214
215         return 0;
216 }
217
218 static struct appinfomgr *_init()
219 {
220         struct appinfomgr *cf;
221
222         cf = calloc(1, sizeof(*cf));
223         if (!cf) {
224                 _E("appinfo init: %s", strerror(errno));
225                 return NULL;
226         }
227
228         cf->tbl = g_hash_table_new_full(g_str_hash, g_str_equal,
229                         NULL, _free_appinfo);
230
231         return cf;
232 }
233
234 static void __vconf_cb(keynode_t *key, void *data)
235 {
236         char *noti_string;
237         char *type_string;
238         char *appid;
239         char *saveptr;
240         pkgmgrinfo_appinfo_h handle;
241         pkgmgrinfo_app_component component;
242         struct appinfomgr *cf = (struct appinfomgr *)data;
243
244         noti_string = vconf_keynode_get_str(key);
245         if( noti_string == NULL ) {
246                 return;
247         }
248
249         _D("noti_string : %s",noti_string);
250
251         type_string = strtok_r(noti_string, ":", &saveptr);
252         appid = strtok_r(NULL, ":", &saveptr);
253
254         if ( strncmp(type_string, "create", 6) == 0) {
255                 pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
256
257                 _D("appid : %s /handle : %x", appid, handle);
258                 pkgmgrinfo_appinfo_get_component(handle, &component);
259
260                 if(component == PMINFO_UI_APP) {
261                         __ui_app_info_insert_handler(handle, data);
262                 } else if (component == PMINFO_SVC_APP) {
263                         __svc_app_info_insert_handler(handle, data);
264                 }
265
266                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
267         } else if ( strncmp(type_string, "delete", 6) == 0) {
268                 g_hash_table_remove(cf->tbl, appid);
269         }
270 }
271
272 int appinfo_init(struct appinfomgr **cf)
273 {
274         struct appinfomgr *_cf;
275         int r;
276
277         if (!cf) {
278                 errno = EINVAL;
279                 _E("appinfo init: %s", strerror(errno));
280                 return -1;
281         }
282
283         _cf = _init();
284         if (!_cf)
285                 return -1;
286
287         r = _read_pkg_info(_cf);
288         if (r == -1) {
289                 _fini(_cf);
290                 return -1;
291         }
292
293         r = vconf_notify_key_changed("memory/menuscreen/desktop", __vconf_cb, _cf);
294
295         *cf = _cf;
296
297         return 0;
298 }
299
300 void appinfo_fini(struct appinfomgr **cf)
301 {
302         if (!cf || !*cf)
303                 return;
304
305         _fini(*cf);
306         *cf = NULL;
307 }
308
309 const struct appinfo *appinfo_insert(struct appinfomgr *cf, const char *pkg_name)
310 {
311         int r;
312         pkgmgrinfo_pkginfo_h handle;
313
314         r = pkgmgrinfo_pkginfo_get_pkginfo(pkg_name, &handle);
315         p_handle = handle;
316         r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_SVC_APP, __svc_app_info_insert_handler, cf);
317         r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP, __ui_app_info_insert_handler, cf);
318         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
319
320         return cf;
321 }
322
323 void appinfo_delete(struct appinfomgr *cf, const char *pkg_name)
324 {
325         int r;
326         pkgmgrinfo_pkginfo_h handle;
327
328         r = pkgmgrinfo_pkginfo_get_pkginfo(pkg_name, &handle);
329         r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_SVC_APP, __app_info_delete_handler, cf);
330         r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP, __app_info_delete_handler, cf);
331         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
332 }
333
334 const struct appinfo *appinfo_find(struct appinfomgr *cf, const char *filename)
335 {
336         if (!cf || !filename || !*filename) {
337                 errno = EINVAL;
338                 _E("appinfo find: %s", strerror(errno));
339                 return NULL;
340         }
341
342         return g_hash_table_lookup(cf->tbl, FILENAME(filename));
343 }
344
345 const char *appinfo_get_value(const struct appinfo *c, enum appinfo_type type)
346 {
347         enum _appinfo_idx i;
348
349         if (!c) {
350                 errno = EINVAL;
351                 _E("appinfo get value: %s", strerror(errno));
352                 return NULL;
353         }
354
355         for (i = _AI_START; i < sizeof(_appinfos)/sizeof(_appinfos[0]); i++) {
356                 if (type == _appinfos[i].type)
357                         return c->val[i];
358         }
359
360         errno = ENOENT;
361         _E("appinfo get value: %s", strerror(errno));
362
363         return NULL;
364 }
365
366 const char *appinfo_get_filename(const struct appinfo *c)
367 {
368         if (!c) {
369                 errno = EINVAL;
370                 _E("appinfo get filename: %s", strerror(errno));
371                 return NULL;
372         }
373
374         return c->val[_AI_FILE];
375 }
376
377 struct _cbinfo {
378         appinfo_iter_callback cb;
379         void *cb_data;
380 };
381
382 static void _iter_cb(gpointer key, gpointer value, gpointer user_data)
383 {
384         struct _cbinfo *cbi = user_data;
385
386         assert(cbi);
387
388         cbi->cb(cbi->cb_data, key, value);
389 }
390
391 void appinfo_foreach(struct appinfomgr *cf, appinfo_iter_callback cb, void *user_data)
392 {
393         struct _cbinfo cbi;
394
395         if (!cf || !cb) {
396                 errno = EINVAL;
397                 _E("appinfo foreach: %s", strerror(errno));
398                 return;
399         }
400
401         cbi.cb = cb;
402         cbi.cb_data = user_data;
403
404         g_hash_table_foreach(cf->tbl, _iter_cb, &cbi);
405 }
406
407 int appinfo_get_boolean(const struct appinfo *c, enum appinfo_type type)
408 {
409         const char *v;
410
411         v = appinfo_get_value(c, type);
412         if (!v)
413                 return -1;
414
415         if (!strcmp(v, "1") || !strcasecmp(v, "true"))
416                 return 1;
417
418         if (!strcmp(v, "0") || !strcasecmp(v, "false"))
419                 return 0;
420
421         errno = EFAULT;
422
423         return -1;
424 }
425