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