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