added error handle
[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_HWACC,
32         _AI_MAX,
33 };
34 #define _AI_START _AI_NAME /* start index */
35
36 struct appinfo_t {
37         char *name;
38         enum appinfo_type type;
39 };
40
41 static struct appinfo_t _appinfos[] = {
42         [_AI_NAME] = { "Name", AIT_NAME, },
43         [_AI_COMP] = { "Component", AIT_COMP, },
44         [_AI_EXEC] = { "Exec", AIT_EXEC, },
45         [_AI_TYPE] = { "PkgType", AIT_TYPE, },
46         [_AI_ONBOOT] = { "StartOnBoot", AIT_ONBOOT, },
47         [_AI_RESTART] = { "AutoRestart", AIT_RESTART, },
48         [_AI_MULTI] = { "Multiple", AIT_MULTI, },
49         [_AI_HWACC] = { "Hwacceleration", AIT_HWACC, },
50 };
51
52 struct appinfo {
53         char *val[_AI_MAX];
54 };
55
56 static void _free_appinfo(gpointer data)
57 {
58         struct appinfo *c = data;
59         int i;
60
61         if (!c)
62                 return;
63
64         for (i = 0; i < sizeof(c->val)/sizeof(c->val[0]); i++)
65                 free(c->val[i]);
66
67         free(c);
68 }
69
70 static void _fini(struct appinfomgr *cf)
71 {
72         assert(cf);
73
74         g_hash_table_destroy(cf->tbl);
75         free(cf);
76 }
77
78 static int __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         char *appid;
86         bool multiple;
87         bool onboot;
88         bool restart;
89         pkgmgrinfo_app_hwacceleration hwacc;
90         pkgmgrinfo_app_component component;
91         int ret = -1;
92
93         if (!handle) {
94                 _E("null app handle");
95                 return -1;
96         }
97
98         ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
99         if (ret < 0) {
100                 _E("fail to get appinfo");
101                 return -1;
102         }
103
104         g_hash_table_remove(cf->tbl, appid);
105
106         c = calloc(1, sizeof(*c));
107         if (!c) {
108                 _E("create appinfo: %s", strerror(errno));
109                 return -1;
110         }
111
112         memset(c, 0, sizeof(struct appinfo));
113
114         c->val[_AI_FILE] = strdup(appid);
115         if (!c->val[_AI_FILE]) {
116                 _E("create appinfo: %s", strerror(errno));
117                 _free_appinfo(c);
118                 return -1;
119         }
120
121         c->val[_AI_NAME] = strdup(appid); //TODO :
122
123         pkgmgrinfo_appinfo_get_component(handle, &component);
124         if(component == PMINFO_UI_APP) {
125                 c->val[_AI_COMP] = strdup("ui"); //TODO :
126
127                 r = pkgmgrinfo_appinfo_is_multiple(handle, &multiple);
128                 if(multiple == true)
129                         c->val[_AI_MULTI] = strdup("true");
130                 else c->val[_AI_MULTI] = strdup("false");
131
132                 r = pkgmgrinfo_appinfo_get_hwacceleration(handle, &hwacc);
133                 if (hwacc == PMINFO_HWACCELERATION_USE_GL) {
134                         c->val[_AI_HWACC] = strdup("USE");
135                 } else if (hwacc == PMINFO_HWACCELERATION_USE_SYSTEM_SETTING) {
136                         c->val[_AI_HWACC] = strdup("SYS");
137                 } else {
138                         c->val[_AI_HWACC] = strdup("NOT_USE");
139                 }
140         } else {
141                 c->val[_AI_COMP] = strdup("svc");
142
143                 r = pkgmgrinfo_appinfo_is_onboot(handle, &onboot);
144                 if(onboot == true)
145                         c->val[_AI_ONBOOT] = strdup("true");
146                 else c->val[_AI_ONBOOT] = strdup("false");
147
148                 r = pkgmgrinfo_appinfo_is_autorestart(handle, &restart);
149                 if(restart == true)
150                         c->val[_AI_RESTART] = strdup("true");
151                 else c->val[_AI_RESTART] = strdup("false");
152         }
153
154         r = pkgmgrinfo_appinfo_get_exec(handle, &exec);
155         c->val[_AI_EXEC] = strdup(exec);
156
157         r = pkgmgrinfo_appinfo_get_apptype(handle, &type);
158         if(strncmp(type, "capp", 4) == 0 ) {
159                 c->val[_AI_TYPE] = strdup("rpm");
160         } else if (strncmp(type, "c++app", 6) == 0 || strncmp(type, "ospapp", 6) == 0) {
161                 c->val[_AI_TYPE] = strdup("tpk");
162         } else if (strncmp(type, "webapp", 6) == 0) {
163                 c->val[_AI_TYPE] = strdup("wgt");
164         }
165
166         _D("%s : %s : %s", c->val[_AI_FILE], c->val[_AI_COMP], c->val[_AI_TYPE]);
167
168         g_hash_table_insert(cf->tbl, c->val[_AI_FILE], c);
169
170         return 0;
171 }
172
173 static int __app_info_delete_handler (const pkgmgrinfo_appinfo_h handle, void *data)
174 {
175         struct appinfomgr *cf = (struct appinfomgr *)data;
176         char *appid;
177
178         pkgmgrinfo_appinfo_get_appid(handle, &appid);
179
180         g_hash_table_remove(cf->tbl, appid);
181
182         return 0;
183 }
184
185 static int _read_pkg_info(struct appinfomgr *cf)
186 {
187         int r;
188
189         r = pkgmgrinfo_appinfo_get_installed_list(__app_info_insert_handler, cf);
190
191         return 0;
192 }
193
194 static struct appinfomgr *_init()
195 {
196         struct appinfomgr *cf;
197
198         cf = calloc(1, sizeof(*cf));
199         if (!cf) {
200                 _E("appinfo init: %s", strerror(errno));
201                 return NULL;
202         }
203
204         cf->tbl = g_hash_table_new_full(g_str_hash, g_str_equal,
205                         NULL, _free_appinfo);
206
207         return cf;
208 }
209
210 static void __vconf_cb(keynode_t *key, void *data)
211 {
212         char *noti_string;
213         char *type_string;
214         char *appid;
215         char *saveptr;
216         char *pkgname;
217         pkgmgrinfo_appinfo_h handle;
218         struct appinfomgr *cf = (struct appinfomgr *)data;
219
220         noti_string = vconf_keynode_get_str(key);
221         if( noti_string == NULL ) {
222                 return;
223         }
224
225         _D("noti_string : %s",noti_string);
226
227         type_string = strtok_r(noti_string, ":", &saveptr);
228         appid = strtok_r(NULL, ":", &saveptr);
229
230         if ( strncmp(type_string, "create", 6) == 0) {
231                 pkgmgrinfo_appinfo_get_appinfo(appid, &handle);
232
233                 _D("appid : %s /handle : %x", appid, handle);
234
235                 __app_info_insert_handler(handle, data);
236
237                 pkgmgrinfo_appinfo_destroy_appinfo(handle);
238         } else if ( strncmp(type_string, "delete", 6) == 0) {
239                 g_hash_table_remove(cf->tbl, appid);
240         }
241 }
242
243 int appinfo_init(struct appinfomgr **cf)
244 {
245         struct appinfomgr *_cf;
246         int r;
247
248         if (!cf) {
249                 errno = EINVAL;
250                 _E("appinfo init: %s", strerror(errno));
251                 return -1;
252         }
253
254         _cf = _init();
255         if (!_cf)
256                 return -1;
257
258         r = _read_pkg_info(_cf);
259         if (r == -1) {
260                 _fini(_cf);
261                 return -1;
262         }
263
264         r = vconf_notify_key_changed(VCONFKEY_MENUSCREEN_DESKTOP, __vconf_cb, _cf);
265
266         *cf = _cf;
267
268         return 0;
269 }
270
271 void appinfo_fini(struct appinfomgr **cf)
272 {
273         if (!cf || !*cf)
274                 return;
275
276         _fini(*cf);
277         *cf = NULL;
278 }
279
280 const struct appinfo *appinfo_insert(struct appinfomgr *cf, const char *pkg_name)
281 {
282         int r;
283         pkgmgrinfo_pkginfo_h handle;
284
285         r = pkgmgrinfo_pkginfo_get_pkginfo(pkg_name, &handle);
286         r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_SVC_APP, __app_info_insert_handler, cf);
287         r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP, __app_info_insert_handler, cf);
288         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
289
290         return cf;
291 }
292
293 void appinfo_delete(struct appinfomgr *cf, const char *pkg_name)
294 {
295         int r;
296         pkgmgrinfo_pkginfo_h handle;
297
298         r = pkgmgrinfo_pkginfo_get_pkginfo(pkg_name, &handle);
299         r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_SVC_APP, __app_info_delete_handler, cf);
300         r = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP, __app_info_delete_handler, cf);
301         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
302 }
303
304 const struct appinfo *appinfo_find(struct appinfomgr *cf, const char *filename)
305 {
306         if (!cf || !filename || !*filename) {
307                 errno = EINVAL;
308                 _E("appinfo find: %s", strerror(errno));
309                 return NULL;
310         }
311
312         return g_hash_table_lookup(cf->tbl, FILENAME(filename));
313 }
314
315 const char *appinfo_get_value(const struct appinfo *c, enum appinfo_type type)
316 {
317         enum _appinfo_idx i;
318
319         if (!c) {
320                 errno = EINVAL;
321                 _E("appinfo get value: %s", strerror(errno));
322                 return NULL;
323         }
324
325         for (i = _AI_START; i < sizeof(_appinfos)/sizeof(_appinfos[0]); i++) {
326                 if (type == _appinfos[i].type)
327                         return c->val[i];
328         }
329
330         errno = ENOENT;
331         _E("appinfo get value: %s", strerror(errno));
332
333         return NULL;
334 }
335
336 const char *appinfo_get_filename(const struct appinfo *c)
337 {
338         if (!c) {
339                 errno = EINVAL;
340                 _E("appinfo get filename: %s", strerror(errno));
341                 return NULL;
342         }
343
344         return c->val[_AI_FILE];
345 }
346
347 struct _cbinfo {
348         appinfo_iter_callback cb;
349         void *cb_data;
350 };
351
352 static void _iter_cb(gpointer key, gpointer value, gpointer user_data)
353 {
354         struct _cbinfo *cbi = user_data;
355
356         assert(cbi);
357
358         cbi->cb(cbi->cb_data, key, value);
359 }
360
361 void appinfo_foreach(struct appinfomgr *cf, appinfo_iter_callback cb, void *user_data)
362 {
363         struct _cbinfo cbi;
364
365         if (!cf || !cb) {
366                 errno = EINVAL;
367                 _E("appinfo foreach: %s", strerror(errno));
368                 return;
369         }
370
371         cbi.cb = cb;
372         cbi.cb_data = user_data;
373
374         g_hash_table_foreach(cf->tbl, _iter_cb, &cbi);
375 }
376
377 int appinfo_get_boolean(const struct appinfo *c, enum appinfo_type type)
378 {
379         const char *v;
380
381         v = appinfo_get_value(c, type);
382         if (!v)
383                 return -1;
384
385         if (!strcmp(v, "1") || !strcasecmp(v, "true"))
386                 return 1;
387
388         if (!strcmp(v, "0") || !strcasecmp(v, "false"))
389                 return 0;
390
391         errno = EFAULT;
392
393         return -1;
394 }
395