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