Fix "_APPINFO_PROP_PKG_DISABLE" filter check logic
[platform/core/appfw/pkgmgr-info.git] / src / server / appinfo_internal.cc
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdbool.h>
20 #include <string.h>
21 #include <ctype.h>
22 #include <unistd.h>
23 #include <sys/types.h>
24 #include <dlfcn.h>
25 #include <sqlite3.h>
26 #include <glib.h>
27
28 #include <memory>
29 #include <vector>
30
31 #include "pkgmgr-info.h"
32 #include "pkgmgrinfo_debug.h"
33 #include "pkgmgrinfo_private.h"
34 #include "pkgmgr_parser.h"
35 #include "pkgmgrinfo_internal.h"
36
37 namespace {
38
39 char* GetCString(int idx, const tizen_base::Database::Result::Record& rec) {
40   std::optional<std::string> str = rec.GetString(idx);
41   if (!str)
42     return nullptr;
43
44   return strdup(str->c_str());
45 }
46
47 void ParseAppControl(GList** appcontrol,
48     const char* appcontrol_str, const char* visibility, const char* id) {
49   char* dup;
50   char* token;
51   char* ptr = nullptr;
52   appcontrol_x* ac;
53
54   if (appcontrol_str == nullptr)
55     return;
56
57   dup = strdup(appcontrol_str);
58   if (dup == nullptr) {
59     _LOGE("out of memory");
60     return;
61   }
62
63   do {
64     ac = static_cast<appcontrol_x*>(calloc(1, sizeof(appcontrol_x)));
65     if (ac == nullptr) {
66       _LOGE("out of memory");
67       break;
68     }
69     token = strtok_r(dup, "|", &ptr);
70     if (token && strcmp(token, "NULL"))
71       ac->operation = strdup(token);
72     token = strtok_r(nullptr, "|", &ptr);
73     if (token && strcmp(token, "NULL"))
74       ac->uri = strdup(token);
75     token = strtok_r(nullptr, "|", &ptr);
76     if (token && strcmp(token, "NULL"))
77       ac->mime = strdup(token);
78     ac->visibility = strdup(visibility);
79     ac->id = strdup(id);
80     *appcontrol = g_list_prepend(*appcontrol, ac);
81   } while ((token = strtok_r(nullptr, ";", &ptr)));
82
83   free(dup);
84 }
85
86 int GetSplashScreens(const tizen_base::Database& db,
87     const char* appid, GList** splashscreens) {
88   auto q = tizen_base::Database::Sql(
89       "SELECT src, type, orientation, indicatordisplay, "
90       "operation, color_depth "
91       "FROM package_app_splash_screen WHERE app_id=?")
92       .Bind(appid);
93
94   auto r = db.Exec(q);
95   if (!r) {
96     _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
97     return PMINFO_R_ERROR;
98   }
99
100   for (const auto& rec : r) {
101     splashscreen_x* info = static_cast<splashscreen_x*>(
102         calloc(1, sizeof(splashscreen_x)));
103     if (info == nullptr) {
104       LOGE("out of memory");
105       return PMINFO_R_ERROR;
106     }
107
108     int idx = 0;
109     info->src = GetCString(idx++, rec);
110     info->type = GetCString(idx++, rec);
111     info->orientation = GetCString(idx++, rec);
112     info->indicatordisplay = GetCString(idx++, rec);
113     info->operation = GetCString(idx++, rec);
114     info->color_depth = GetCString(idx++, rec);
115     *splashscreens = g_list_prepend(*splashscreens, info);
116   }
117
118   return PMINFO_R_OK;
119 }
120
121 int GetMetadata(const tizen_base::Database& db,
122     const char* appid, GList** metadata) {
123   auto q = tizen_base::Database::Sql(
124       "SELECT md_key, md_value "
125       "FROM package_app_app_metadata WHERE app_id=?")
126       .Bind(appid);
127
128   auto r = db.Exec(q);
129   if (!r) {
130     _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
131     return PMINFO_R_ERROR;
132   }
133
134   for (const auto& rec : r) {
135     metadata_x* info = static_cast<metadata_x*>(
136         calloc(1, sizeof(metadata_x)));
137     if (info == nullptr) {
138       LOGE("out of memory");
139       return PMINFO_R_ERROR;
140     }
141
142     int idx = 0;
143     info->key = GetCString(idx++, rec);
144     info->value = GetCString(idx++, rec);
145     *metadata = g_list_prepend(*metadata, info);
146   }
147
148   return PMINFO_R_OK;
149 }
150
151 int GetAppControl(const tizen_base::Database& db,
152     const char* appid, GList** appcontrol) {
153   auto q = tizen_base::Database::Sql(
154       "SELECT app_control, visibility, app_control_id "
155       "FROM package_app_app_control WHERE app_id=?")
156       .Bind(appid);
157
158   auto r = db.Exec(q);
159   if (!r) {
160     _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
161     return PMINFO_R_ERROR;
162   }
163
164   for (const auto& rec : r) {
165     ParseAppControl(appcontrol, rec.GetString(0)->c_str(),
166         rec.GetString(1)->c_str(), rec.GetString(2)->c_str());
167   }
168
169   return PMINFO_R_OK;
170 }
171
172 int GetCategory(const tizen_base::Database& db,
173     const char* appid, GList** category) {
174   auto q = tizen_base::Database::Sql(
175       "SELECT category "
176       "FROM package_app_app_category WHERE app_id=?")
177       .Bind(appid);
178   auto r = db.Exec(q);
179   if (!r) {
180     _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
181     return PMINFO_R_ERROR;
182   }
183
184   for (const auto& rec : r) {
185     char* val = GetCString(0, rec);
186     if (val)
187       *category = g_list_prepend(*category, (gpointer)val);
188   }
189
190   return PMINFO_R_OK;
191 }
192
193 int GetResControl(const tizen_base::Database& db, const char* appid,
194     GList** res_control) {
195   auto q = tizen_base::Database::Sql(
196       "SELECT res_type, min_res_version, max_res_version, auto_close "
197       "FROM package_app_res_control WHERE app_id=?")
198       .Bind(appid);
199
200   auto r = db.Exec(q);
201   if (!r) {
202     _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
203     return PMINFO_R_ERROR;
204   }
205
206   for (const auto& rec : r) {
207     res_control_x* info = static_cast<res_control_x*>(
208         calloc(1, sizeof(res_control_x)));
209     if (info == nullptr) {
210       LOGE("out of memory");
211       return PMINFO_R_ERROR;
212     }
213
214     int idx = 0;
215     info->res_type = GetCString(idx++, rec);
216     info->min_res_version = GetCString(idx++, rec);
217     info->max_res_version = GetCString(idx++, rec);
218     info->auto_close = GetCString(idx++, rec);
219     *res_control = g_list_prepend(*res_control, info);
220   }
221
222   return PMINFO_R_OK;
223 }
224
225 GList* __get_background_category(const char* value) {
226   GList* category_list = nullptr;
227   int convert_value = 0;
228
229   if (!value || strlen(value) == 0)
230     return nullptr;
231
232   convert_value = atoi(value);
233   if (convert_value < 0)
234     return nullptr;
235
236   if (convert_value & APP_BG_CATEGORY_USER_DISABLE_TRUE_VAL)
237     category_list = g_list_prepend(category_list,
238         strdup(APP_BG_CATEGORY_USER_DISABLE_TRUE_STR));
239   else
240     category_list = g_list_prepend(category_list,
241         strdup(APP_BG_CATEGORY_USER_DISABLE_FALSE_STR));
242
243   if (convert_value & APP_BG_CATEGORY_MEDIA_VAL)
244     category_list = g_list_prepend(category_list,
245         strdup(APP_BG_CATEGORY_MEDIA_STR));
246
247   if (convert_value & APP_BG_CATEGORY_DOWNLOAD_VAL)
248     category_list = g_list_prepend(category_list,
249         strdup(APP_BG_CATEGORY_DOWNLOAD_STR));
250
251   if (convert_value & APP_BG_CATEGORY_BGNETWORK_VAL)
252     category_list = g_list_prepend(category_list,
253         strdup(APP_BG_CATEGORY_BGNETWORK_STR));
254
255   if (convert_value & APP_BG_CATEGORY_LOCATION_VAL)
256     category_list = g_list_prepend(category_list,
257         strdup(APP_BG_CATEGORY_LOCATION_STR));
258
259   if (convert_value & APP_BG_CATEGORY_SENSOR_VAL)
260     category_list = g_list_prepend(category_list,
261         strdup(APP_BG_CATEGORY_SENSOR_STR));
262
263   if (convert_value & APP_BG_CATEGORY_IOTCOMM_VAL)
264     category_list = g_list_prepend(category_list,
265         strdup(APP_BG_CATEGORY_IOTCOMM_STR));
266
267   if (convert_value & APP_BG_CATEGORY_SYSTEM_VAL)
268     category_list = g_list_prepend(category_list,
269         strdup(APP_BG_CATEGORY_SYSTEM));
270
271   return category_list;
272 }
273
274 constexpr const char join_localized_info[] =
275     " LEFT OUTER JOIN package_app_localized_info"
276     " ON ai.app_id=package_app_localized_info.app_id"
277     " AND package_app_localized_info.app_locale=?";
278 constexpr const char join_category[] =
279     " LEFT OUTER JOIN package_app_app_category"
280     " ON ai.app_id=package_app_app_category.app_id";
281 constexpr const char join_app_control[] =
282     " LEFT OUTER JOIN package_app_app_control"
283     " ON ai.app_id=package_app_app_control.app_id";
284 constexpr const char join_metadata[] =
285     " LEFT OUTER JOIN package_app_app_metadata"
286     " ON ai.app_id=package_app_app_metadata.app_id ";
287 constexpr const char join_privilege[] =
288     " LEFT OUTER JOIN package_privilege_info"
289     " ON ai.package=package_privilege_info.package ";
290
291 int GetFilteredQuery(pkgmgrinfo_filter_x* filter, const char* locale,
292     uid_t uid, std::string& query, std::list<std::string>& bind_params) {
293   int joined = 0;
294   char* condition = nullptr;
295
296   if (!filter)
297     return PMINFO_R_OK;
298
299   if (filter->cache_flag) {
300     joined = E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO |
301       E_PMINFO_APPINFO_JOIN_CATEGORY |
302       E_PMINFO_APPINFO_JOIN_APP_CONTROL |
303       E_PMINFO_APPINFO_JOIN_METADATA |
304       E_PMINFO_APPINFO_JOIN_PRIVILEGE;
305   }
306
307   std::string buf = " WHERE 1=1";
308   GList* tmp_params = nullptr;
309   for (GSList* list = filter->list; list; list = list->next) {
310     joined |= __get_filter_condition(list->data,
311         uid, &condition, &tmp_params);
312     if (condition == nullptr)
313       continue;
314
315     buf += " AND ";
316     buf += condition;
317     free(condition);
318     condition = nullptr;
319   }
320
321   if (filter->list_metadata)
322     buf += " AND (";
323   for (GSList* list = filter->list_metadata; list; list = list->next) {
324     joined |= __get_metadata_filter_condition(list->data,
325         &condition, &tmp_params);
326     if (condition == nullptr)
327       continue;
328     buf += condition;
329     free(condition);
330     condition = nullptr;
331     buf += " OR ";
332   }
333
334   if (filter->list_metadata)
335     buf += "1=0)";
336
337   std::string tmp_query;
338   if (joined & E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO) {
339     tmp_query += join_localized_info;
340     bind_params.push_back(locale);
341   }
342
343   if (joined & E_PMINFO_APPINFO_JOIN_CATEGORY)
344     tmp_query += join_category;
345   if (joined & E_PMINFO_APPINFO_JOIN_APP_CONTROL)
346     tmp_query += join_app_control;
347   if (joined & E_PMINFO_APPINFO_JOIN_METADATA)
348     tmp_query += join_metadata;
349   if (joined & E_PMINFO_APPINFO_JOIN_PRIVILEGE)
350     tmp_query += join_privilege;
351
352   for (GList* l = tmp_params; l != nullptr; l = l->next)
353     bind_params.push_back(reinterpret_cast<char*>(l->data));
354
355   query = tmp_query + buf;
356   g_list_free_full(tmp_params, free);
357
358   return PMINFO_R_OK;
359 }
360
361 bool __check_app_storage_status(pkgmgrinfo_filter_x* tmp_filter) {
362   GSList* tmp_list = nullptr;
363   pkgmgrinfo_node_x* tmp_node = nullptr;
364   int property = -1;
365
366   if (tmp_filter == nullptr)
367     return true;
368
369   if (tmp_filter->cache_flag)
370     return false;
371
372   property = _pminfo_appinfo_convert_to_prop_bool(
373       PMINFO_APPINFO_PROP_APP_CHECK_STORAGE);
374   for (tmp_list = tmp_filter->list; tmp_list != nullptr;
375       tmp_list = g_slist_next(tmp_list)) {
376     tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
377     if (property == tmp_node->prop) {
378       if (strcmp(tmp_node->value, "true") == 0)
379         return true;
380       else
381         return false;
382     }
383   }
384
385   return true;
386 }
387
388 enum class PackageDisableFilterStatus {
389   None,
390   True,
391   False
392 };
393
394 PackageDisableFilterStatus GetPackageDisableFilterStatus(
395     const pkgmgrinfo_filter_x* filter) {
396   GSList* tmp_list = nullptr;
397   pkgmgrinfo_node_x* tmp_node = nullptr;
398   int property = -1;
399
400   property = _pminfo_appinfo_convert_to_prop_bool(
401         PMINFO_APPINFO_PROP_PKG_DISABLE);
402   for (tmp_list = filter->list; tmp_list != nullptr;
403       tmp_list = g_slist_next(tmp_list)) {
404     tmp_node = reinterpret_cast<pkgmgrinfo_node_x*>(tmp_list->data);
405     if (property != tmp_node->prop)
406       continue;
407
408     return strcasecmp(tmp_node->value, "true") == 0 ?
409         PackageDisableFilterStatus::True : PackageDisableFilterStatus::False;
410   }
411
412   return PackageDisableFilterStatus::None;
413 }
414
415 bool CheckPkgDisableFilter(PackageDisableFilterStatus expected,
416     const char* package_disable, application_x* app_info) {
417   if (!package_disable)
418     return true;
419
420   PackageDisableFilterStatus result = strcasecmp(package_disable, "true") == 0 ?
421       PackageDisableFilterStatus::True : PackageDisableFilterStatus::False;
422
423   if (expected == result)
424     return true;
425
426   if (result == PackageDisableFilterStatus::True)
427     LOGW("The package [%s] to which the application [%s] belongs is disabled",
428         app_info->package, app_info->appid);
429
430   return false;
431 }
432
433 bool CheckAppDisableFilter(const pkgmgrinfo_filter_x* filter,
434     const application_x* app_info) {
435   GSList* tmp_list = nullptr;
436   pkgmgrinfo_node_x* tmp_node = nullptr;
437   int property = -1;
438
439   property = _pminfo_appinfo_convert_to_prop_bool(
440         PMINFO_APPINFO_PROP_APP_DISABLE);
441   for (tmp_list = filter->list; tmp_list != nullptr;
442       tmp_list = g_slist_next(tmp_list)) {
443     tmp_node = reinterpret_cast<pkgmgrinfo_node_x*>(tmp_list->data);
444     if (property != tmp_node->prop)
445       continue;
446
447     if (strcasecmp(tmp_node->value, app_info->is_disabled) == 0)
448       return true;
449
450     if (strcasecmp(app_info->is_disabled, "true") == 0)
451       LOGW("The application [%s] is disabled", app_info->appid);
452
453     return false;
454   }
455   return true;
456 }
457
458 int DoGetAppInfo(const tizen_base::Database& db, uid_t db_uid, uid_t uid,
459     const char* locale, pkgmgrinfo_filter_x* filter, int flag,
460     std::vector<std::shared_ptr<application_x>>& applications) {
461   static const char query_raw[] =
462       "SELECT DISTINCT ai.app_id, ai.app_installed_storage, "
463       "ai.app_external_path";
464   static const char query_app_disable[] = ", "
465       "CASE "
466         "WHEN ai.app_disable='true' COLLATE NOCASE OR "
467           "ui.is_disabled='true' COLLATE NOCASE "
468         "THEN 'true' "
469         "ELSE 'false' "
470       "END AS app_disable";
471   static const char query_basic[] =
472       ", ai.app_component, ai.app_exec, "
473       "ai.app_nodisplay, ai.app_type, ai.app_onboot, "
474       "ai.app_multiple, ai.app_autorestart, ai.app_taskmanage, "
475       "ai.app_hwacceleration, ai.app_screenreader, "
476       "ai.app_mainapp, ai.app_recentimage, ai.app_launchcondition, "
477       "ai.app_indicatordisplay, ai.app_portraitimg, "
478       "ai.app_landscapeimg, ai.app_guestmodevisibility, "
479       "ai.app_permissiontype, ai.app_preload, ai.app_submode, "
480       "ai.app_submode_mainid, ai.app_launch_mode, ai.app_ui_gadget, "
481       "ai.app_support_disable, ai.app_process_pool, "
482       "ai.app_background_category, ai.app_package_type, "
483       "ai.app_root_path, ai.app_api_version, ai.app_effective_appid, "
484       "ai.app_splash_screen_display, ai.app_tep_name, "
485       "ai.app_zip_mount_file, ai.component_type, ai.package, "
486       "ai.app_package_system, ai.app_removable, "
487       "ai.app_package_installed_time, ai.app_support_mode, "
488       "ai.app_support_ambient, ai.app_setup_appid, ai.light_user_switch_mode";
489   static const char query_uid_info[] =
490       ", ui.is_disabled, ui.is_splash_screen_enabled";
491   static const char query_label[] =
492       ", COALESCE("
493       "(SELECT app_label FROM package_app_localized_info WHERE "
494       "ai.app_id=app_id AND app_locale=?), "
495       "(SELECT app_label FROM package_app_localized_info WHERE "
496       "ai.app_id=app_id AND app_locale='No Locale'))";
497   static const char query_icon[] =
498       ", COALESCE("
499       "(SELECT app_icon FROM package_app_localized_info WHERE ai.app_id=app_id "
500       "AND app_locale=?), "
501       "(SELECT app_icon FROM package_app_localized_info WHERE ai.app_id=app_id "
502       "AND app_locale='No Locale'))";
503   static const char query_package_disable[] =
504       ", (SELECT package_disable FROM package_info WHERE ai.package=package)";
505   static const char query_from_clause[] = " FROM package_app_info as ai";
506   static const char query_uid_info_clause[] =
507       " LEFT OUTER JOIN package_app_info_for_uid AS ui "
508       "ON (ai.app_id=ui.app_id AND ui.uid=?)";
509   char* bg_category_str = nullptr;
510   char* tmp_record = nullptr;
511   std::list<std::string> bind_params;
512   bool is_check_storage = true;
513   const uid_t global_user_uid = GLOBAL_USER;
514   std::string query = query_raw;
515   auto pkg_disable_filter_status = GetPackageDisableFilterStatus(filter);
516
517   query += query_app_disable;
518
519   if (flag & PMINFO_APPINFO_GET_BASICINFO) {
520     query += query_basic;
521     query += query_uid_info;
522   }
523
524   if (flag & PMINFO_APPINFO_GET_LABEL) {
525     query += query_label;
526     bind_params.push_back(locale);
527   }
528
529   if (flag & PMINFO_APPINFO_GET_ICON) {
530     query += query_icon;
531     bind_params.push_back(locale);
532   }
533
534   if (pkg_disable_filter_status != PackageDisableFilterStatus::None)
535     query += query_package_disable;
536
537   bind_params.push_back(std::to_string(uid));
538   is_check_storage = __check_app_storage_status(filter);
539
540   std::string constraint;
541   int ret = GetFilteredQuery(filter, locale, uid, constraint, bind_params);
542   if (ret != PMINFO_R_OK) {
543     LOGE("Failed to get WHERE clause");
544     return PMINFO_R_ERROR;
545   }
546
547   query += query_from_clause;
548   query += query_uid_info_clause;
549
550   if (!constraint.empty())
551     query += constraint;
552
553   auto q = tizen_base::Database::Sql(query);
554   for (auto& i : bind_params)
555     q.Bind(std::move(i));
556
557   auto r = db.Exec(q);
558   if (!r) {
559     _LOGE("db.Exec() failed: %s", static_cast<const char*>(r));
560     return PMINFO_R_ERROR;
561   }
562
563   for (const auto& rec : r) {
564     application_x* info = static_cast<application_x*>(
565         calloc(1, sizeof(application_x)));
566     if (info == nullptr) {
567       LOGE("out of memory");
568       return PMINFO_R_ERROR;
569     }
570     std::shared_ptr<application_x> info_auto(info,
571         pkgmgrinfo_basic_free_application);
572
573     info->locale = strdup(locale);
574     if (info->locale == nullptr) {
575       LOGE("Out of memory");
576       return PMINFO_R_ERROR;
577     }
578
579     int idx = 0;
580     info->appid = GetCString(idx++, rec);
581     info->installed_storage = GetCString(idx++, rec);
582     info->external_path = GetCString(idx++, rec);
583     info->is_disabled = GetCString(idx++, rec);
584     if (flag & PMINFO_APPINFO_GET_BASICINFO) {
585       info->component = GetCString(idx++, rec);
586       info->exec = GetCString(idx++, rec);
587       info->nodisplay = GetCString(idx++, rec);
588       info->type = GetCString(idx++, rec);
589       info->onboot = GetCString(idx++, rec);
590       info->multiple = GetCString(idx++, rec);
591       info->autorestart = GetCString(idx++, rec);
592       info->taskmanage = GetCString(idx++, rec);
593       info->hwacceleration = GetCString(idx++, rec);
594       info->screenreader = GetCString(idx++, rec);
595       info->mainapp = GetCString(idx++, rec);
596       info->recentimage = GetCString(idx++, rec);
597       info->launchcondition = GetCString(idx++, rec);
598       info->indicatordisplay = GetCString(idx++, rec);
599       info->portraitimg = GetCString(idx++, rec);
600       info->landscapeimg = GetCString(idx++, rec);
601       info->guestmode_visibility = GetCString(idx++, rec);
602       info->permission_type = GetCString(idx++, rec);
603       info->preload = GetCString(idx++, rec);
604       info->submode = GetCString(idx++, rec);
605       info->submode_mainid = GetCString(idx++, rec);
606       info->launch_mode = GetCString(idx++, rec);
607       info->ui_gadget = GetCString(idx++, rec);
608       info->support_disable = GetCString(idx++, rec);
609       info->process_pool = GetCString(idx++, rec);
610       bg_category_str = GetCString(idx++, rec);
611       info->package_type = GetCString(idx++, rec);
612       info->root_path = GetCString(idx++, rec);
613       info->api_version = GetCString(idx++, rec);
614       info->effective_appid = GetCString(idx++, rec);
615       info->splash_screen_display = GetCString(idx++, rec);
616       info->tep_name = GetCString(idx++, rec);
617       info->zip_mount_file = GetCString(idx++, rec);
618       info->component_type = GetCString(idx++, rec);
619       info->package = GetCString(idx++, rec);
620       info->package_system = GetCString(idx++, rec);
621       info->removable = GetCString(idx++, rec);
622       info->package_installed_time = GetCString(idx++, rec);
623       info->support_mode = GetCString(idx++, rec);
624       info->support_ambient = GetCString(idx++, rec);
625       info->setup_appid = GetCString(idx++, rec);
626       info->light_user_switch_mode = GetCString(idx++, rec);
627       info->background_category = __get_background_category(
628             bg_category_str);
629       free(bg_category_str);
630     }
631
632     info->for_all_users =
633         strdup((db_uid != global_user_uid) ?
634             "false" : "true");
635
636     if (db_uid != global_user_uid) {
637       idx = idx + 2;
638     } else {
639       tmp_record = GetCString(idx++, rec);
640       if (tmp_record != nullptr) {
641         if (strcasecmp(info->is_disabled, "false") == 0 &&
642             strcasecmp(tmp_record, "false") == 0) {
643           free(info->is_disabled);
644           info->is_disabled = tmp_record;
645         } else {
646           free(tmp_record);
647         }
648       }
649       tmp_record = GetCString(idx++, rec);
650       if (tmp_record != nullptr) {
651         if (strcasecmp(info->splash_screen_display, "false") == 0 &&
652             strcasecmp(tmp_record, "false") == 0) {
653           free(info->splash_screen_display);
654           info->splash_screen_display = tmp_record;
655         } else {
656           free(tmp_record);
657         }
658       }
659     }
660
661     if (flag & PMINFO_APPINFO_GET_LABEL) {
662       tmp_record = GetCString(idx++, rec);
663       if (_add_label_info_into_list(locale, tmp_record,
664           &info->label)) {
665         if (tmp_record)
666           free(tmp_record);
667
668         return PMINFO_R_ERROR;
669       }
670     }
671
672     if (flag & PMINFO_APPINFO_GET_ICON) {
673       tmp_record = GetCString(idx++, rec);
674       if (_add_icon_info_into_list(locale, tmp_record,
675           &info->icon)) {
676         if (tmp_record)
677           free(tmp_record);
678
679         return PMINFO_R_ERROR;
680       }
681     }
682
683     if (pkg_disable_filter_status != PackageDisableFilterStatus::None) {
684       tmp_record = GetCString(idx++, rec);
685       if (tmp_record) {
686         bool filter_passed = CheckPkgDisableFilter(pkg_disable_filter_status,
687             tmp_record, info);
688         free(tmp_record);
689
690         if (!filter_passed)
691           continue;
692       }
693     }
694
695     if (flag & PMINFO_APPINFO_GET_CATEGORY) {
696       if (GetCategory(db, info->appid, &info->category))
697         return PMINFO_R_ERROR;
698     }
699
700     if (flag & PMINFO_APPINFO_GET_APP_CONTROL) {
701       if (GetAppControl(db, info->appid, &info->appcontrol))
702         return PMINFO_R_ERROR;
703     }
704
705     if (flag & PMINFO_APPINFO_GET_METADATA) {
706       if (GetMetadata(db, info->appid, &info->metadata))
707         return PMINFO_R_ERROR;
708     }
709
710     if (flag & PMINFO_APPINFO_GET_SPLASH_SCREEN) {
711       if (GetSplashScreens(db, info->appid, &info->splashscreens))
712         return PMINFO_R_ERROR;
713     }
714
715     if (flag & PMINFO_APPINFO_GET_RES_CONTROL) {
716       if (GetResControl(db, info->appid, &info->res_control))
717         return PMINFO_R_ERROR;
718     }
719
720     if (is_check_storage &&
721         __appinfo_check_installed_storage(info) !=
722             PMINFO_R_OK) {
723       continue;
724     }
725
726     if (!CheckAppDisableFilter(filter, info))
727       continue;
728
729     if (!(flag & PMINFO_APPINFO_GET_BASICINFO) && info->is_disabled) {
730       free(info->is_disabled);
731       info->is_disabled = nullptr;
732     }
733
734     applications.push_back(std::move(info_auto));
735   }
736
737   return PMINFO_R_OK;
738 }
739
740 }  // namespace
741
742 namespace pkgmgr_server {
743 namespace internal {
744
745 API bool CheckAppStorageStatus(pkgmgrinfo_filter_x* tmp_filter) {
746   return ::__check_app_storage_status(tmp_filter);
747 }
748
749 API int GetAppInfo(const tizen_base::Database& db,
750     pkgmgrinfo_appinfo_filter_h filter, uid_t db_uid, uid_t uid,
751     const std::string& locale,
752     std::vector<std::shared_ptr<application_x>>& appinfo_list) {
753   if (!static_cast<bool>(db) || filter == nullptr) {
754     LOGE("Invalid argument");
755     return PMINFO_R_EINVAL;
756   }
757
758   return ::DoGetAppInfo(db, db_uid, uid, locale.c_str(),
759       static_cast<pkgmgrinfo_filter_x*>(filter), PMINFO_APPINFO_GET_ALL,
760       appinfo_list);
761 }
762
763 }  // namesapce internal
764 }  // namesapce pkgmgr_server