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