Fix returning empty value on getter
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_pkginfo.c
1 /*
2  * pkgmgr-info
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #define _GNU_SOURCE
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdbool.h>
28 #include <unistd.h>
29 #include <ctype.h>
30 #include <sys/smack.h>
31 #include <linux/limits.h>
32 #include <libgen.h>
33 #include <sys/stat.h>
34
35 #include <libxml/parser.h>
36 #include <libxml/xmlreader.h>
37 #include <libxml/xmlschemas.h>
38 #include <sqlite3.h>
39 #include <glib.h>
40
41 #include "pkgmgr_parser.h"
42 #include "pkgmgrinfo_basic.h"
43 #include "pkgmgrinfo_private.h"
44 #include "pkgmgrinfo_debug.h"
45 #include "pkgmgr-info.h"
46 #include "pkgmgr_parser_db.h"
47 #include "pkgmgr_parser_internal.h"
48
49 static bool _get_bool_value(const char *str)
50 {
51         if (str && !strcmp(str, "true"))
52                 return true;
53         else
54                 return false;
55 }
56
57 static gint __compare_func(gconstpointer data1, gconstpointer data2)
58 {
59         pkgmgrinfo_node_x *node1 = (pkgmgrinfo_node_x*)data1;
60         pkgmgrinfo_node_x *node2 = (pkgmgrinfo_node_x*)data2;
61         if (node1->prop == node2->prop)
62                 return 0;
63         else if (node1->prop > node2->prop)
64                 return 1;
65         else
66                 return -1;
67 }
68
69 static void __destroy_each_node(gpointer data, gpointer user_data)
70 {
71         ret_if(data == NULL);
72         pkgmgrinfo_node_x *node = (pkgmgrinfo_node_x*)data;
73         if (node->value) {
74                 free(node->value);
75                 node->value = NULL;
76         }
77         if (node->key) {
78                 free(node->key);
79                 node->key = NULL;
80         }
81         free(node);
82         node = NULL;
83 }
84
85 static void __cleanup_pkginfo(pkgmgr_pkginfo_x *data)
86 {
87         ret_if(data == NULL);
88         if (data->locale){
89                 free((void *)data->locale);
90                 data->locale = NULL;
91         }
92
93         pkgmgrinfo_basic_free_package(data->pkg_info);
94         free((void *)data);
95         data = NULL;
96         return;
97 }
98
99 static int __child_element(xmlTextReaderPtr reader, int depth)
100 {
101         int ret = xmlTextReaderRead(reader);
102         int cur = xmlTextReaderDepth(reader);
103         while (ret == 1) {
104
105                 switch (xmlTextReaderNodeType(reader)) {
106                 case XML_READER_TYPE_ELEMENT:
107                         if (cur == depth + 1)
108                                 return 1;
109                         break;
110                 case XML_READER_TYPE_TEXT:
111                         /*text is handled by each function separately*/
112                         if (cur == depth + 1)
113                                 return 0;
114                         break;
115                 case XML_READER_TYPE_END_ELEMENT:
116                         if (cur == depth)
117                                 return 0;
118                         break;
119                 default:
120                         if (cur <= depth)
121                                 return 0;
122                         break;
123                 }
124                 ret = xmlTextReaderRead(reader);
125                 cur = xmlTextReaderDepth(reader);
126         }
127         return ret;
128 }
129
130 long long _pkgmgr_calculate_dir_size(char *dirname)
131 {
132         long long total = 0;
133         long long ret = 0;
134         int q = 0; /*quotient*/
135         int r = 0; /*remainder*/
136         DIR *dp = NULL;
137         struct dirent ep, *result;
138         struct stat fileinfo;
139         char abs_filename[FILENAME_MAX] = { 0, };
140         retvm_if(dirname == NULL, PMINFO_R_ERROR, "dirname is NULL");
141
142         dp = opendir(dirname);
143         if (dp == NULL) {
144                 _LOGE("Couldn't open the directory\n");
145                 return -1;
146         }
147
148         for (ret = readdir_r(dp, &ep, &result);
149                         ret == 0 && result != NULL;
150                         ret = readdir_r(dp, &ep, &result)) {
151                 if (!strcmp(ep.d_name, ".") ||
152                         !strcmp(ep.d_name, "..")) {
153                         continue;
154                 }
155                 snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname,
156                          ep.d_name);
157                 if (lstat(abs_filename, &fileinfo) < 0)
158                         perror(abs_filename);
159                 else {
160                         if (S_ISDIR(fileinfo.st_mode)) {
161                                 total += fileinfo.st_size;
162                                 if (strcmp(ep.d_name, ".")
163                                     && strcmp(ep.d_name, "..")) {
164                                         ret = _pkgmgr_calculate_dir_size
165                                             (abs_filename);
166                                         total = total + ret;
167                                 }
168                         } else if (S_ISLNK(fileinfo.st_mode)) {
169                                 continue;
170                         } else {
171                                 /*It is a file. Calculate the actual
172                                 size occupied (in terms of 4096 blocks)*/
173                         q = (fileinfo.st_size / BLOCK_SIZE);
174                         r = (fileinfo.st_size % BLOCK_SIZE);
175                         if (r) {
176                                 q = q + 1;
177                         }
178                         total += q * BLOCK_SIZE;
179                         }
180                 }
181         }
182         (void)closedir(dp);
183         return total;
184
185 }
186
187 static int _pkginfo_get_author(sqlite3 *db, const char *pkgid,
188                 GList **author)
189 {
190         static const char query_raw[] =
191                 "SELECT author_name, author_email, author_href "
192                 "FROM package_info WHERE package=%Q";
193         int ret;
194         char *query;
195         sqlite3_stmt *stmt;
196         int idx = 0;
197         author_x *info;
198
199         query = sqlite3_mprintf(query_raw, pkgid);
200         if (query == NULL) {
201                 LOGE("out of memory");
202                 return PMINFO_R_ERROR;
203         }
204
205         ret = sqlite3_prepare_v2(db, query, strlen(query),
206                         &stmt, NULL);
207         sqlite3_free(query);
208         if (ret != SQLITE_OK) {
209                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
210                 return PMINFO_R_ERROR;
211         }
212
213         if (sqlite3_step(stmt) == SQLITE_ERROR) {
214                 LOGE("step error: %s", sqlite3_errmsg(db));
215                 sqlite3_finalize(stmt);
216                 return PMINFO_R_ERROR;
217         }
218
219         /* one author per one package */
220         info = calloc(1, sizeof(author_x));
221         if (info == NULL) {
222                 LOGE("out of memory");
223                 sqlite3_finalize(stmt);
224                 return PMINFO_R_ERROR;
225         }
226
227         _save_column_str(stmt, idx++, &info->text);
228         _save_column_str(stmt, idx++, &info->email);
229         _save_column_str(stmt, idx++, &info->href);
230
231         /* TODO: revised */
232         *author = g_list_append(*author, info);
233
234         sqlite3_finalize(stmt);
235
236         return PMINFO_R_OK;
237 }
238
239 static int _pkginfo_get_label(sqlite3 *db, const char *pkgid,
240                 const char *locale, GList **label)
241 {
242         static const char query_raw[] =
243                 "SELECT package_label, package_locale "
244                 "FROM package_localized_info "
245                 "WHERE package=%Q AND package_locale IN (%Q, %Q)";
246         int ret;
247         char *query;
248         sqlite3_stmt *stmt;
249         int idx;
250         label_x *info;
251
252         query = sqlite3_mprintf(query_raw, pkgid, locale, DEFAULT_LOCALE);
253         if (query == NULL) {
254                 LOGE("out of memory");
255                 return PMINFO_R_ERROR;
256         }
257
258         ret = sqlite3_prepare_v2(db, query, strlen(query),
259                         &stmt, NULL);
260         sqlite3_free(query);
261         if (ret != SQLITE_OK) {
262                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
263                 return PMINFO_R_ERROR;
264         }
265
266         while (sqlite3_step(stmt) == SQLITE_ROW) {
267                 info = calloc(1, sizeof(label_x));
268                 if (info == NULL) {
269                         LOGE("out of memory");
270                         sqlite3_finalize(stmt);
271                         return PMINFO_R_ERROR;
272                 }
273                 idx = 0;
274                 _save_column_str(stmt, idx++, &info->text);
275                 _save_column_str(stmt, idx++, &info->lang);
276                 *label = g_list_append(*label, info);
277         }
278
279         sqlite3_finalize(stmt);
280
281         return PMINFO_R_OK;
282 }
283
284 static int _pkginfo_get_icon(sqlite3 *db, const char *pkgid, const char *locale,
285                 GList **icon)
286 {
287         static const char query_raw[] =
288                 "SELECT package_icon, package_locale "
289                 "FROM package_localized_info "
290                 "WHERE package=%Q AND package_locale IN (%Q, %Q)";
291         int ret;
292         char *query;
293         sqlite3_stmt *stmt;
294         int idx;
295         icon_x *info;
296
297         query = sqlite3_mprintf(query_raw, pkgid, locale, DEFAULT_LOCALE);
298         if (query == NULL) {
299                 LOGE("out of memory");
300                 return PMINFO_R_ERROR;
301         }
302
303         ret = sqlite3_prepare_v2(db, query, strlen(query),
304                         &stmt, NULL);
305         sqlite3_free(query);
306         if (ret != SQLITE_OK) {
307                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
308                 return PMINFO_R_ERROR;
309         }
310
311         while (sqlite3_step(stmt) == SQLITE_ROW) {
312                 info = calloc(1, sizeof(icon_x));
313                 if (info == NULL) {
314                         LOGE("out of memory");
315                         sqlite3_finalize(stmt);
316                         return PMINFO_R_ERROR;
317                 }
318                 idx = 0;
319                 _save_column_str(stmt, idx++, &info->text);
320                 _save_column_str(stmt, idx++, &info->lang);
321                 *icon = g_list_append(*icon, info);
322         }
323
324         sqlite3_finalize(stmt);
325
326         return PMINFO_R_OK;
327 }
328
329 static int _pkginfo_get_description(sqlite3 *db, const char *pkgid,
330                 const char *locale, GList **description)
331 {
332         static const char query_raw[] =
333                 "SELECT package_description, package_locale "
334                 "FROM package_localized_info "
335                 "WHERE package=%Q AND package_locale IN (%Q, %Q)";
336         int ret;
337         char *query;
338         sqlite3_stmt *stmt;
339         int idx;
340         description_x *info;
341
342         query = sqlite3_mprintf(query_raw, pkgid, locale, DEFAULT_LOCALE);
343         if (query == NULL) {
344                 LOGE("out of memory");
345                 return PMINFO_R_ERROR;
346         }
347
348         ret = sqlite3_prepare_v2(db, query, strlen(query),
349                         &stmt, NULL);
350         sqlite3_free(query);
351         if (ret != SQLITE_OK) {
352                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
353                 return PMINFO_R_ERROR;
354         }
355
356         while (sqlite3_step(stmt) == SQLITE_ROW) {
357                 info = calloc(1, sizeof(description_x));
358                 if (info == NULL) {
359                         LOGE("out of memory");
360                         sqlite3_finalize(stmt);
361                         return PMINFO_R_ERROR;
362                 }
363                 idx = 0;
364                 _save_column_str(stmt, idx++, &info->text);
365                 _save_column_str(stmt, idx++, &info->lang);
366                 *description = g_list_append(*description, info);
367         }
368
369         sqlite3_finalize(stmt);
370
371         return PMINFO_R_OK;
372 }
373
374 static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid,
375                 GList **privileges)
376 {
377         static const char query_raw[] =
378                 "SELECT privilege FROM package_privilege_info WHERE package=%Q";
379         int ret;
380         char *query;
381         sqlite3_stmt *stmt;
382         char *privilege;
383
384         query = sqlite3_mprintf(query_raw, pkgid);
385         if (query == NULL) {
386                 LOGE("out of memory");
387                 return PMINFO_R_ERROR;
388         }
389
390         ret = sqlite3_prepare_v2(db, query, strlen(query),
391                         &stmt, NULL);
392         sqlite3_free(query);
393         if (ret != SQLITE_OK) {
394                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
395                 return PMINFO_R_ERROR;
396         }
397
398         while (sqlite3_step(stmt) == SQLITE_ROW) {
399                 privilege = NULL;
400                 _save_column_str(stmt, 0, &privilege);
401                 if (privilege)
402                         *privileges = g_list_append(*privileges,
403                                         (gpointer)privilege);
404         }
405
406         sqlite3_finalize(stmt);
407
408         return PMINFO_R_OK;
409 }
410
411 static const char join_localized_info[] =
412         " LEFT OUTER JOIN package_localized_info"
413         "  ON pi.package=package_localized_info.package"
414         "  AND package_localized_info.package_locale=?";
415 static const char join_privilege_info[] =
416         " LEFT OUTER JOIN package_privilege_info"
417         "  ON pi.package=package_privilege_info.package";
418
419 static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
420                 const char *locale, char **query, GList **bind_params)
421 {
422         int joined = 0;
423         char buf[MAX_QUERY_LEN] = { '\0' };
424         char buf2[MAX_QUERY_LEN] = { '\0' };
425         char *condition = NULL;
426         size_t len = 0;
427         GSList *list = NULL;
428
429         if (filter == NULL)
430                 return PMINFO_R_OK;
431
432         len += strlen(" WHERE 1=1 ");
433         strncat(buf, " WHERE 1=1 ", MAX_QUERY_LEN - len - 1);
434         for (list = filter->list; list; list = list->next) {
435                 joined |= __get_filter_condition(list->data, &condition,
436                                 bind_params);
437                 if (condition == NULL)
438                         continue;
439
440                 len += strlen(" AND ");
441                 strncat(buf, " AND ", MAX_QUERY_LEN - len - 1);
442
443                 len += strlen(condition);
444                 strncat(buf, condition, sizeof(buf) - len - 1);
445                 free(condition);
446                 condition = NULL;
447         }
448
449         if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
450                 strncat(buf2, join_localized_info, MAX_QUERY_LEN - len - 1);
451                 len += strlen(join_localized_info);
452                 *bind_params = g_list_append(*bind_params, strdup(locale));
453         }
454         if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO) {
455                 strncat(buf2, join_privilege_info, MAX_QUERY_LEN - len - 1);
456                 len += strlen(join_privilege_info);
457         }
458         strncat(buf2, buf, MAX_QUERY_LEN - len - 1);
459
460         *query = strdup(buf2);
461         if (*query == NULL)
462                 return PMINFO_R_ERROR;
463
464         return PMINFO_R_OK;
465 }
466
467 static void __free_packages(gpointer data)
468 {
469         pkgmgrinfo_basic_free_package((package_x *)data);
470 }
471
472 static int __bind_params(sqlite3_stmt *stmt, GList *params)
473 {
474         GList *tmp_list = NULL;
475         int idx = 0;
476         int ret;
477
478         if (stmt == NULL || params == NULL)
479                 return PMINFO_R_EINVAL;
480
481         tmp_list = params;
482         while (tmp_list) {
483                 ret = sqlite3_bind_text(stmt, ++idx, (char *)tmp_list->data, -1, SQLITE_STATIC);
484                 if (ret != SQLITE_OK)
485                         return PMINFO_R_ERROR;
486                 tmp_list = tmp_list->next;
487         }
488
489         return PMINFO_R_OK;
490 }
491
492 static int _pkginfo_get_packages(uid_t uid, const char *locale,
493                 pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages)
494 {
495         static const char query_raw[] =
496                 "SELECT DISTINCT pi.package, pi.package_version, "
497                 "pi.install_location, pi.package_removable, "
498                 "pi.package_preload, pi.package_readonly, pi.package_update, "
499                 "pi.package_appsetting, pi.package_system, pi.package_type, "
500                 "pi.package_size, pi.installed_time, pi.installed_storage, "
501                 "pi.storeclient_id, pi.mainapp_id, pi.package_url, "
502                 "pi.root_path, pi.csc_path, pi.package_nodisplay, "
503                 "pi.package_api_version, pi.package_support_disable, "
504                 "pi.package_tep_name, pi.package_zip_mount_file "
505                 "FROM package_info as pi ";
506         int ret = PMINFO_R_ERROR;
507         int idx = 0;
508         const char *dbpath;
509         char *constraints = NULL;
510         char query[MAX_QUERY_LEN] = { '\0' };
511         package_x *info = NULL;
512         GList *bind_params = NULL;
513         sqlite3 *db;
514         sqlite3_stmt *stmt;
515         pkgmgrinfo_filter_x *tmp_filter = NULL;
516
517         dbpath = getUserPkgParserDBPathUID(uid);
518         if (dbpath == NULL)
519                 return PMINFO_R_ERROR;
520
521         ret = sqlite3_open_v2(dbpath, &db, SQLITE_OPEN_READONLY, NULL);
522         if (ret != SQLITE_OK) {
523                 _LOGD("failed to open db: %d", ret);
524                 return PMINFO_R_ERROR;
525         }
526
527         if (filter != NULL) {
528                 tmp_filter = filter;
529         } else {
530                 ret = pkgmgrinfo_pkginfo_filter_create((void *)&tmp_filter);
531                 if (ret != PMINFO_R_OK) {
532                         _LOGE("Failed to create filter");
533                         return PMINFO_R_ERROR;
534                 }
535         }
536
537         /* add package_disable='false' clause by default */
538         pkgmgrinfo_pkginfo_filter_add_bool(tmp_filter, PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false);
539
540         ret = _get_filtered_query(tmp_filter, locale, &constraints, &bind_params);
541         if (ret != PMINFO_R_OK) {
542                 LOGE("Failed to get WHERE clause");
543                 goto catch;
544         }
545
546         if (constraints)
547                 snprintf(query, MAX_QUERY_LEN - 1, "%s%s", query_raw, constraints);
548         else
549                 snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
550
551         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
552         if (ret != SQLITE_OK) {
553                 LOGE("prepare failed: %s", sqlite3_errmsg(db));
554                 ret = PMINFO_R_ERROR;
555                 goto catch;
556         }
557
558         ret = __bind_params(stmt, bind_params);
559         if (ret != SQLITE_OK) {
560                 LOGE("Failed to bind parameters");
561                 goto catch;
562         }
563
564         while (sqlite3_step(stmt) == SQLITE_ROW) {
565                 info = calloc(1, sizeof(package_x));
566                 if (info == NULL) {
567                         LOGE("out of memory");
568                         sqlite3_finalize(stmt);
569                         sqlite3_close_v2(db);
570                         return PMINFO_R_ERROR;
571                 }
572                 idx = 0;
573                 _save_column_str(stmt, idx++, &info->package);
574                 if (g_hash_table_contains(packages,
575                                         (gconstpointer)info->package)) {
576                         free(info->package);
577                         free(info);
578                         continue;
579                 }
580                 _save_column_str(stmt, idx++, &info->version);
581                 _save_column_str(stmt, idx++, &info->installlocation);
582                 _save_column_str(stmt, idx++, &info->removable);
583                 _save_column_str(stmt, idx++, &info->preload);
584                 _save_column_str(stmt, idx++, &info->readonly);
585                 _save_column_str(stmt, idx++, &info->update);
586                 _save_column_str(stmt, idx++, &info->appsetting);
587                 _save_column_str(stmt, idx++, &info->system);
588                 _save_column_str(stmt, idx++, &info->type);
589                 _save_column_str(stmt, idx++, &info->package_size);
590                 _save_column_str(stmt, idx++, &info->installed_time);
591                 _save_column_str(stmt, idx++, &info->installed_storage);
592                 _save_column_str(stmt, idx++, &info->storeclient_id);
593                 _save_column_str(stmt, idx++, &info->mainapp_id);
594                 _save_column_str(stmt, idx++, &info->package_url);
595                 _save_column_str(stmt, idx++, &info->root_path);
596                 _save_column_str(stmt, idx++, &info->csc_path);
597                 _save_column_str(stmt, idx++, &info->nodisplay_setting);
598                 _save_column_str(stmt, idx++, &info->api_version);
599                 _save_column_str(stmt, idx++, &info->support_disable);
600                 _save_column_str(stmt, idx++, &info->tep_name);
601                 _save_column_str(stmt, idx++, &info->zip_mount_file);
602                 info->for_all_users =
603                         strdup((uid != GLOBAL_USER) ? "false" : "true");
604
605                 if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
606                         if (_pkginfo_get_author(db, info->package,
607                                                 &info->author)) {
608                                 pkgmgrinfo_basic_free_package(info);
609                                 sqlite3_finalize(stmt);
610                                 sqlite3_close_v2(db);
611                                 return PMINFO_R_ERROR;
612                         }
613                 }
614
615                 if (flag & PMINFO_PKGINFO_GET_LABEL) {
616                         if (_pkginfo_get_label(db, info->package, locale,
617                                                 &info->label)) {
618                                 pkgmgrinfo_basic_free_package(info);
619                                 sqlite3_finalize(stmt);
620                                 sqlite3_close_v2(db);
621                                 return PMINFO_R_ERROR;
622                         }
623                 }
624
625                 if (flag & PMINFO_PKGINFO_GET_ICON) {
626                         if (_pkginfo_get_icon(db, info->package, locale,
627                                                 &info->icon)) {
628                                 pkgmgrinfo_basic_free_package(info);
629                                 sqlite3_finalize(stmt);
630                                 sqlite3_close_v2(db);
631                                 return PMINFO_R_ERROR;
632                         }
633                 }
634
635                 if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
636                         if (_pkginfo_get_description(db, info->package, locale,
637                                                 &info->description)) {
638                                 pkgmgrinfo_basic_free_package(info);
639                                 sqlite3_finalize(stmt);
640                                 sqlite3_close_v2(db);
641                                 return PMINFO_R_ERROR;
642                         }
643                 }
644
645                 if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
646                         if (_pkginfo_get_privilege(db, info->package,
647                                                 &info->privileges)) {
648                                 pkgmgrinfo_basic_free_package(info);
649                                 sqlite3_finalize(stmt);
650                                 sqlite3_close_v2(db);
651                                 return PMINFO_R_ERROR;
652                         }
653                 }
654
655                 g_hash_table_insert(packages, (gpointer)info->package,
656                                 (gpointer)info);
657         }
658
659         ret = PMINFO_R_OK;
660
661 catch:
662         if (constraints)
663                 free(constraints);
664
665         if (ret != PMINFO_R_OK && info != NULL)
666                 pkgmgrinfo_basic_free_package(info);
667
668         if (filter == NULL)
669                 pkgmgrinfo_pkginfo_filter_destroy(tmp_filter);
670
671         g_list_free_full(bind_params, free);
672         sqlite3_close_v2(db);
673         sqlite3_finalize(stmt);
674
675         return ret;
676 }
677
678 static int _pkginfo_get_filtered_foreach_pkginfo(uid_t uid,
679                 pkgmgrinfo_filter_x *filter, int flag,
680                 pkgmgrinfo_pkg_list_cb pkg_list_cb, void *user_data)
681 {
682         int ret;
683         char *locale;
684         package_x *pkg;
685         pkgmgr_pkginfo_x info;
686         GHashTable *list;
687         GHashTableIter iter;
688         gpointer value;
689
690         locale = _get_system_locale();
691         if (locale == NULL)
692                 return PMINFO_R_ERROR;
693
694         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
695                         __free_packages);
696         if (list == NULL) {
697                 free(locale);
698                 return PMINFO_R_ERROR;
699         }
700
701         ret = _pkginfo_get_packages(uid, locale, filter, flag, list);
702         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
703                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
704                                 flag, list);
705
706         if (ret != PMINFO_R_OK) {
707                 g_hash_table_destroy(list);
708                 free(locale);
709                 return PMINFO_R_ERROR;
710         }
711
712         g_hash_table_iter_init(&iter, list);
713         while (g_hash_table_iter_next(&iter, NULL, &value)) {
714                 pkg = (package_x *)value;
715                 info.uid = uid;
716                 info.pkg_info = pkg;
717                 info.locale = locale;
718                 if (pkg_list_cb(&info, user_data) < 0)
719                         break;
720         }
721
722         g_hash_table_destroy(list);
723         free(locale);
724
725         return PMINFO_R_OK;
726 }
727
728 API int pkgmgrinfo_pkginfo_get_usr_pkginfo(const char *pkgid, uid_t uid,
729                 pkgmgrinfo_pkginfo_h *handle)
730 {
731         int ret;
732         char *locale;
733         GHashTable *list;
734         pkgmgrinfo_pkginfo_filter_h filter;
735         pkgmgr_pkginfo_x *info;
736
737         if (pkgid == NULL || handle == NULL) {
738                 LOGE("invalid parameter");
739                 return PMINFO_R_EINVAL;
740         }
741
742         locale = _get_system_locale();
743         if (locale == NULL)
744                 return PMINFO_R_ERROR;
745
746         ret = pkgmgrinfo_pkginfo_filter_create(&filter);
747         if (ret != PMINFO_R_OK) {
748                 free(locale);
749                 return ret;
750         }
751
752         ret = pkgmgrinfo_pkginfo_filter_add_string(filter,
753                         PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid);
754         if (ret != PMINFO_R_OK) {
755                 pkgmgrinfo_pkginfo_filter_destroy(filter);
756                 free(locale);
757                 return PMINFO_R_ERROR;
758         }
759
760         list = g_hash_table_new(g_str_hash, g_str_equal);
761         if (list == NULL) {
762                 pkgmgrinfo_pkginfo_filter_destroy(filter);
763                 free(locale);
764                 return PMINFO_R_ERROR;
765         }
766
767         ret = _pkginfo_get_packages(uid, locale, filter,
768                         PMINFO_PKGINFO_GET_ALL, list);
769         if (!g_hash_table_size(list) && uid != GLOBAL_USER)
770                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, filter,
771                                 PMINFO_PKGINFO_GET_ALL, list);
772
773         pkgmgrinfo_pkginfo_filter_destroy(filter);
774         if (ret != PMINFO_R_OK) {
775                 g_hash_table_destroy(list);
776                 free(locale);
777                 return ret;
778         }
779
780         if (!g_hash_table_size(list)) {
781                 _LOGI("pkginfo for [%s] is not existed for user [%d]",
782                                 pkgid, uid);
783                 g_hash_table_destroy(list);
784                 free(locale);
785                 return PMINFO_R_ENOENT;
786         }
787
788         info = calloc(1, sizeof(pkgmgr_pkginfo_x));
789         if (info == NULL) {
790                 _LOGE("out of memory");
791                 g_hash_table_destroy(list);
792                 free(locale);
793                 return PMINFO_R_ERROR;
794         }
795
796         info->uid = uid;
797         info->pkg_info = (package_x *)g_hash_table_lookup(list, pkgid);
798         info->locale = locale;
799
800         /* just free list only */
801         g_hash_table_destroy(list);
802
803         *handle = info;
804
805         return ret;
806 }
807
808 API int pkgmgrinfo_pkginfo_get_pkginfo(const char *pkgid,
809                 pkgmgrinfo_pkginfo_h *handle)
810 {
811         return pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, _getuid(), handle);
812 }
813
814 API int pkgmgrinfo_pkginfo_get_usr_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
815                 int flag, void *user_data, uid_t uid)
816 {
817         if (pkg_list_cb == NULL) {
818                 LOGE("invalid parameter");
819                 return PMINFO_R_EINVAL;
820         }
821
822         return _pkginfo_get_filtered_foreach_pkginfo(uid, NULL, flag,
823                         pkg_list_cb, user_data);
824 }
825
826 API int pkgmgrinfo_pkginfo_get_list_full(pkgmgrinfo_pkg_list_cb pkg_list_cb,
827                 int flag, void *user_data)
828 {
829         return pkgmgrinfo_pkginfo_get_usr_list_full(pkg_list_cb, flag,
830                         user_data, _getuid());
831 }
832
833 API int pkgmgrinfo_pkginfo_get_usr_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
834                 void *user_data, uid_t uid)
835 {
836         if (pkg_list_cb == NULL) {
837                 LOGE("invalid parameter");
838                 return PMINFO_R_EINVAL;
839         }
840
841         return _pkginfo_get_filtered_foreach_pkginfo(uid, NULL,
842                         PMINFO_PKGINFO_GET_ALL, pkg_list_cb, user_data);
843 }
844
845 API int pkgmgrinfo_pkginfo_get_list(pkgmgrinfo_pkg_list_cb pkg_list_cb,
846                 void *user_data)
847 {
848         return pkgmgrinfo_pkginfo_get_usr_list(pkg_list_cb, user_data,
849                         _getuid());
850 }
851
852 API int pkgmgrinfo_pkginfo_get_pkgname(pkgmgrinfo_pkginfo_h handle, char **pkg_name)
853 {
854         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
855
856         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
857         retvm_if(pkg_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
858
859         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
860                 return PMINFO_R_ERROR;
861
862         *pkg_name = (char *)info->pkg_info->package;
863
864         return PMINFO_R_OK;
865 }
866
867 API int pkgmgrinfo_pkginfo_get_pkgid(pkgmgrinfo_pkginfo_h handle, char **pkgid)
868 {
869         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
870
871         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
872         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
873
874         if (info->pkg_info == NULL || info->pkg_info->package == NULL)
875                 return PMINFO_R_ERROR;
876
877         *pkgid = (char *)info->pkg_info->package;
878
879         return PMINFO_R_OK;
880 }
881
882 API int pkgmgrinfo_pkginfo_get_type(pkgmgrinfo_pkginfo_h handle, char **type)
883 {
884         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
885
886         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
887         retvm_if(type == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
888
889         if (info->pkg_info == NULL)
890                 return PMINFO_R_ERROR;
891         if (info->pkg_info->type == NULL)
892                 info->pkg_info->type = strdup("");
893
894         *type = (char *)info->pkg_info->type;
895
896         return PMINFO_R_OK;
897 }
898
899 API int pkgmgrinfo_pkginfo_get_version(pkgmgrinfo_pkginfo_h handle, char **version)
900 {
901         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
902
903         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
904         retvm_if(version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
905
906         if (info->pkg_info == NULL)
907                 return PMINFO_R_ERROR;
908         if (info->pkg_info->version == NULL)
909                 info->pkg_info->version = strdup("");
910
911         *version = (char *)info->pkg_info->version;
912
913         return PMINFO_R_OK;
914 }
915
916 API int pkgmgrinfo_pkginfo_get_api_version(pkgmgrinfo_pkginfo_h handle, char **api_version)
917 {
918         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
919
920         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
921         retvm_if(api_version == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
922
923         if (info->pkg_info == NULL)
924                 return PMINFO_R_ERROR;
925         if (info->pkg_info->api_version == NULL)
926                 info->pkg_info->api_version = strdup("");
927
928         *api_version = (char *)info->pkg_info->api_version;
929
930         return PMINFO_R_OK;
931 }
932
933 API int pkgmgrinfo_pkginfo_get_tep_name(pkgmgrinfo_pkginfo_h handle, char **tep_name)
934 {
935         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
936
937         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
938         retvm_if(tep_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
939
940         if (info->pkg_info == NULL || info->pkg_info->tep_name == NULL)
941                 return PMINFO_R_ERROR;
942
943         *tep_name = (char *)info->pkg_info->tep_name;
944
945         return PMINFO_R_OK;
946 }
947
948 API int pkgmgrinfo_pkginfo_get_zip_mount_file(pkgmgrinfo_pkginfo_h handle, char **zip_mount_file)
949 {
950         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
951
952         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
953         retvm_if(zip_mount_file == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
954
955         if (info->pkg_info == NULL)
956                 return PMINFO_R_ERROR;
957         if (info->pkg_info->zip_mount_file == NULL)
958                 info->pkg_info->zip_mount_file = strdup("");
959
960         *zip_mount_file = (char *)info->pkg_info->zip_mount_file;
961
962         return PMINFO_R_OK;
963 }
964
965 API int pkgmgrinfo_pkginfo_get_install_location(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_install_location *location)
966 {
967         char *val;
968         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
969
970         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
971         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
972
973         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
974                 return PMINFO_R_ERROR;
975
976         val = (char *)info->pkg_info->installlocation;
977         if (strcmp(val, "internal-only") == 0)
978                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
979         else if (strcmp(val, "prefer-external") == 0)
980                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
981         else
982                 *location = PMINFO_INSTALL_LOCATION_AUTO;
983
984         return PMINFO_R_OK;
985 }
986
987 API int pkgmgrinfo_pkginfo_get_package_size(pkgmgrinfo_pkginfo_h handle, int *size)
988 {
989         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
990         char *temp = NULL;
991
992         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
993         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
994
995         if (info->pkg_info == NULL)
996                 return PMINFO_R_ERROR;
997
998         if (info->pkg_info->package_size == NULL) {
999                 temp = strdup("");
1000                 if (temp == NULL) {
1001                         _LOGE("out of memory");
1002                         return PMINFO_R_ERROR;
1003                 } else {
1004                         info->pkg_info->package_size = temp;
1005                 }
1006         }
1007
1008         *size = atoi((char *)info->pkg_info->package_size);
1009
1010         return PMINFO_R_OK;
1011 }
1012
1013 API int pkgmgrinfo_pkginfo_get_total_size(pkgmgrinfo_pkginfo_h handle, int *size)
1014 {
1015         char *pkgid;
1016         char device_path[PKG_STRING_LEN_MAX] = { '\0', };
1017         long long rw_size = 0;
1018         long long ro_size = 0;
1019         long long tmp_size = 0;
1020         long long total_size = 0;
1021         struct stat fileinfo;
1022         int ret;
1023
1024         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1025         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1026
1027         ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1028         if (ret < 0)
1029                 return PMINFO_R_ERROR;
1030
1031         /* RW area */
1032         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/bin", PKG_RW_PATH, pkgid);
1033         if (lstat(device_path, &fileinfo) == 0) {
1034                 if (!S_ISLNK(fileinfo.st_mode)) {
1035                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1036                         if (tmp_size > 0)
1037                                 rw_size += tmp_size;
1038                 }
1039         }
1040
1041         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/info", PKG_RW_PATH, pkgid);
1042         if (lstat(device_path, &fileinfo) == 0) {
1043                 if (!S_ISLNK(fileinfo.st_mode)) {
1044                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1045                         if (tmp_size > 0)
1046                         rw_size += tmp_size;
1047                 }
1048         }
1049
1050         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/res", PKG_RW_PATH, pkgid);
1051         if (lstat(device_path, &fileinfo) == 0) {
1052                 if (!S_ISLNK(fileinfo.st_mode)) {
1053                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1054                         if (tmp_size > 0)
1055                         rw_size += tmp_size;
1056                 }
1057         }
1058
1059         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/data", PKG_RW_PATH, pkgid);
1060         if (lstat(device_path, &fileinfo) == 0) {
1061                 if (!S_ISLNK(fileinfo.st_mode)) {
1062                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1063                         if (tmp_size > 0)
1064                                 rw_size += tmp_size;
1065                 }
1066         }
1067
1068         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/shared", PKG_RW_PATH, pkgid);
1069         if (lstat(device_path, &fileinfo) == 0) {
1070                 if (!S_ISLNK(fileinfo.st_mode)) {
1071                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1072                         if (tmp_size > 0)
1073                                 rw_size += tmp_size;
1074         }
1075         }
1076
1077         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/setting", PKG_RW_PATH, pkgid);
1078         if (lstat(device_path, &fileinfo) == 0) {
1079                 if (!S_ISLNK(fileinfo.st_mode)) {
1080                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1081                         if (tmp_size > 0)
1082                                 rw_size += tmp_size;
1083                 }
1084         }
1085
1086         /* RO area */
1087         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/bin", PKG_RO_PATH, pkgid);
1088         if (lstat(device_path, &fileinfo) == 0) {
1089                 if (!S_ISLNK(fileinfo.st_mode)) {
1090                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1091                         if (tmp_size > 0)
1092                                 ro_size += tmp_size;
1093                 }
1094         }
1095
1096         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/info", PKG_RO_PATH, pkgid);
1097         if (lstat(device_path, &fileinfo) == 0) {
1098                 if (!S_ISLNK(fileinfo.st_mode)) {
1099                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1100                         if (tmp_size > 0)
1101                                 ro_size += tmp_size;
1102                 }
1103         }
1104
1105         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/res", PKG_RO_PATH, pkgid);
1106         if (lstat(device_path, &fileinfo) == 0) {
1107                 if (!S_ISLNK(fileinfo.st_mode)) {
1108                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1109                         if (tmp_size > 0)
1110                                 ro_size += tmp_size;
1111                 }
1112         }
1113
1114         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/data", PKG_RO_PATH, pkgid);
1115         if (lstat(device_path, &fileinfo) == 0) {
1116                 if (!S_ISLNK(fileinfo.st_mode)) {
1117                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1118                         if (tmp_size > 0)
1119                                 ro_size += tmp_size;
1120                 }
1121         }
1122
1123         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/shared", PKG_RO_PATH, pkgid);
1124         if (lstat(device_path, &fileinfo) == 0) {
1125                 if (!S_ISLNK(fileinfo.st_mode)) {
1126                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1127                         if (tmp_size > 0)
1128                                 ro_size += tmp_size;
1129                 }
1130         }
1131
1132         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/setting", PKG_RO_PATH, pkgid);
1133         if (lstat(device_path, &fileinfo) == 0) {
1134                 if (!S_ISLNK(fileinfo.st_mode)) {
1135                         tmp_size = _pkgmgr_calculate_dir_size(device_path);
1136                         if (tmp_size > 0)
1137                                 ro_size += tmp_size;
1138                 }
1139         }
1140
1141         /* Total size */
1142         total_size = rw_size + ro_size;
1143         *size = (int)total_size;
1144
1145         return PMINFO_R_OK;
1146 }
1147
1148 API int pkgmgrinfo_pkginfo_get_data_size(pkgmgrinfo_pkginfo_h handle, int *size)
1149 {
1150         char *pkgid;
1151         char device_path[PKG_STRING_LEN_MAX] = { '\0', };
1152         long long total_size = 0;
1153
1154         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1155         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1156
1157         if (pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid) < 0)
1158                 return PMINFO_R_ERROR;
1159
1160         snprintf(device_path, PKG_STRING_LEN_MAX, "%s%s/data", PKG_RW_PATH, pkgid);
1161         if (access(device_path, R_OK) == 0)
1162                 total_size = _pkgmgr_calculate_dir_size(device_path);
1163         if (total_size < 0)
1164                 return PMINFO_R_ERROR;
1165
1166         *size = (int)total_size;
1167
1168         return PMINFO_R_OK;
1169 }
1170
1171 API int pkgmgrinfo_pkginfo_get_icon(pkgmgrinfo_pkginfo_h handle, char **icon)
1172 {
1173         const char *locale;
1174         icon_x *ptr;
1175         GList *tmp;
1176         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1177
1178         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1179         retvm_if(icon == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1180
1181         locale = info->locale;
1182         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1183
1184         if (info->pkg_info == NULL || info->pkg_info->icon == NULL)
1185                 return PMINFO_R_ERROR;
1186
1187         for (tmp = info->pkg_info->icon; tmp; tmp = tmp->next) {
1188                 ptr = (icon_x *)tmp->data;
1189                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1190                                 strcmp(ptr->lang, locale))
1191                         continue;
1192                 *icon = (char *)ptr->text;
1193                 return PMINFO_R_OK;
1194         }
1195
1196         locale = DEFAULT_LOCALE;
1197         for (tmp = info->pkg_info->icon; tmp; tmp = tmp->next) {
1198                 ptr = (icon_x *)tmp->data;
1199                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1200                                 strcmp(ptr->lang, locale))
1201                         continue;
1202                 *icon = (char *)ptr->text;
1203                 return PMINFO_R_OK;
1204         }
1205
1206         *icon = "";
1207
1208         return PMINFO_R_OK;
1209 }
1210
1211 API int pkgmgrinfo_pkginfo_get_label(pkgmgrinfo_pkginfo_h handle, char **label)
1212 {
1213         const char *locale;
1214         label_x *ptr;
1215         GList *tmp;
1216         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1217
1218         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
1219         retvm_if(label == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
1220
1221         locale = info->locale;
1222         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1223
1224         if (info->pkg_info == NULL || info->pkg_info->label == NULL)
1225                 return PMINFO_R_ERROR;
1226
1227         for (tmp = info->pkg_info->label; tmp != NULL; tmp = tmp->next) {
1228                 ptr = (label_x *)tmp->data;
1229                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1230                                 strcmp(ptr->lang, locale))
1231                         continue;
1232                 *label = (char *)ptr->text;
1233                 return PMINFO_R_OK;
1234         }
1235
1236         locale = DEFAULT_LOCALE;
1237         for (tmp = info->pkg_info->label; tmp != NULL; tmp = tmp->next) {
1238                 ptr = (label_x *)tmp->data;
1239                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1240                                 strcmp(ptr->lang, locale))
1241                         continue;
1242                 *label = (char *)ptr->text;
1243                 return PMINFO_R_OK;
1244         }
1245
1246         *label = "";
1247
1248         return PMINFO_R_OK;
1249 }
1250
1251 API int pkgmgrinfo_pkginfo_get_description(pkgmgrinfo_pkginfo_h handle, char **description)
1252 {
1253         const char *locale;
1254         description_x *ptr;
1255         GList *tmp;
1256         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1257
1258         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1259         retvm_if(description == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1260
1261         locale = info->locale;
1262         retvm_if(locale == NULL, PMINFO_R_ERROR, "manifest locale is NULL");
1263
1264         if (info->pkg_info == NULL || info->pkg_info->description == NULL)
1265                 return PMINFO_R_ERROR;
1266
1267         for (tmp = info->pkg_info->description; tmp; tmp = tmp->next) {
1268                 ptr = (description_x *)tmp->data;
1269                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1270                                 strcmp(ptr->lang, locale))
1271                         continue;
1272                 *description = (char *)ptr->text;
1273                 return PMINFO_R_OK;
1274         }
1275
1276         locale = DEFAULT_LOCALE;
1277         for (tmp = info->pkg_info->description; tmp; tmp = tmp->next) {
1278                 ptr = (description_x *)tmp->data;
1279                 if (ptr == NULL || ptr->text == NULL || ptr->lang == NULL ||
1280                                 strcmp(ptr->lang, locale))
1281                         continue;
1282                 *description = (char *)ptr->text;
1283                 return PMINFO_R_OK;
1284         }
1285
1286         *description = "";
1287
1288         return PMINFO_R_OK;
1289 }
1290
1291 API int pkgmgrinfo_pkginfo_get_author_name(pkgmgrinfo_pkginfo_h handle, char **author_name)
1292 {
1293         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1294         author_x *author;
1295
1296         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1297         retvm_if(author_name == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1298
1299         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1300                 return PMINFO_R_ERROR;
1301
1302         author = (author_x *)info->pkg_info->author->data;
1303         if (author == NULL)
1304                 return PMINFO_R_ERROR;
1305         if (author->text == NULL)
1306                 author->text = strdup("");
1307
1308         *author_name = (char *)author->text;
1309
1310         return PMINFO_R_OK;
1311 }
1312
1313 API int pkgmgrinfo_pkginfo_get_author_email(pkgmgrinfo_pkginfo_h handle, char **author_email)
1314 {
1315         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1316         author_x *author;
1317
1318         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1319         retvm_if(author_email == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1320
1321         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1322                 return PMINFO_R_ERROR;
1323
1324         author = (author_x *)info->pkg_info->author->data;
1325         if (author == NULL)
1326                 return PMINFO_R_ERROR;
1327         if (author->email == NULL)
1328                 author->email = strdup("");
1329
1330         *author_email = (char *)author->email;
1331
1332         return PMINFO_R_OK;
1333 }
1334
1335 API int pkgmgrinfo_pkginfo_get_author_href(pkgmgrinfo_pkginfo_h handle, char **author_href)
1336 {
1337         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1338         author_x *author;
1339
1340         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1341         retvm_if(author_href == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1342
1343         if (info->pkg_info == NULL || info->pkg_info->author == NULL)
1344                 return PMINFO_R_ERROR;
1345
1346         author = (author_x *)info->pkg_info->author->data;
1347         if (author == NULL)
1348                 return PMINFO_R_ERROR;
1349         if (author->href == NULL)
1350                 author->href = strdup("");
1351
1352         *author_href = (char *)author->href;
1353
1354         return PMINFO_R_OK;
1355 }
1356
1357 API int pkgmgrinfo_pkginfo_get_installed_storage(pkgmgrinfo_pkginfo_h handle, pkgmgrinfo_installed_storage *storage)
1358 {
1359         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1360
1361         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1362         retvm_if(storage == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1363
1364         if (info->pkg_info == NULL || info->pkg_info->installed_storage == NULL)
1365                 return PMINFO_R_ERROR;
1366
1367         if (strcmp(info->pkg_info->installed_storage,"installed_internal") == 0)
1368                 *storage = PMINFO_INTERNAL_STORAGE;
1369         else if (strcmp(info->pkg_info->installed_storage,"installed_external") == 0)
1370                 *storage = PMINFO_EXTERNAL_STORAGE;
1371         else
1372                 return PMINFO_R_ERROR;
1373
1374         return PMINFO_R_OK;
1375 }
1376
1377 API int pkgmgrinfo_pkginfo_get_installed_time(pkgmgrinfo_pkginfo_h handle, int *installed_time)
1378 {
1379         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1380
1381         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1382         retvm_if(installed_time == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1383
1384         if (info->pkg_info == NULL || info->pkg_info->installed_time == NULL)
1385                 return PMINFO_R_ERROR;
1386
1387         *installed_time = atoi(info->pkg_info->installed_time);
1388
1389         return PMINFO_R_OK;
1390 }
1391
1392 API int pkgmgrinfo_pkginfo_get_storeclientid(pkgmgrinfo_pkginfo_h handle, char **storeclientid)
1393 {
1394         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1395
1396         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1397         retvm_if(storeclientid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1398
1399         if (info->pkg_info == NULL)
1400                 return PMINFO_R_ERROR;
1401         if (info->pkg_info->storeclient_id == NULL)
1402                 info->pkg_info->storeclient_id = strdup("");
1403
1404         *storeclientid = (char *)info->pkg_info->storeclient_id;
1405
1406         return PMINFO_R_OK;
1407 }
1408
1409 API int pkgmgrinfo_pkginfo_get_mainappid(pkgmgrinfo_pkginfo_h handle, char **mainappid)
1410 {
1411         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1412
1413         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1414         retvm_if(mainappid == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1415
1416         if (info->pkg_info == NULL || info->pkg_info->mainapp_id == NULL)
1417                 return PMINFO_R_ERROR;
1418
1419         *mainappid = (char *)info->pkg_info->mainapp_id;
1420
1421         return PMINFO_R_OK;
1422 }
1423
1424 API int pkgmgrinfo_pkginfo_get_url(pkgmgrinfo_pkginfo_h handle, char **url)
1425 {
1426         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1427
1428         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1429         retvm_if(url == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1430
1431         if (info->pkg_info == NULL)
1432                 return PMINFO_R_ERROR;
1433         if (info->pkg_info->package_url == NULL)
1434                 info->pkg_info->package_url = strdup("");
1435
1436         *url = (char *)info->pkg_info->package_url;
1437
1438         return PMINFO_R_OK;
1439 }
1440
1441 API int pkgmgrinfo_pkginfo_get_size_from_xml(const char *manifest, int *size)
1442 {
1443         const char *val = NULL;
1444         const xmlChar *node;
1445         xmlTextReaderPtr reader;
1446         retvm_if(manifest == NULL, PMINFO_R_EINVAL, "Input argument is NULL\n");
1447         retvm_if(size == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1448
1449         xmlInitParser();
1450         reader = xmlReaderForFile(manifest, NULL, 0);
1451
1452         if (reader){
1453                 if (__child_element(reader, -1)) {
1454                         node = xmlTextReaderConstName(reader);
1455                         if (!node) {
1456                                 _LOGE("xmlTextReaderConstName value is NULL\n");
1457                                 xmlFreeTextReader(reader);
1458                                 xmlCleanupParser();
1459                                 return PMINFO_R_ERROR;
1460                         }
1461
1462                         if (!strcmp(ASC_CHAR(node), "manifest")) {
1463                                 if (xmlTextReaderGetAttribute(reader, XML_CHAR("size")))
1464                                         val = ASC_CHAR(xmlTextReaderGetAttribute(reader, XML_CHAR("size")));
1465
1466                                 if (val) {
1467                                         *size = atoi(val);
1468                                 } else {
1469                                         *size = 0;
1470                                         _LOGE("package size is not specified\n");
1471                                         xmlFreeTextReader(reader);
1472                                         xmlCleanupParser();
1473                                         return PMINFO_R_ERROR;
1474                                 }
1475                         } else {
1476                                 _LOGE("Unable to create xml reader\n");
1477                                 xmlFreeTextReader(reader);
1478                                 xmlCleanupParser();
1479                                 return PMINFO_R_ERROR;
1480                         }
1481                 }
1482         } else {
1483                 _LOGE("xmlReaderForFile value is NULL\n");
1484                 xmlCleanupParser();
1485                 return PMINFO_R_ERROR;
1486         }
1487
1488         xmlFreeTextReader(reader);
1489         xmlCleanupParser();
1490
1491         return PMINFO_R_OK;
1492 }
1493
1494 API int pkgmgrinfo_pkginfo_get_location_from_xml(const char *manifest, pkgmgrinfo_install_location *location)
1495 {
1496         const char *val = NULL;
1497         const xmlChar *node;
1498         xmlTextReaderPtr reader;
1499         retvm_if(manifest == NULL, PMINFO_R_EINVAL, "Input argument is NULL\n");
1500         retvm_if(location == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1501
1502         xmlInitParser();
1503         reader = xmlReaderForFile(manifest, NULL, 0);
1504
1505         if (reader) {
1506                 if ( __child_element(reader, -1)) {
1507                         node = xmlTextReaderConstName(reader);
1508                         if (!node) {
1509                                 _LOGE("xmlTextReaderConstName value is NULL\n");
1510                                 xmlFreeTextReader(reader);
1511                                 xmlCleanupParser();
1512                                 return PMINFO_R_ERROR;
1513                         }
1514
1515                         if (!strcmp(ASC_CHAR(node), "manifest")) {
1516                                 if (xmlTextReaderGetAttribute(reader, XML_CHAR("install-location")))
1517                                         val = ASC_CHAR(xmlTextReaderGetAttribute(reader, XML_CHAR("install-location")));
1518
1519                                 if (val) {
1520                                         if (strcmp(val, "internal-only") == 0)
1521                                                 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
1522                                         else if (strcmp(val, "prefer-external") == 0)
1523                                                 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
1524                                         else
1525                                                 *location = PMINFO_INSTALL_LOCATION_AUTO;
1526                                 }
1527                         } else {
1528                                 _LOGE("Unable to create xml reader\n");
1529                                 xmlFreeTextReader(reader);
1530                                 xmlCleanupParser();
1531                                 return PMINFO_R_ERROR;
1532                         }
1533                 }
1534         } else {
1535                 _LOGE("xmlReaderForFile value is NULL\n");
1536                 xmlCleanupParser();
1537                 return PMINFO_R_ERROR;
1538         }
1539
1540         xmlFreeTextReader(reader);
1541         xmlCleanupParser();
1542
1543         return PMINFO_R_OK;
1544 }
1545
1546
1547 API int pkgmgrinfo_pkginfo_get_root_path(pkgmgrinfo_pkginfo_h handle, char **path)
1548 {
1549         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1550
1551         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1552         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1553
1554         if (info->pkg_info == NULL || info->pkg_info->root_path == NULL)
1555                 return PMINFO_R_ERROR;
1556
1557         *path = (char *)info->pkg_info->root_path;
1558
1559         return PMINFO_R_OK;
1560 }
1561
1562 API int pkgmgrinfo_pkginfo_get_csc_path(pkgmgrinfo_pkginfo_h handle, char **path)
1563 {
1564         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1565
1566         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1567         retvm_if(path == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1568
1569         if (info->pkg_info == NULL)
1570                 return PMINFO_R_ERROR;
1571         if (info->pkg_info->csc_path == NULL)
1572                 info->pkg_info->csc_path = strdup("");
1573
1574         *path = (char *)info->pkg_info->csc_path;
1575
1576         return PMINFO_R_OK;
1577 }
1578
1579
1580 API int pkgmgrinfo_pkginfo_is_accessible(pkgmgrinfo_pkginfo_h handle, bool *accessible)
1581 {
1582         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1583         retvm_if(accessible == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1584
1585 #if 0 //smack issue occured, check later
1586         char *pkgid = NULL;
1587         pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
1588         if (pkgid == NULL){
1589                  _LOGD("invalid func parameters\n");
1590                  return PMINFO_R_ERROR;
1591         }
1592          _LOGD("pkgmgr_get_pkg_external_validation() called\n");
1593
1594         FILE *fp = NULL;
1595         char app_mmc_path[FILENAME_MAX] = { 0, };
1596         char app_dir_path[FILENAME_MAX] = { 0, };
1597         char app_mmc_internal_path[FILENAME_MAX] = { 0, };
1598         snprintf(app_dir_path, FILENAME_MAX,"%s%s", PKG_INSTALLATION_PATH, pkgid);
1599         snprintf(app_mmc_path, FILENAME_MAX,"%s%s", PKG_SD_PATH, pkgid);
1600         snprintf(app_mmc_internal_path, FILENAME_MAX,"%s%s/.mmc", PKG_INSTALLATION_PATH, pkgid);
1601
1602         /*check whether application is in external memory or not */
1603         fp = fopen(app_mmc_path, "r");
1604         if (fp == NULL){
1605                 _LOGD(" app path in external memory not accesible\n");
1606         } else {
1607                 fclose(fp);
1608                 fp = NULL;
1609                 *accessible = 1;
1610                 _LOGD("pkgmgr_get_pkg_external_validation() : SD_CARD \n");
1611                 return PMINFO_R_OK;
1612         }
1613
1614         /*check whether application is in internal or not */
1615         fp = fopen(app_dir_path, "r");
1616         if (fp == NULL) {
1617                 _LOGD(" app path in internal memory not accesible\n");
1618                 *accessible = 0;
1619                 return PMINFO_R_ERROR;
1620         } else {
1621                 fclose(fp);
1622                 /*check whether the application is installed in SD card
1623                 but SD card is not present*/
1624                 fp = fopen(app_mmc_internal_path, "r");
1625                 if (fp == NULL){
1626                         *accessible = 1;
1627                         _LOGD("pkgmgr_get_pkg_external_validation() : INTERNAL_MEM \n");
1628                         return PMINFO_R_OK;
1629                 }
1630                 else{
1631                         *accessible = 0;
1632                         _LOGD("pkgmgr_get_pkg_external_validation() : ERROR_MMC_STATUS \n");
1633                 }
1634                 fclose(fp);
1635         }
1636
1637         _LOGD("pkgmgr_get_pkg_external_validation() end\n");
1638 #endif
1639
1640         *accessible = 1;
1641         return PMINFO_R_OK;
1642 }
1643
1644 API int pkgmgrinfo_pkginfo_is_removable(pkgmgrinfo_pkginfo_h handle, bool *removable)
1645 {
1646         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1647
1648         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1649         retvm_if(removable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1650
1651         if (info->pkg_info == NULL || info->pkg_info->removable == NULL)
1652                 return PMINFO_R_ERROR;
1653
1654         *removable = _get_bool_value(info->pkg_info->removable);
1655
1656         return PMINFO_R_OK;
1657 }
1658
1659 API int pkgmgrinfo_pkginfo_is_movable(pkgmgrinfo_pkginfo_h handle, bool *movable)
1660 {
1661         char *val;
1662         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1663
1664         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1665         retvm_if(movable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1666
1667         if (info->pkg_info == NULL || info->pkg_info->installlocation == NULL)
1668                 return PMINFO_R_ERROR;
1669
1670         val = (char *)info->pkg_info->installlocation;
1671         if (strcmp(val, "internal-only") == 0)
1672                 *movable = 0;
1673         else if (strcmp(val, "prefer-external") == 0)
1674                 *movable = 1;
1675         else
1676                 *movable = 1;
1677
1678         return PMINFO_R_OK;
1679 }
1680
1681 API int pkgmgrinfo_pkginfo_is_preload(pkgmgrinfo_pkginfo_h handle, bool *preload)
1682 {
1683         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1684
1685         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1686         retvm_if(preload == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1687
1688         if (info->pkg_info == NULL || info->pkg_info->preload == NULL)
1689                 return PMINFO_R_ERROR;
1690
1691         *preload = _get_bool_value(info->pkg_info->preload);
1692
1693         return PMINFO_R_OK;
1694 }
1695
1696 API int pkgmgrinfo_pkginfo_is_system(pkgmgrinfo_pkginfo_h handle, bool *system)
1697 {
1698         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1699
1700         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1701         retvm_if(system == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1702
1703         if (info->pkg_info == NULL || info->pkg_info->system == NULL)
1704                 return PMINFO_R_ERROR;
1705
1706         *system = _get_bool_value(info->pkg_info->system);
1707
1708         return PMINFO_R_OK;
1709 }
1710
1711 API int pkgmgrinfo_pkginfo_is_readonly(pkgmgrinfo_pkginfo_h handle, bool *readonly)
1712 {
1713         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1714
1715         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1716         retvm_if(readonly == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1717
1718         if (info->pkg_info == NULL || info->pkg_info->readonly == NULL)
1719                 return PMINFO_R_ERROR;
1720
1721         *readonly = _get_bool_value(info->pkg_info->readonly);
1722
1723         return PMINFO_R_OK;
1724 }
1725
1726 API int pkgmgrinfo_pkginfo_is_update(pkgmgrinfo_pkginfo_h handle, bool *update)
1727 {
1728         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1729
1730         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1731         retvm_if(update == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1732
1733         if (info->pkg_info == NULL || info->pkg_info->update == NULL)
1734                 return PMINFO_R_ERROR;
1735
1736         *update = _get_bool_value(info->pkg_info->update);
1737
1738         return PMINFO_R_OK;
1739 }
1740
1741 API int pkgmgrinfo_pkginfo_is_support_disable(pkgmgrinfo_pkginfo_h handle, bool *support_disable)
1742 {
1743         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1744
1745         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1746         retvm_if(support_disable == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1747
1748         if (info->pkg_info == NULL || info->pkg_info->support_disable == NULL)
1749                 return PMINFO_R_ERROR;
1750
1751         *support_disable = _get_bool_value(info->pkg_info->support_disable);
1752
1753         return PMINFO_R_OK;
1754 }
1755
1756 API int pkgmgrinfo_pkginfo_is_global(pkgmgrinfo_pkginfo_h handle, bool *global)
1757 {
1758         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1759
1760         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1761         retvm_if(global == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
1762
1763         if (info->pkg_info == NULL || info->pkg_info->for_all_users == NULL)
1764                 return PMINFO_R_ERROR;
1765
1766         *global = _get_bool_value(info->pkg_info->for_all_users);
1767
1768         return PMINFO_R_OK;
1769 }
1770
1771 API int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users)
1772 {
1773         return pkgmgrinfo_pkginfo_is_global(handle, for_all_users);
1774 }
1775
1776 API int pkgmgrinfo_pkginfo_destroy_pkginfo(pkgmgrinfo_pkginfo_h handle)
1777 {
1778         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
1779
1780         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL\n");
1781
1782         __cleanup_pkginfo(info);
1783
1784         return PMINFO_R_OK;
1785 }
1786
1787 API int pkgmgrinfo_pkginfo_filter_create(pkgmgrinfo_pkginfo_filter_h *handle)
1788 {
1789         pkgmgrinfo_filter_x *filter;
1790
1791         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle output parameter is NULL\n");
1792
1793         filter = (pkgmgrinfo_filter_x*)calloc(1, sizeof(pkgmgrinfo_filter_x));
1794         if (filter == NULL) {
1795                 _LOGE("Out of Memory!!!");
1796                 return PMINFO_R_ERROR;
1797         }
1798
1799         *handle = filter;
1800
1801         return PMINFO_R_OK;
1802 }
1803
1804 API int pkgmgrinfo_pkginfo_filter_destroy(pkgmgrinfo_pkginfo_filter_h handle)
1805 {
1806         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1807
1808         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1809
1810         if (filter->list) {
1811                 g_slist_foreach(filter->list, __destroy_each_node, NULL);
1812                 g_slist_free(filter->list);
1813         }
1814
1815         free(filter);
1816
1817         return PMINFO_R_OK;
1818 }
1819
1820 API int pkgmgrinfo_pkginfo_filter_add_int(pkgmgrinfo_pkginfo_filter_h handle,
1821                                 const char *property, const int value)
1822 {
1823         char buf[PKG_VALUE_STRING_LEN_MAX] = {'\0'};
1824         char *val;
1825         GSList *link;
1826         int prop;
1827         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1828         pkgmgrinfo_node_x *node;
1829
1830         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1831         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1832
1833         prop = _pminfo_pkginfo_convert_to_prop_int(property);
1834         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_INT ||
1835                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_INT) {
1836                 _LOGE("Invalid Integer Property\n");
1837                 return PMINFO_R_EINVAL;
1838         }
1839         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1840         if (node == NULL) {
1841                 _LOGE("Out of Memory!!!\n");
1842                 return PMINFO_R_ERROR;
1843         }
1844         snprintf(buf, PKG_VALUE_STRING_LEN_MAX - 1, "%d", value);
1845         val = strndup(buf, PKG_VALUE_STRING_LEN_MAX - 1);
1846         if (val == NULL) {
1847                 _LOGE("Out of Memory\n");
1848                 free(node);
1849                 return PMINFO_R_ERROR;
1850         }
1851         node->prop = prop;
1852         node->value = val;
1853         /*If API is called multiple times for same property, we should override the previous values.
1854         Last value set will be used for filtering.*/
1855         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1856         if (link)
1857                 filter->list = g_slist_delete_link(filter->list, link);
1858         filter->list = g_slist_append(filter->list, (gpointer)node);
1859         return PMINFO_R_OK;
1860
1861 }
1862
1863 API int pkgmgrinfo_pkginfo_filter_add_bool(pkgmgrinfo_pkginfo_filter_h handle,
1864                                 const char *property, const bool value)
1865 {
1866         char *val;
1867         GSList *link;
1868         int prop;
1869         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1870         pkgmgrinfo_node_x *node;
1871
1872         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1873         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1874
1875         prop = _pminfo_pkginfo_convert_to_prop_bool(property);
1876         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_BOOL ||
1877                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_BOOL) {
1878                 _LOGE("Invalid Boolean Property\n");
1879                 return PMINFO_R_EINVAL;
1880         }
1881         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1882         if (node == NULL) {
1883                 _LOGE("Out of Memory!!!\n");
1884                 return PMINFO_R_ERROR;
1885         }
1886         if (value)
1887                 val = strndup("true", 4);
1888         else
1889                 val = strndup("false", 5);
1890         if (val == NULL) {
1891                 _LOGE("Out of Memory\n");
1892                 free(node);
1893                 return PMINFO_R_ERROR;
1894         }
1895         node->prop = prop;
1896         node->value = val;
1897         /*If API is called multiple times for same property, we should override the previous values.
1898         Last value set will be used for filtering.*/
1899         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1900         if (link)
1901                 filter->list = g_slist_delete_link(filter->list, link);
1902         filter->list = g_slist_append(filter->list, (gpointer)node);
1903         return PMINFO_R_OK;
1904
1905 }
1906
1907 API int pkgmgrinfo_pkginfo_filter_add_string(pkgmgrinfo_pkginfo_filter_h handle,
1908                                 const char *property, const char *value)
1909 {
1910         char *val;
1911         GSList *link;
1912         int prop;
1913         pkgmgrinfo_filter_x *filter = (pkgmgrinfo_filter_x *)handle;
1914         pkgmgrinfo_node_x *node;
1915
1916         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1917         retvm_if(property == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1918         retvm_if(value == NULL, PMINFO_R_EINVAL, "Filter handle input parameter is NULL\n");
1919
1920         prop = _pminfo_pkginfo_convert_to_prop_str(property);
1921         if (prop < E_PMINFO_PKGINFO_PROP_PACKAGE_MIN_STR ||
1922                 prop > E_PMINFO_PKGINFO_PROP_PACKAGE_MAX_STR) {
1923                 _LOGE("Invalid String Property\n");
1924                 return PMINFO_R_EINVAL;
1925         }
1926         node = (pkgmgrinfo_node_x *)calloc(1, sizeof(pkgmgrinfo_node_x));
1927         if (node == NULL) {
1928                 _LOGE("Out of Memory!!!\n");
1929                 return PMINFO_R_ERROR;
1930         }
1931         if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_AUTO) == 0)
1932                 val = strndup("auto", PKG_STRING_LEN_MAX - 1);
1933         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_INTERNAL) == 0)
1934                 val = strndup("internal-only", PKG_STRING_LEN_MAX - 1);
1935         else if (strcmp(value, PMINFO_PKGINFO_INSTALL_LOCATION_EXTERNAL) == 0)
1936                 val = strndup("prefer-external", PKG_STRING_LEN_MAX - 1);
1937         else if (strcmp(value, "installed_internal") == 0)
1938                 val = strndup("installed_internal", PKG_STRING_LEN_MAX - 1);
1939         else if (strcmp(value, "installed_external") == 0)
1940                 val = strndup("installed_external", PKG_STRING_LEN_MAX - 1);
1941         else
1942                 val = strndup(value, PKG_STRING_LEN_MAX - 1);
1943         if (val == NULL) {
1944                 _LOGE("Out of Memory\n");
1945                 free(node);
1946                 return PMINFO_R_ERROR;
1947         }
1948         node->prop = prop;
1949         node->value = val;
1950         /*If API is called multiple times for same property, we should override the previous values.
1951         Last value set will be used for filtering.*/
1952         link = g_slist_find_custom(filter->list, (gconstpointer)node, __compare_func);
1953         if (link)
1954                 filter->list = g_slist_delete_link(filter->list, link);
1955         filter->list = g_slist_append(filter->list, (gpointer)node);
1956         return PMINFO_R_OK;
1957
1958 }
1959
1960 API int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid)
1961 {
1962         int ret;
1963         char *locale;
1964         GHashTable *list = NULL;
1965
1966         if (handle == NULL || count == NULL) {
1967                 _LOGE("invalid parameter");
1968                 return PMINFO_R_EINVAL;
1969         }
1970
1971         locale = _get_system_locale();
1972         if (locale == NULL)
1973                 return PMINFO_R_ERROR;
1974
1975         list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
1976                         __free_packages);
1977         if (list == NULL) {
1978                 free(locale);
1979                 return PMINFO_R_ERROR;
1980         }
1981
1982         ret = _pkginfo_get_packages(uid, locale,
1983                         (pkgmgrinfo_filter_x *)handle, 0, list);
1984         if (ret == PMINFO_R_OK && uid != GLOBAL_USER)
1985                 ret = _pkginfo_get_packages(GLOBAL_USER, locale, handle, 0,
1986                                 list);
1987
1988         if (ret != PMINFO_R_OK) {
1989                 g_hash_table_destroy(list);
1990                 free(locale);
1991                 return PMINFO_R_ERROR;
1992         }
1993
1994         *count = g_hash_table_size(list);
1995
1996         g_hash_table_destroy(list);
1997         free(locale);
1998
1999         return PMINFO_R_OK;
2000 }
2001
2002 API int pkgmgrinfo_pkginfo_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count)
2003 {
2004         return pkgmgrinfo_pkginfo_usr_filter_count(handle, count, _getuid());
2005 }
2006
2007 API int pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(
2008                 pkgmgrinfo_pkginfo_filter_h handle,
2009                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data, uid_t uid)
2010 {
2011         if (handle == NULL || pkg_cb == NULL) {
2012                 LOGE("invalid parameter");
2013                 return PMINFO_R_EINVAL;
2014         }
2015
2016         return _pkginfo_get_filtered_foreach_pkginfo(uid, handle,
2017                         PMINFO_PKGINFO_GET_ALL, pkg_cb, user_data);
2018 }
2019
2020 API int pkgmgrinfo_pkginfo_filter_foreach_pkginfo(pkgmgrinfo_pkginfo_filter_h handle,
2021                                 pkgmgrinfo_pkg_list_cb pkg_cb, void *user_data)
2022 {
2023         return pkgmgrinfo_pkginfo_usr_filter_foreach_pkginfo(handle, pkg_cb, user_data, _getuid());
2024 }
2025
2026 API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
2027                         pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data)
2028 {
2029         retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
2030         retvm_if(privilege_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
2031         int ret;
2032         const char *privilege;
2033         GList *tmp;
2034         pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
2035
2036         if (info->pkg_info == NULL)
2037                 return PMINFO_R_ERROR;
2038
2039         for (tmp = info->pkg_info->privileges; tmp; tmp = tmp->next) {
2040                 privilege = (const char *)tmp->data;
2041                 if (privilege == NULL)
2042                         continue;
2043                 ret = privilege_func(privilege, user_data);
2044                 if (ret < 0)
2045                         break;
2046         }
2047         return PMINFO_R_OK;
2048 }