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