Add Error handling in RequestHandler (#117)
[platform/core/appfw/pkgmgr-info.git] / src / appinfo_internal.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdbool.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <dlfcn.h>
9
10 #include <sqlite3.h>
11 #include <glib.h>
12
13 #include "pkgmgr-info.h"
14 #include "pkgmgrinfo_debug.h"
15 #include "pkgmgrinfo_private.h"
16 #include "pkgmgr_parser.h"
17 #include "pkgmgrinfo_internal.h"
18
19 static int __free_applications(gpointer key, gpointer value,
20                                gpointer user_data) {
21   pkgmgrinfo_basic_free_application((application_x *)value);
22   return 0;
23 }
24
25 static void __parse_appcontrol(GList **appcontrol, char *appcontrol_str,
26                                char *visibility, char *id) {
27   char *dup;
28   char *token;
29   char *ptr = NULL;
30   appcontrol_x *ac;
31
32   if (appcontrol_str == NULL) return;
33
34   dup = strdup(appcontrol_str);
35   if (dup == NULL) {
36     _LOGE("out of memory");
37     return;
38   }
39
40   do {
41     ac = calloc(1, sizeof(appcontrol_x));
42     if (ac == NULL) {
43       _LOGE("out of memory");
44       break;
45     }
46     token = strtok_r(dup, "|", &ptr);
47     if (token && strcmp(token, "NULL")) ac->operation = strdup(token);
48     token = strtok_r(NULL, "|", &ptr);
49     if (token && strcmp(token, "NULL")) ac->uri = strdup(token);
50     token = strtok_r(NULL, "|", &ptr);
51     if (token && strcmp(token, "NULL")) ac->mime = strdup(token);
52     ac->visibility = strdup(visibility);
53     ac->id = strdup(id);
54     *appcontrol = g_list_prepend(*appcontrol, ac);
55   } while ((token = strtok_r(NULL, ";", &ptr)));
56
57   free(dup);
58 }
59
60 static int _appinfo_get_splashscreens(sqlite3 *db, const char *appid,
61                                       GList **splashscreens) {
62   static const char query_raw[] =
63       "SELECT src, type, orientation, indicatordisplay, operation, color_depth "
64       "FROM package_app_splash_screen WHERE app_id=%Q";
65   int ret;
66   char *query;
67   sqlite3_stmt *stmt;
68   int idx;
69   splashscreen_x *info;
70
71   query = sqlite3_mprintf(query_raw, appid);
72   if (query == NULL) {
73     LOGE("out of memory");
74     return PMINFO_R_ERROR;
75   }
76
77   ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
78   sqlite3_free(query);
79   if (ret != SQLITE_OK) {
80     LOGE("prepare failed: %s", sqlite3_errmsg(db));
81     return PMINFO_R_ERROR;
82   }
83
84   while (sqlite3_step(stmt) == SQLITE_ROW) {
85     info = calloc(1, sizeof(splashscreen_x));
86     if (info == NULL) {
87       LOGE("out of memory");
88       sqlite3_finalize(stmt);
89       return PMINFO_R_ERROR;
90     }
91     idx = 0;
92     _save_column_str(stmt, idx++, &info->src);
93     _save_column_str(stmt, idx++, &info->type);
94     _save_column_str(stmt, idx++, &info->orientation);
95     _save_column_str(stmt, idx++, &info->indicatordisplay);
96     _save_column_str(stmt, idx++, &info->operation);
97     _save_column_str(stmt, idx++, &info->color_depth);
98     *splashscreens = g_list_prepend(*splashscreens, info);
99   }
100
101   sqlite3_finalize(stmt);
102
103   return PMINFO_R_OK;
104 }
105
106 static int _appinfo_get_metadata(sqlite3 *db, const char *appid,
107                                  GList **metadata) {
108   static const char query_raw[] =
109       "SELECT md_key, md_value "
110       "FROM package_app_app_metadata WHERE app_id=%Q";
111   int ret;
112   char *query;
113   sqlite3_stmt *stmt;
114   int idx;
115   metadata_x *info;
116
117   query = sqlite3_mprintf(query_raw, appid);
118   if (query == NULL) {
119     LOGE("out of memory");
120     return PMINFO_R_ERROR;
121   }
122
123   ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
124   sqlite3_free(query);
125   if (ret != SQLITE_OK) {
126     LOGE("prepare failed: %s", sqlite3_errmsg(db));
127     return PMINFO_R_ERROR;
128   }
129
130   while (sqlite3_step(stmt) == SQLITE_ROW) {
131     info = calloc(1, sizeof(metadata_x));
132     if (info == NULL) {
133       LOGE("out of memory");
134       sqlite3_finalize(stmt);
135       return PMINFO_R_ERROR;
136     }
137     idx = 0;
138     _save_column_str(stmt, idx++, &info->key);
139     _save_column_str(stmt, idx++, &info->value);
140     *metadata = g_list_prepend(*metadata, info);
141   }
142
143   sqlite3_finalize(stmt);
144
145   return PMINFO_R_OK;
146 }
147
148 static int _appinfo_get_app_control(sqlite3 *db, const char *appid,
149                                     GList **appcontrol) {
150   static const char query_raw[] =
151       "SELECT app_control, visibility, app_control_id "
152       "FROM package_app_app_control WHERE app_id=%Q";
153   int ret;
154   int idx;
155   char *query;
156   sqlite3_stmt *stmt;
157   char *str;
158   char *visibility;
159   char *id;
160
161   query = sqlite3_mprintf(query_raw, appid);
162   if (query == NULL) {
163     LOGE("out of memory");
164     return PMINFO_R_ERROR;
165   }
166
167   ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
168   sqlite3_free(query);
169   if (ret != SQLITE_OK) {
170     LOGE("prepare failed: %s", sqlite3_errmsg(db));
171     return PMINFO_R_ERROR;
172   }
173
174   while (sqlite3_step(stmt) == SQLITE_ROW) {
175     str = NULL;
176     visibility = NULL;
177     id = NULL;
178     idx = 0;
179     _save_column_str(stmt, idx++, &str);
180     _save_column_str(stmt, idx++, &visibility);
181     _save_column_str(stmt, idx++, &id);
182     /* TODO: revise */
183     __parse_appcontrol(appcontrol, str, visibility, id);
184     free(str);
185     free(visibility);
186     free(id);
187   }
188
189   sqlite3_finalize(stmt);
190
191   return PMINFO_R_OK;
192 }
193
194 static int _appinfo_get_category(sqlite3 *db, const char *appid,
195                                  GList **category) {
196   static const char query_raw[] =
197       "SELECT category FROM package_app_app_category WHERE app_id=%Q";
198   int ret;
199   char *query;
200   sqlite3_stmt *stmt;
201   char *val;
202
203   query = sqlite3_mprintf(query_raw, appid);
204   if (query == NULL) {
205     LOGE("out of memory");
206     return PMINFO_R_ERROR;
207   }
208
209   ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
210   sqlite3_free(query);
211   if (ret != SQLITE_OK) {
212     LOGE("prepare failed: %s", sqlite3_errmsg(db));
213     return PMINFO_R_ERROR;
214   }
215
216   while (sqlite3_step(stmt) == SQLITE_ROW) {
217     val = NULL;
218     _save_column_str(stmt, 0, &val);
219     if (val) *category = g_list_prepend(*category, (gpointer)val);
220   }
221
222   sqlite3_finalize(stmt);
223
224   return PMINFO_R_OK;
225 }
226
227 static GList *__get_background_category(const char *value) {
228   GList *category_list = NULL;
229   int convert_value = 0;
230   if (!value || strlen(value) == 0) return NULL;
231
232   convert_value = atoi(value);
233   if (convert_value < 0) return NULL;
234
235   if (convert_value & APP_BG_CATEGORY_USER_DISABLE_TRUE_VAL)
236     category_list = g_list_prepend(
237         category_list, strdup(APP_BG_CATEGORY_USER_DISABLE_TRUE_STR));
238   else
239     category_list = g_list_prepend(
240         category_list, strdup(APP_BG_CATEGORY_USER_DISABLE_FALSE_STR));
241
242   if (convert_value & APP_BG_CATEGORY_MEDIA_VAL)
243     category_list =
244         g_list_prepend(category_list, strdup(APP_BG_CATEGORY_MEDIA_STR));
245
246   if (convert_value & APP_BG_CATEGORY_DOWNLOAD_VAL)
247     category_list =
248         g_list_prepend(category_list, strdup(APP_BG_CATEGORY_DOWNLOAD_STR));
249
250   if (convert_value & APP_BG_CATEGORY_BGNETWORK_VAL)
251     category_list =
252         g_list_prepend(category_list, strdup(APP_BG_CATEGORY_BGNETWORK_STR));
253
254   if (convert_value & APP_BG_CATEGORY_LOCATION_VAL)
255     category_list =
256         g_list_prepend(category_list, strdup(APP_BG_CATEGORY_LOCATION_STR));
257
258   if (convert_value & APP_BG_CATEGORY_SENSOR_VAL)
259     category_list =
260         g_list_prepend(category_list, strdup(APP_BG_CATEGORY_SENSOR_STR));
261
262   if (convert_value & APP_BG_CATEGORY_IOTCOMM_VAL)
263     category_list =
264         g_list_prepend(category_list, strdup(APP_BG_CATEGORY_IOTCOMM_STR));
265
266   if (convert_value & APP_BG_CATEGORY_SYSTEM_VAL)
267     category_list =
268         g_list_prepend(category_list, strdup(APP_BG_CATEGORY_SYSTEM));
269
270   return category_list;
271 }
272
273 static int __bind_params(sqlite3_stmt *stmt, GList *params) {
274   GList *tmp_list = NULL;
275   int idx = 0;
276   int ret;
277
278   if (stmt == NULL || params == NULL) return PMINFO_R_EINVAL;
279
280   tmp_list = params;
281   while (tmp_list) {
282     ret = sqlite3_bind_text(stmt, ++idx, (char *)tmp_list->data, -1,
283                             SQLITE_STATIC);
284     if (ret != SQLITE_OK) return PMINFO_R_ERROR;
285     tmp_list = tmp_list->next;
286   }
287
288   return PMINFO_R_OK;
289 }
290
291 static const char join_localized_info[] =
292     " LEFT OUTER JOIN package_app_localized_info"
293     "  ON ai.app_id=package_app_localized_info.app_id"
294     "  AND package_app_localized_info.app_locale=?";
295 static const char join_category[] =
296     " LEFT OUTER JOIN package_app_app_category"
297     " ON ai.app_id=package_app_app_category.app_id";
298 static const char join_app_control[] =
299     " LEFT OUTER JOIN package_app_app_control"
300     "  ON ai.app_id=package_app_app_control.app_id";
301 static const char join_metadata[] =
302     " LEFT OUTER JOIN package_app_app_metadata"
303     "  ON ai.app_id=package_app_app_metadata.app_id ";
304 static const char join_privilege[] =
305     " LEFT OUTER JOIN package_privilege_info"
306     " ON ai.package=package_privilege_info.package ";
307
308 static int _get_filtered_query(pkgmgrinfo_filter_x *filter, const char *locale,
309                                uid_t uid, char **query, GList **bind_params) {
310   int joined = 0;
311   int size;
312   char *condition = NULL;
313   char buf[MAX_QUERY_LEN] = {'\0'};
314   char tmp_query[MAX_QUERY_LEN] = {'\0'};
315   GSList *list;
316
317   if (!filter) return PMINFO_R_OK;
318   strncat(buf, " WHERE 1=1", sizeof(buf) - strlen(buf) - 1);
319
320   for (list = filter->list; list; list = list->next) {
321     joined |= __get_filter_condition(list->data, uid, &condition, bind_params);
322     if (condition == NULL) continue;
323
324     strncat(buf, " AND ", sizeof(buf) - strlen(buf) - 1);
325
326     strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
327     free(condition);
328     condition = NULL;
329   }
330
331   if (filter->list_metadata)
332     strncat(buf, " AND (", sizeof(buf) - strlen(buf) - 1);
333   for (list = filter->list_metadata; list; list = list->next) {
334     joined |=
335         __get_metadata_filter_condition(list->data, &condition, bind_params);
336     if (condition == NULL) continue;
337     strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
338     free(condition);
339     condition = NULL;
340
341     strncat(buf, " OR ", sizeof(buf) - strlen(buf) - 1);
342   }
343   if (filter->list_metadata)
344     strncat(buf, "1=0)", sizeof(buf) - strlen(buf) - 1);
345
346   if (joined & E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO) {
347     strncat(tmp_query, join_localized_info,
348             sizeof(tmp_query) - strlen(tmp_query) - 1);
349     *bind_params = g_list_append(*bind_params, strdup(locale));
350   }
351   if (joined & E_PMINFO_APPINFO_JOIN_CATEGORY)
352     strncat(tmp_query, join_category,
353             sizeof(tmp_query) - strlen(tmp_query) - 1);
354   if (joined & E_PMINFO_APPINFO_JOIN_APP_CONTROL)
355     strncat(tmp_query, join_app_control,
356             sizeof(tmp_query) - strlen(tmp_query) - 1);
357   if (joined & E_PMINFO_APPINFO_JOIN_METADATA)
358     strncat(tmp_query, join_metadata,
359             sizeof(tmp_query) - strlen(tmp_query) - 1);
360   if (joined & E_PMINFO_APPINFO_JOIN_PRIVILEGE)
361     strncat(tmp_query, join_privilege,
362             sizeof(tmp_query) - strlen(tmp_query) - 1);
363
364   size = strlen(tmp_query) + strlen(buf) + 1;
365   *query = (char *)calloc(1, size);
366   if (*query == NULL) return PMINFO_R_ERROR;
367   snprintf(*query, size, "%s%s", tmp_query, buf);
368
369   return PMINFO_R_OK;
370 }
371
372 static bool __check_app_storage_status(pkgmgrinfo_filter_x *tmp_filter) {
373   GSList *tmp_list = NULL;
374   pkgmgrinfo_node_x *tmp_node = NULL;
375   int property = -1;
376
377   if (tmp_filter == NULL) return true;
378
379   property = _pminfo_appinfo_convert_to_prop_bool(
380       PMINFO_APPINFO_PROP_APP_CHECK_STORAGE);
381   for (tmp_list = tmp_filter->list; tmp_list != NULL;
382        tmp_list = g_slist_next(tmp_list)) {
383     tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
384     if (property == tmp_node->prop) {
385       if (strcmp(tmp_node->value, "true") == 0)
386         return true;
387       else
388         return false;
389     }
390   }
391
392   return true;
393 }
394
395 static int _appinfo_get_applications(sqlite3 *db, uid_t db_uid, uid_t uid,
396                                      const char *locale,
397                                      pkgmgrinfo_filter_x *filter, int flag,
398                                      GHashTable *applications) {
399   static const char query_raw[] =
400       "SELECT DISTINCT ai.app_id, ai.app_installed_storage, "
401       "ai.app_external_path";
402   static const char query_basic[] =
403       ", ai.app_component, ai.app_exec, "
404       "ai.app_nodisplay, ai.app_type, ai.app_onboot, "
405       "ai.app_multiple, ai.app_autorestart, ai.app_taskmanage, "
406       "ai.app_hwacceleration, ai.app_screenreader, "
407       "ai.app_mainapp, ai.app_recentimage, ai.app_launchcondition, "
408       "ai.app_indicatordisplay, ai.app_portraitimg, "
409       "ai.app_landscapeimg, ai.app_guestmodevisibility, "
410       "ai.app_permissiontype, ai.app_preload, ai.app_submode, "
411       "ai.app_submode_mainid, ai.app_launch_mode, ai.app_ui_gadget, "
412       "ai.app_support_disable, ai.app_process_pool, "
413       "ai.app_background_category, ai.app_package_type, "
414       "ai.app_root_path, ai.app_api_version, ai.app_effective_appid, "
415       "ai.app_disable, ai.app_splash_screen_display, ai.app_tep_name, "
416       "ai.app_zip_mount_file, ai.component_type, ai.package, "
417       "ai.app_package_system, ai.app_removable, "
418       "ai.app_package_installed_time, ai.app_support_mode, "
419       "ai.app_support_ambient, ai.app_setup_appid";
420   static const char query_uid_info[] =
421       ", ui.is_disabled, ui.is_splash_screen_enabled";
422   static const char query_label[] =
423       ", COALESCE("
424       "(SELECT app_label FROM package_app_localized_info WHERE "
425       "ai.app_id=app_id AND app_locale=?), "
426       "(SELECT app_label FROM package_app_localized_info WHERE "
427       "ai.app_id=app_id AND app_locale='No Locale'))";
428   static const char query_icon[] =
429       ", COALESCE("
430       "(SELECT app_icon FROM package_app_localized_info WHERE ai.app_id=app_id "
431       "AND app_locale=?), "
432       "(SELECT app_icon FROM package_app_localized_info WHERE ai.app_id=app_id "
433       "AND app_locale='No Locale'))";
434   static const char query_from_clause[] = " FROM package_app_info as ai";
435   static const char query_uid_info_clause[] =
436       " LEFT OUTER JOIN package_app_info_for_uid AS ui "
437       "ON (ai.app_id=ui.app_id AND ui.uid=?)";
438   int ret = PMINFO_R_ERROR;
439   int idx;
440   char *bg_category_str = NULL;
441   char *constraint = NULL;
442   char *tmp_record = NULL;
443   char query[MAX_QUERY_LEN] = {'\0'};
444   char buf[BUFSIZE] = {'\0'};
445   application_x *info = NULL;
446   GList *bind_params = NULL;
447   sqlite3_stmt *stmt = NULL;
448   bool is_check_storage = true;
449   const uid_t global_user_uid = GLOBAL_USER;
450
451   snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
452
453   if (flag & PMINFO_APPINFO_GET_BASICINFO) {
454     strncat(query, query_basic, sizeof(query) - strlen(query) - 1);
455     strncat(query, query_uid_info, sizeof(query) - strlen(query) - 1);
456   }
457   if (flag & PMINFO_APPINFO_GET_LABEL) {
458     strncat(query, query_label, sizeof(query) - strlen(query) - 1);
459     bind_params = g_list_append(bind_params, strdup(locale));
460   }
461   if (flag & PMINFO_APPINFO_GET_ICON) {
462     strncat(query, query_icon, sizeof(query) - strlen(query) - 1);
463     bind_params = g_list_append(bind_params, strdup(locale));
464   }
465
466   snprintf(buf, MAX_QUERY_LEN - 1, "%d", uid);
467   bind_params = g_list_append(bind_params, strdup(buf));
468
469   is_check_storage = __check_app_storage_status(filter);
470
471   ret = _get_filtered_query(filter, locale, uid, &constraint, &bind_params);
472   if (ret != PMINFO_R_OK) {
473     LOGE("Failed to get WHERE clause");
474     goto catch;
475   }
476   strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1);
477
478   strncat(query, query_uid_info_clause, sizeof(query) - strlen(query) - 1);
479
480   if (constraint) strncat(query, constraint, sizeof(query) - strlen(query) - 1);
481
482   ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
483   if (ret != SQLITE_OK) {
484     LOGE("prepare failed: %s", sqlite3_errmsg(db));
485     ret = PMINFO_R_ERROR;
486     goto catch;
487   }
488
489   if (g_list_length(bind_params) != 0) {
490     ret = __bind_params(stmt, bind_params);
491     if (ret != SQLITE_OK) {
492       LOGE("Failed to bind parameters");
493       goto catch;
494     }
495   }
496
497   while (sqlite3_step(stmt) == SQLITE_ROW) {
498     info = calloc(1, sizeof(application_x));
499     if (info == NULL) {
500       LOGE("out of memory");
501       ret = PMINFO_R_ERROR;
502       goto catch;
503     }
504     info->locale = strdup(locale);
505     if (info->locale == NULL) {
506       LOGE("Out of memory");
507       ret = PMINFO_R_ERROR;
508       goto catch;
509     }
510
511     idx = 0;
512     _save_column_str(stmt, idx++, &info->appid);
513     _save_column_str(stmt, idx++, &info->installed_storage);
514     _save_column_str(stmt, idx++, &info->external_path);
515
516     if (flag & PMINFO_APPINFO_GET_BASICINFO) {
517       _save_column_str(stmt, idx++, &info->component);
518       _save_column_str(stmt, idx++, &info->exec);
519       _save_column_str(stmt, idx++, &info->nodisplay);
520       _save_column_str(stmt, idx++, &info->type);
521       _save_column_str(stmt, idx++, &info->onboot);
522       _save_column_str(stmt, idx++, &info->multiple);
523       _save_column_str(stmt, idx++, &info->autorestart);
524       _save_column_str(stmt, idx++, &info->taskmanage);
525       _save_column_str(stmt, idx++, &info->hwacceleration);
526       _save_column_str(stmt, idx++, &info->screenreader);
527       _save_column_str(stmt, idx++, &info->mainapp);
528       _save_column_str(stmt, idx++, &info->recentimage);
529       _save_column_str(stmt, idx++, &info->launchcondition);
530       _save_column_str(stmt, idx++, &info->indicatordisplay);
531       _save_column_str(stmt, idx++, &info->portraitimg);
532       _save_column_str(stmt, idx++, &info->landscapeimg);
533       _save_column_str(stmt, idx++, &info->guestmode_visibility);
534       _save_column_str(stmt, idx++, &info->permission_type);
535       _save_column_str(stmt, idx++, &info->preload);
536       _save_column_str(stmt, idx++, &info->submode);
537       _save_column_str(stmt, idx++, &info->submode_mainid);
538       _save_column_str(stmt, idx++, &info->launch_mode);
539       _save_column_str(stmt, idx++, &info->ui_gadget);
540       _save_column_str(stmt, idx++, &info->support_disable);
541       _save_column_str(stmt, idx++, &info->process_pool);
542       _save_column_str(stmt, idx++, &bg_category_str);
543       _save_column_str(stmt, idx++, &info->package_type);
544       _save_column_str(stmt, idx++, &info->root_path);
545       _save_column_str(stmt, idx++, &info->api_version);
546       _save_column_str(stmt, idx++, &info->effective_appid);
547       _save_column_str(stmt, idx++, &info->is_disabled);
548       _save_column_str(stmt, idx++, &info->splash_screen_display);
549       _save_column_str(stmt, idx++, &info->tep_name);
550       _save_column_str(stmt, idx++, &info->zip_mount_file);
551       _save_column_str(stmt, idx++, &info->component_type);
552       _save_column_str(stmt, idx++, &info->package);
553       _save_column_str(stmt, idx++, &info->package_system);
554       _save_column_str(stmt, idx++, &info->removable);
555       _save_column_str(stmt, idx++, &info->package_installed_time);
556       _save_column_str(stmt, idx++, &info->support_mode);
557       _save_column_str(stmt, idx++, &info->support_ambient);
558       _save_column_str(stmt, idx++, &info->setup_appid);
559       info->background_category = __get_background_category(bg_category_str);
560       free(bg_category_str);
561       bg_category_str = NULL;
562     }
563
564     info->for_all_users =
565         strdup((db_uid != global_user_uid) ? "false" : "true");
566
567     if (db_uid != global_user_uid) {
568       idx = idx + 2;
569     } else {
570       tmp_record = NULL;
571       _save_column_str(stmt, idx++, &tmp_record);
572       if (tmp_record != NULL) {
573         if (strcasecmp(info->is_disabled, "false") == 0 &&
574             strcasecmp(tmp_record, "false") == 0) {
575           free(info->is_disabled);
576           info->is_disabled = tmp_record;
577         } else {
578           free(tmp_record);
579         }
580       }
581       tmp_record = NULL;
582       _save_column_str(stmt, idx++, &tmp_record);
583       if (tmp_record != NULL) {
584         if (strcasecmp(info->splash_screen_display, "false") == 0 &&
585             strcasecmp(tmp_record, "false") == 0) {
586           free(info->splash_screen_display);
587           info->splash_screen_display = tmp_record;
588         } else {
589           free(tmp_record);
590         }
591       }
592     }
593
594     if (flag & PMINFO_APPINFO_GET_LABEL) {
595       tmp_record = NULL;
596       _save_column_str(stmt, idx++, &tmp_record);
597       if (_add_label_info_into_list(locale, tmp_record, &info->label)) {
598         ret = PMINFO_R_ERROR;
599         goto catch;
600       }
601     }
602
603     if (flag & PMINFO_APPINFO_GET_ICON) {
604       tmp_record = NULL;
605       _save_column_str(stmt, idx++, &tmp_record);
606       if (_add_icon_info_into_list(locale, tmp_record, &info->icon)) {
607         ret = PMINFO_R_ERROR;
608         goto catch;
609       }
610     }
611
612     if (flag & PMINFO_APPINFO_GET_CATEGORY) {
613       if (_appinfo_get_category(db, info->appid, &info->category)) {
614         ret = PMINFO_R_ERROR;
615         goto catch;
616       }
617     }
618
619     if (flag & PMINFO_APPINFO_GET_APP_CONTROL) {
620       if (_appinfo_get_app_control(db, info->appid, &info->appcontrol)) {
621         ret = PMINFO_R_ERROR;
622         goto catch;
623       }
624     }
625
626     if (flag & PMINFO_APPINFO_GET_METADATA) {
627       if (_appinfo_get_metadata(db, info->appid, &info->metadata)) {
628         ret = PMINFO_R_ERROR;
629         goto catch;
630       }
631     }
632
633     if (flag & PMINFO_APPINFO_GET_SPLASH_SCREEN) {
634       if (_appinfo_get_splashscreens(db, info->appid, &info->splashscreens)) {
635         ret = PMINFO_R_ERROR;
636         goto catch;
637       }
638     }
639
640     if (is_check_storage &&
641         __appinfo_check_installed_storage(info) != PMINFO_R_OK) {
642       ret = PMINFO_R_ERROR;
643       pkgmgrinfo_basic_free_application(info);
644       info = NULL;
645       continue;
646     }
647
648     g_hash_table_insert(applications, (gpointer)info->appid, (gpointer)info);
649   }
650
651   ret = PMINFO_R_OK;
652
653   catch : sqlite3_finalize(stmt);
654
655   if (constraint) free(constraint);
656
657   if (ret != PMINFO_R_OK && info != NULL)
658     pkgmgrinfo_basic_free_application(info);
659
660   g_list_free_full(bind_params, free);
661
662   return ret;
663 }
664
665 API int appinfo_internal_filter_get_list(sqlite3 *db,
666                                          pkgmgrinfo_appinfo_filter_h filter,
667                                          uid_t uid, const char *locale,
668                                          GHashTable **appinfo_list) {
669   int ret;
670   GHashTable *list;
671
672   if (db == NULL || filter == NULL || appinfo_list == NULL) {
673     // TODO: add log
674     return PMINFO_R_EINVAL;
675   }
676
677   list = g_hash_table_new(g_str_hash, g_str_equal);
678   if (list == NULL) return PMINFO_R_ERROR;
679
680   ret = _appinfo_get_applications(db, uid, uid, locale, filter,
681                                   PMINFO_APPINFO_GET_ALL, list);
682   if (!g_hash_table_size(list) && uid != GLOBAL_USER)
683     ret = _appinfo_get_applications(db, GLOBAL_USER, uid, locale, filter,
684                                     PMINFO_APPINFO_GET_ALL, list);
685
686   if (ret != PMINFO_R_OK) {
687     g_hash_table_foreach_remove(list, __free_applications, NULL);
688     g_hash_table_destroy(list);
689     return ret;
690   }
691
692   if (!g_hash_table_size(list)) {
693     // TODO: add logs that failed to find appid
694     g_hash_table_destroy(list);
695     return PMINFO_R_ENOENT;
696   }
697
698   *appinfo_list = list;
699   return ret;
700 }