Merge branch 'master' of github.sec.samsung.net:appfw/pkgmgr-info into tizen
authorIlho Kim <ilho159.kim@samsung.com>
Mon, 28 Jun 2021 09:10:40 +0000 (18:10 +0900)
committerIlho Kim <ilho159.kim@samsung.com>
Mon, 28 Jun 2021 10:32:02 +0000 (19:32 +0900)
Change-Id: I404ed720f12f81f00ca8c5cf1acf27370bee14ee
Signed-off-by: Ilho Kim <ilho159.kim@samsung.com>
27 files changed:
1  2 
packaging/pkgmgr-info.spec
src/CMakeLists.txt
src/common/parcel/abstract_parcelable.hh
src/common/parcel/pkginfo_parcelable.cc
src/common/parcel/pkginfo_parcelable.hh
src/common/parcel/query_parcelable.cc
src/common/parcel/query_parcelable.hh
src/manager/pkginfo_manager.cc
src/pkgmgrinfo_appinfo.c
src/pkgmgrinfo_pkginfo.c
src/pkgmgrinfo_private.c
src/pkgmgrinfo_private.h
src/pkgmgrinfo_updateinfo.c
src/server/CMakeLists.txt
src/server/appinfo_internal.c
src/server/database/query_handler.cc
src/server/database/query_handler.hh
src/server/pkginfo_internal.c
src/server/request_handler/command_request_handler.cc
src/server/request_handler/create_db_request_handler.cc
src/server/request_handler/query_request_handler.cc
src/server/request_handler/set_cert_request_handler.cc
src/server/request_handler/set_pkginfo_request_handler.cc
test/unit_tests/CMakeLists.txt
test/unit_tests/parcel_utils.cc
test/unit_tests/test_parcel.cc
test/unit_tests/test_parser_db_handlers.cc

Simple merge
Simple merge
index b34e1e8d482b848f1bf42434a5beaf8b9669d5ff,ed994f7b4bfe12e1dbe6fa30f7b8a90b8bb9272a..40fa0fa1c43123f46d5b1e7a6b73f41a2cd62d03
@@@ -27,39 -27,23 +27,37 @@@ namespace parcel 
  
  QueryParcelable::QueryParcelable()
      : AbstractParcelable(0, ParcelableType::Query),
-     db_type_(AbstractDBHandler::DBType::DB_TYPE_NONE),
-     op_type_(AbstractDBHandler::OperationType::OPERATION_TYPE_NONE) {}
+     db_type_(DBType::DB_TYPE_NONE),
+     op_type_(DBOperationType::OPERATION_TYPE_NONE) {}
  
  QueryParcelable::QueryParcelable(uid_t uid,
 -    QueryArgs query_args,
 -    DBType db_type,
 -    DBOperationType op_type)
 -    : AbstractParcelable(0, ParcelableType::Query),
 -    query_args_(std::vector<QueryArgs>{query_args}),
 -    db_type_(db_type), op_type_(op_type) {}
 +    const std::pair<int, std::vector<const char*>>& query_args,
-     AbstractDBHandler::DBType db_type,
-     AbstractDBHandler::OperationType op_type)
++    DBType db_type, DBOperationType op_type)
 +    : AbstractParcelable(uid, ParcelableType::Query),
 +    db_type_(db_type), op_type_(op_type) {
 +  query_args_.emplace_back(CreateQueryArgs(query_args));
 +}
  
  QueryParcelable::QueryParcelable(uid_t uid,
 -    std::vector<QueryArgs> query_args,
 -    DBType db_type,
 -    DBOperationType op_type)
 +    const std::vector<std::pair<int, std::vector<const char*>>>& query_args,
-     AbstractDBHandler::DBType db_type,
-     AbstractDBHandler::OperationType op_type)
++    DBType db_type, DBOperationType op_type)
      : AbstractParcelable(uid, ParcelableType::Query),
 -    query_args_(std::move(query_args)), db_type_(db_type), op_type_(op_type) {}
 +    db_type_(db_type), op_type_(op_type) {
 +  for (const auto& arg : query_args)
 +    query_args_.emplace_back(CreateQueryArgs(arg));
 +}
 +
 +QueryArgs QueryParcelable::CreateQueryArgs(
 +    const std::pair<int, std::vector<const char*>>& args) {
 +  StrArgs vt;
 +  for (const char* param : args.second) {
 +      if (param)
 +        vt.emplace_back(param);
 +      else
 +        vt.emplace_back(std::nullopt);
 +  }
 +  return std::make_pair(args.first, std::move(vt));
 +}
  
  void QueryParcelable::WriteToParcel(tizen_base::Parcel* parcel) const {
    AbstractParcelable::WriteToParcel(parcel);
      WriteInt(parcel, query_info.first);
      WriteInt(parcel, query_info.second.size());
      for (const auto& args : query_info.second)
 -      parcel->WriteString(args);
 +      WriteString(parcel, args);
    }
-   WriteInt(parcel, db_type_);
-   WriteInt(parcel, op_type_);
+   WriteInt(parcel, static_cast<int>(db_type_));
+   WriteInt(parcel, static_cast<int>(op_type_));
  }
  
  void QueryParcelable::ReadFromParcel(tizen_base::Parcel* parcel) {
      query_args_.push_back(QueryArgs(index, std::move(args)));
    }
    ReadInt(parcel, &db_type);
-   db_type_ = static_cast<AbstractDBHandler::DBType>(db_type);
+   db_type_ = static_cast<DBType>(db_type);
    ReadInt(parcel, &op_type);
-   op_type_ = static_cast<AbstractDBHandler::OperationType>(op_type);
+   op_type_ = static_cast<DBOperationType>(op_type);
  }
  
 -const std::vector<QueryArgs>& QueryParcelable::GetQueryArgs() {
 -  return query_args_;
 +std::vector<QueryArgs> QueryParcelable::ExtractQueryArgs() {
 +  return std::move(query_args_);
  }
  
AbstractDBHandler::DBType QueryParcelable::GetDBType() {
+ DBType QueryParcelable::GetDBType() {
    return db_type_;
  }
  
index c1a4b793a6bb9e91ef652a2bef3e26129a079045,d2507b3eac3dd2d3c558ca5572c439b3c11d00e5..bf67c4866ef06e2e9d502e7814207d42c76db88d
@@@ -2,9 -2,7 +2,8 @@@
  #define QUERY_PARCELABLE_HH_
  
  #include "abstract_parcelable.hh"
- #include "abstract_db_handler.hh"
  
 +#include <optional>
  #include <vector>
  
  #include "pkgmgrinfo_private.h"
@@@ -24,28 -21,21 +23,26 @@@ using QueryArgs = std::pair<int, StrArg
  class EXPORT_API QueryParcelable : public AbstractParcelable {
   public:
    QueryParcelable();
 -  QueryParcelable(uid_t uid, QueryArgs query_args,
 +  QueryParcelable(uid_t uid,
 +      const std::pair<int, std::vector<const char*>>& query_args,
-       AbstractDBHandler::DBType db_type,
-       AbstractDBHandler::OperationType op_type);
+       DBType db_type, DBOperationType op_type);
 -  QueryParcelable(uid_t uid, std::vector<QueryArgs> query_args,
 +  QueryParcelable(uid_t uid,
 +      const std::vector<std::pair<int, std::vector<const char*>>>& query_args,
-       AbstractDBHandler::DBType db_type,
-       AbstractDBHandler::OperationType op_type);
+       DBType db_type, DBOperationType op_type);
 -  const std::vector<QueryArgs>& GetQueryArgs();
 +  std::vector<QueryArgs> ExtractQueryArgs();
-   AbstractDBHandler::DBType GetDBType();
-   AbstractDBHandler::OperationType GetOpType();
+   DBType GetDBType();
+   DBOperationType GetOpType();
  
    void WriteToParcel(tizen_base::Parcel* parcel) const override;
    void ReadFromParcel(tizen_base::Parcel* parcel) override;
  
   private:
 +  QueryArgs CreateQueryArgs(
 +      const std::pair<int, std::vector<const char*>>& args);
 +
    std::vector<QueryArgs> query_args_;
-   AbstractDBHandler::DBType db_type_;
-   AbstractDBHandler::OperationType op_type_;
+   DBType db_type_;
+   DBOperationType op_type_;
  };
  
  }  // namespace parcel
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 45e62e92e9f29a5d50353127a797b17a18e7989f,5704da04e9a816dfa08dbcd52cb124e51b72f16c..2bbe7447e5d16ecd1619d152d5914cc99253b5b5
@@@ -1,23 -1,36 +1,36 @@@
  ## build pkginfo-server binary
  SET(PKGINFO_SERVER "pkginfo-server")
  
- AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} PKGINFO_SERVER_SRCS)
- INCLUDE_DIRECTORIES(
-   ${CMAKE_CURRENT_SOURCE_DIR}/../
-   ${CMAKE_CURRENT_SOURCE_DIR}/../common/database
-   ${CMAKE_CURRENT_SOURCE_DIR}/../common/socket
-   ${CMAKE_CURRENT_SOURCE_DIR}/../common/parcel
-   ${CMAKE_CURRENT_SOURCE_DIR}/../common/request_handler
+ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SERVER_SRCS)
+ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/cynara_checker CYNARA_CHECKER_SRCS)
+ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/database DATABASE_SRCS)
+ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/request_handler REQUEST_HANDLER_SRCS)
+ ADD_LIBRARY(pkgmgr-info-server SHARED
+   ${CYNARA_CHECKER_SRCS}
+   ${SERVER_SRCS}
+   ${DATABASE_SRCS}
+   ${REQUEST_HANDLER_SRCS}
  )
  
- ADD_EXECUTABLE(${PKGINFO_SERVER} ${PKGINFO_SERVER_SRCS})
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++17 -pthread -fPIE")
- SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
+ ADD_DEFINITIONS("-DSYSCONFDIR=\"${SYSCONFDIR}\"")
+ SET_TARGET_PROPERTIES(pkgmgr-info-server PROPERTIES SOVERSION ${MAJORVER})
+ SET_TARGET_PROPERTIES(pkgmgr-info-server PROPERTIES VERSION ${FULLVER})
+ TARGET_LINK_LIBRARIES(pkgmgr-info-server pkgmgr-info ${libpkgs_server_LDFLAGS})
+ INSTALL(TARGETS pkgmgr-info-server DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+ ADD_EXECUTABLE(${PKGINFO_SERVER} main.cc)
+ SET_TARGET_PROPERTIES(${PKGINFO_SERVER} PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE")
+ SET_TARGET_PROPERTIES(${PKGINFO_SERVER} PROPERTIES LINK_FLAGS "-pie")
 -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++14 -pthread")
++SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -fpic -std=c++17 -pthread")
  
- TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} PRIVATE ${libpkgs_LDFLAGS})
- TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} PRIVATE ${libpkgmgr-parser_LDFLAGS})
- TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} PUBLIC pkgmgr-info pthread)
+ TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} ${libpkgs_LDFLAGS})
+ TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} ${libpkgmgr-parser_LDFLAGS})
+ TARGET_LINK_LIBRARIES(${PKGINFO_SERVER} PUBLIC pkgmgr-info-server pthread)
  
  SET_TARGET_PROPERTIES(${PKGINFO_SERVER} PROPERTIES LINKER_LANGUAGE CXX)
  INSTALL(TARGETS ${PKGINFO_SERVER} DESTINATION bin)
index 0000000000000000000000000000000000000000,006fd7884fff091f302cb4fc3f8705f5ee76c3b1..ae5d8f27666aa638cd45bf9d5a499f10ddd58a83
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,735 +1,788 @@@
+ /*
+  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdbool.h>
+ #include <string.h>
+ #include <ctype.h>
+ #include <unistd.h>
+ #include <sys/types.h>
+ #include <dlfcn.h>
+ #include <sqlite3.h>
+ #include <glib.h>
+ #include "pkgmgr-info.h"
+ #include "pkgmgrinfo_debug.h"
+ #include "pkgmgrinfo_private.h"
+ #include "pkgmgr_parser.h"
+ #include "pkgmgrinfo_internal.h"
+ static void __parse_appcontrol(GList **appcontrol,
+               char *appcontrol_str, char *visibility, char *id)
+ {
+       char *dup;
+       char *token;
+       char *ptr = NULL;
+       appcontrol_x *ac;
+       if (appcontrol_str == NULL)
+               return;
+       dup = strdup(appcontrol_str);
+       if (dup == NULL) {
+               _LOGE("out of memory");
+               return;
+       }
+       do {
+               ac = calloc(1, sizeof(appcontrol_x));
+               if (ac == NULL) {
+                       _LOGE("out of memory");
+                       break;
+               }
+               token = strtok_r(dup, "|", &ptr);
+               if (token && strcmp(token, "NULL"))
+                       ac->operation = strdup(token);
+               token = strtok_r(NULL, "|", &ptr);
+               if (token && strcmp(token, "NULL"))
+                       ac->uri = strdup(token);
+               token = strtok_r(NULL, "|", &ptr);
+               if (token && strcmp(token, "NULL"))
+                       ac->mime = strdup(token);
+               ac->visibility = strdup(visibility);
+               ac->id = strdup(id);
+               *appcontrol = g_list_prepend(*appcontrol, ac);
+       } while ((token = strtok_r(NULL, ";", &ptr)));
+       free(dup);
+ }
+ static int _appinfo_get_splashscreens(sqlite3 *db,
+               const char *appid, GList **splashscreens)
+ {
+       static const char query_raw[] =
+                       "SELECT src, type, orientation, indicatordisplay, "
+                       "operation, color_depth "
+                       "FROM package_app_splash_screen WHERE app_id=%Q";
+       int ret;
+       char *query;
+       sqlite3_stmt *stmt;
+       int idx;
+       splashscreen_x *info;
+       query = sqlite3_mprintf(query_raw, appid);
+       if (query == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       sqlite3_free(query);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               info = calloc(1, sizeof(splashscreen_x));
+               if (info == NULL) {
+                       LOGE("out of memory");
+                       sqlite3_finalize(stmt);
+                       return PMINFO_R_ERROR;
+               }
+               idx = 0;
+               _save_column_str(stmt, idx++, &info->src);
+               _save_column_str(stmt, idx++, &info->type);
+               _save_column_str(stmt, idx++, &info->orientation);
+               _save_column_str(stmt, idx++, &info->indicatordisplay);
+               _save_column_str(stmt, idx++, &info->operation);
+               _save_column_str(stmt, idx++, &info->color_depth);
+               *splashscreens = g_list_prepend(*splashscreens, info);
+       }
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
+ static int _appinfo_get_metadata(sqlite3 *db,
+               const char *appid, GList **metadata)
+ {
+       static const char query_raw[] =
+                       "SELECT md_key, md_value "
+                       "FROM package_app_app_metadata WHERE app_id=%Q";
+       int ret;
+       char *query;
+       sqlite3_stmt *stmt;
+       int idx;
+       metadata_x *info;
+       query = sqlite3_mprintf(query_raw, appid);
+       if (query == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       sqlite3_free(query);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               info = calloc(1, sizeof(metadata_x));
+               if (info == NULL) {
+                       LOGE("out of memory");
+                       sqlite3_finalize(stmt);
+                       return PMINFO_R_ERROR;
+               }
+               idx = 0;
+               _save_column_str(stmt, idx++, &info->key);
+               _save_column_str(stmt, idx++, &info->value);
+               *metadata = g_list_prepend(*metadata, info);
+       }
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
+ static int _appinfo_get_app_control(sqlite3 *db,
+               const char *appid, GList **appcontrol)
+ {
+       static const char query_raw[] =
+                       "SELECT app_control, visibility, app_control_id "
+                       "FROM package_app_app_control WHERE app_id=%Q";
+       int ret;
+       int idx;
+       char *query;
+       sqlite3_stmt *stmt;
+       char *str;
+       char *visibility;
+       char *id;
+       query = sqlite3_mprintf(query_raw, appid);
+       if (query == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       sqlite3_free(query);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               str = NULL;
+               visibility = NULL;
+               id = NULL;
+               idx = 0;
+               _save_column_str(stmt, idx++, &str);
+               _save_column_str(stmt, idx++, &visibility);
+               _save_column_str(stmt, idx++, &id);
+               /* TODO: revise */
+               __parse_appcontrol(appcontrol, str, visibility, id);
+               free(str);
+               free(visibility);
+               free(id);
+       }
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
+ static int _appinfo_get_category(sqlite3 *db,
+               const char *appid, GList **category)
+ {
+       static const char query_raw[] =
+                       "SELECT category "
+                       "FROM package_app_app_category WHERE app_id=%Q";
+       int ret;
+       char *query;
+       sqlite3_stmt *stmt;
+       char *val;
+       query = sqlite3_mprintf(query_raw, appid);
+       if (query == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       sqlite3_free(query);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               val = NULL;
+               _save_column_str(stmt, 0, &val);
+               if (val)
+                       *category = g_list_prepend(*category, (gpointer)val);
+       }
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
++static int _appinfo_get_res_control(sqlite3 *db, const char *appid,
++              GList **res_control)
++{
++      static const char query_raw[] =
++              "SELECT res_type, min_res_version, max_res_version, auto_close "
++              "FROM package_app_res_control WHERE app_id=%Q";
++      int ret;
++      char *query;
++      sqlite3_stmt *stmt;
++      int idx;
++      res_control_x *info;
++
++      query = sqlite3_mprintf(query_raw, appid);
++      if (query == NULL) {
++              LOGE("out of memory");
++              return PMINFO_R_ERROR;
++      }
++
++      ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
++      sqlite3_free(query);
++      if (ret != SQLITE_OK) {
++              LOGE("prepare failed: %s", sqlite3_errmsg(db));
++              return PMINFO_R_ERROR;
++      }
++
++      while (sqlite3_step(stmt) == SQLITE_ROW) {
++              info = calloc(1, sizeof(res_control_x));
++              if (info == NULL) {
++                      LOGE("out of memory");
++                      sqlite3_finalize(stmt);
++                      return PMINFO_R_ERROR;
++              }
++              idx = 0;
++              _save_column_str(stmt, idx++, &info->res_type);
++              _save_column_str(stmt, idx++, &info->min_res_version);
++              _save_column_str(stmt, idx++, &info->max_res_version);
++              _save_column_str(stmt, idx++, &info->auto_close);
++              *res_control = g_list_prepend(*res_control, info);
++      }
++
++      sqlite3_finalize(stmt);
++
++      return PMINFO_R_OK;
++}
++
+ static GList *__get_background_category(const char *value)
+ {
+       GList *category_list = NULL;
+       int convert_value = 0;
+       if (!value || strlen(value) == 0)
+               return NULL;
+       convert_value = atoi(value);
+       if (convert_value < 0)
+               return NULL;
+       if (convert_value & APP_BG_CATEGORY_USER_DISABLE_TRUE_VAL)
+               category_list = g_list_prepend(category_list,
+                               strdup(APP_BG_CATEGORY_USER_DISABLE_TRUE_STR));
+       else
+               category_list = g_list_prepend(category_list,
+                               strdup(APP_BG_CATEGORY_USER_DISABLE_FALSE_STR));
+       if (convert_value & APP_BG_CATEGORY_MEDIA_VAL)
+               category_list = g_list_prepend(category_list,
+                               strdup(APP_BG_CATEGORY_MEDIA_STR));
+       if (convert_value & APP_BG_CATEGORY_DOWNLOAD_VAL)
+               category_list = g_list_prepend(category_list,
+                               strdup(APP_BG_CATEGORY_DOWNLOAD_STR));
+       if (convert_value & APP_BG_CATEGORY_BGNETWORK_VAL)
+               category_list = g_list_prepend(category_list,
+                               strdup(APP_BG_CATEGORY_BGNETWORK_STR));
+       if (convert_value & APP_BG_CATEGORY_LOCATION_VAL)
+               category_list = g_list_prepend(category_list,
+                               strdup(APP_BG_CATEGORY_LOCATION_STR));
+       if (convert_value & APP_BG_CATEGORY_SENSOR_VAL)
+               category_list = g_list_prepend(category_list,
+                               strdup(APP_BG_CATEGORY_SENSOR_STR));
+       if (convert_value & APP_BG_CATEGORY_IOTCOMM_VAL)
+               category_list = g_list_prepend(category_list,
+                               strdup(APP_BG_CATEGORY_IOTCOMM_STR));
+       if (convert_value & APP_BG_CATEGORY_SYSTEM_VAL)
+               category_list = g_list_prepend(category_list,
+                               strdup(APP_BG_CATEGORY_SYSTEM));
+       return category_list;
+ }
+ static int __bind_params(sqlite3_stmt *stmt, GList *params)
+ {
+       GList *tmp_list = NULL;
+       int idx = 0;
+       int ret;
+       if (stmt == NULL || params == NULL)
+               return PMINFO_R_EINVAL;
+       tmp_list = params;
+       while (tmp_list) {
+               ret = sqlite3_bind_text(stmt, ++idx,
+                               (char *)tmp_list->data, -1, SQLITE_STATIC);
+               if (ret != SQLITE_OK)
+                       return PMINFO_R_ERROR;
+               tmp_list = tmp_list->next;
+       }
+       return PMINFO_R_OK;
+ }
+ static const char join_localized_info[] =
+               " LEFT OUTER JOIN package_app_localized_info"
+               " ON ai.app_id=package_app_localized_info.app_id"
+               " AND package_app_localized_info.app_locale=?";
+ static const char join_category[] =
+               " LEFT OUTER JOIN package_app_app_category"
+               " ON ai.app_id=package_app_app_category.app_id";
+ static const char join_app_control[] =
+               " LEFT OUTER JOIN package_app_app_control"
+               " ON ai.app_id=package_app_app_control.app_id";
+ static const char join_metadata[] =
+               " LEFT OUTER JOIN package_app_app_metadata"
+               " ON ai.app_id=package_app_app_metadata.app_id ";
+ static const char join_privilege[] =
+               " LEFT OUTER JOIN package_privilege_info"
+               " ON ai.package=package_privilege_info.package ";
+ static int _get_filtered_query(pkgmgrinfo_filter_x *filter, const char *locale,
+               uid_t uid, char **query, GList **bind_params)
+ {
+       int joined = 0;
+       int size;
+       char *condition = NULL;
+       char buf[MAX_QUERY_LEN] = {'\0'};
+       char tmp_query[MAX_QUERY_LEN] = {'\0'};
+       GSList *list;
+       if (!filter)
+               return PMINFO_R_OK;
+       strncat(buf, " WHERE 1=1", sizeof(buf) - strlen(buf) - 1);
+       for (list = filter->list; list; list = list->next) {
+               joined |= __get_filter_condition(list->data,
+                               uid, &condition, bind_params);
+               if (condition == NULL)
+                       continue;
+               strncat(buf, " AND ", sizeof(buf) - strlen(buf) - 1);
+               strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
+               free(condition);
+               condition = NULL;
+       }
+       if (filter->list_metadata)
+               strncat(buf, " AND (", sizeof(buf) - strlen(buf) - 1);
+       for (list = filter->list_metadata; list; list = list->next) {
+               joined |= __get_metadata_filter_condition(list->data,
+                               &condition, bind_params);
+               if (condition == NULL)
+                       continue;
+               strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
+               free(condition);
+               condition = NULL;
+               strncat(buf, " OR ", sizeof(buf) - strlen(buf) - 1);
+       }
+       if (filter->list_metadata)
+               strncat(buf, "1=0)", sizeof(buf) - strlen(buf) - 1);
+       if (joined & E_PMINFO_APPINFO_JOIN_LOCALIZED_INFO) {
+               strncat(tmp_query, join_localized_info,
+                               sizeof(tmp_query) - strlen(tmp_query) - 1);
+               *bind_params = g_list_append(*bind_params, strdup(locale));
+       }
+       if (joined & E_PMINFO_APPINFO_JOIN_CATEGORY)
+               strncat(tmp_query, join_category,
+                               sizeof(tmp_query) - strlen(tmp_query) - 1);
+       if (joined & E_PMINFO_APPINFO_JOIN_APP_CONTROL)
+               strncat(tmp_query, join_app_control,
+                               sizeof(tmp_query) - strlen(tmp_query) - 1);
+       if (joined & E_PMINFO_APPINFO_JOIN_METADATA)
+               strncat(tmp_query, join_metadata,
+                               sizeof(tmp_query) - strlen(tmp_query) - 1);
+       if (joined & E_PMINFO_APPINFO_JOIN_PRIVILEGE)
+               strncat(tmp_query, join_privilege,
+                               sizeof(tmp_query) - strlen(tmp_query) - 1);
+       size = strlen(tmp_query) + strlen(buf) + 1;
+       *query = (char *)calloc(1, size);
+       if (*query == NULL)
+               return PMINFO_R_ERROR;
+       snprintf(*query, size, "%s%s", tmp_query, buf);
+       return PMINFO_R_OK;
+ }
+ static bool __check_app_storage_status(pkgmgrinfo_filter_x *tmp_filter)
+ {
+       GSList *tmp_list = NULL;
+       pkgmgrinfo_node_x *tmp_node = NULL;
+       int property = -1;
+       if (tmp_filter == NULL)
+               return true;
+       property = _pminfo_appinfo_convert_to_prop_bool(
+                       PMINFO_APPINFO_PROP_APP_CHECK_STORAGE);
+       for (tmp_list = tmp_filter->list; tmp_list != NULL;
+                        tmp_list = g_slist_next(tmp_list)) {
+               tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
+               if (property == tmp_node->prop) {
+                       if (strcmp(tmp_node->value, "true") == 0)
+                               return true;
+                       else
+                               return false;
+               }
+       }
+       return true;
+ }
+ static int _appinfo_get_applications(sqlite3 *db, uid_t db_uid, uid_t uid,
+               const char *locale, pkgmgrinfo_filter_x *filter, int flag,
+               GHashTable *applications)
+ {
+       static const char query_raw[] =
+                       "SELECT DISTINCT ai.app_id, ai.app_installed_storage, "
+                       "ai.app_external_path";
+       static const char query_basic[] =
+                       ", ai.app_component, ai.app_exec, "
+                       "ai.app_nodisplay, ai.app_type, ai.app_onboot, "
+                       "ai.app_multiple, ai.app_autorestart, ai.app_taskmanage, "
+                       "ai.app_hwacceleration, ai.app_screenreader, "
+                       "ai.app_mainapp, ai.app_recentimage, ai.app_launchcondition, "
+                       "ai.app_indicatordisplay, ai.app_portraitimg, "
+                       "ai.app_landscapeimg, ai.app_guestmodevisibility, "
+                       "ai.app_permissiontype, ai.app_preload, ai.app_submode, "
+                       "ai.app_submode_mainid, ai.app_launch_mode, ai.app_ui_gadget, "
+                       "ai.app_support_disable, ai.app_process_pool, "
+                       "ai.app_background_category, ai.app_package_type, "
+                       "ai.app_root_path, ai.app_api_version, ai.app_effective_appid, "
+                       "ai.app_disable, ai.app_splash_screen_display, ai.app_tep_name, "
+                       "ai.app_zip_mount_file, ai.component_type, ai.package, "
+                       "ai.app_package_system, ai.app_removable, "
+                       "ai.app_package_installed_time, ai.app_support_mode, "
+                       "ai.app_support_ambient, ai.app_setup_appid";
+       static const char query_uid_info[] =
+                       ", ui.is_disabled, ui.is_splash_screen_enabled";
+       static const char query_label[] =
+                       ", COALESCE("
+                       "(SELECT app_label FROM package_app_localized_info WHERE "
+                       "ai.app_id=app_id AND app_locale=?), "
+                       "(SELECT app_label FROM package_app_localized_info WHERE "
+                       "ai.app_id=app_id AND app_locale='No Locale'))";
+       static const char query_icon[] =
+                       ", COALESCE("
+                       "(SELECT app_icon FROM package_app_localized_info WHERE ai.app_id=app_id "
+                       "AND app_locale=?), "
+                       "(SELECT app_icon FROM package_app_localized_info WHERE ai.app_id=app_id "
+                       "AND app_locale='No Locale'))";
+       static const char query_from_clause[] = " FROM package_app_info as ai";
+       static const char query_uid_info_clause[] =
+                       " LEFT OUTER JOIN package_app_info_for_uid AS ui "
+                       "ON (ai.app_id=ui.app_id AND ui.uid=?)";
+       int ret = PMINFO_R_ERROR;
+       int idx;
+       char *bg_category_str = NULL;
+       char *constraint = NULL;
+       char *tmp_record = NULL;
+       char query[MAX_QUERY_LEN] = {'\0'};
+       char buf[BUFSIZE] = {'\0'};
+       application_x *info = NULL;
+       GList *bind_params = NULL;
+       sqlite3_stmt *stmt = NULL;
+       bool is_check_storage = true;
+       const uid_t global_user_uid = GLOBAL_USER;
+       snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
+       if (flag & PMINFO_APPINFO_GET_BASICINFO) {
+               strncat(query, query_basic, sizeof(query) - strlen(query) - 1);
+               strncat(query, query_uid_info,
+                               sizeof(query) - strlen(query) - 1);
+       }
+       if (flag & PMINFO_APPINFO_GET_LABEL) {
+               strncat(query, query_label, sizeof(query) - strlen(query) - 1);
+               bind_params = g_list_append(bind_params, strdup(locale));
+       }
+       if (flag & PMINFO_APPINFO_GET_ICON) {
+               strncat(query, query_icon, sizeof(query) - strlen(query) - 1);
+               bind_params = g_list_append(bind_params, strdup(locale));
+       }
+       snprintf(buf, MAX_QUERY_LEN - 1, "%d", uid);
+       bind_params = g_list_append(bind_params, strdup(buf));
+       is_check_storage = __check_app_storage_status(filter);
+       ret = _get_filtered_query(filter, locale,
+                       uid, &constraint, &bind_params);
+       if (ret != PMINFO_R_OK) {
+               LOGE("Failed to get WHERE clause");
+               goto catch;
+       }
+       strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1);
+       strncat(query, query_uid_info_clause,
+                       sizeof(query) - strlen(query) - 1);
+       if (constraint)
+               strncat(query, constraint, sizeof(query) - strlen(query) - 1);
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               ret = PMINFO_R_ERROR;
+               goto catch;
+       }
+       if (g_list_length(bind_params) != 0) {
+               ret = __bind_params(stmt, bind_params);
+               if (ret != SQLITE_OK) {
+                       LOGE("Failed to bind parameters");
+                       goto catch;
+               }
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               info = calloc(1, sizeof(application_x));
+               if (info == NULL) {
+                       LOGE("out of memory");
+                       ret = PMINFO_R_ERROR;
+                       goto catch;
+               }
+               info->locale = strdup(locale);
+               if (info->locale == NULL) {
+                       LOGE("Out of memory");
+                       ret = PMINFO_R_ERROR;
+                       goto catch;
+               }
+               idx = 0;
+               _save_column_str(stmt, idx++, &info->appid);
+               _save_column_str(stmt, idx++, &info->installed_storage);
+               _save_column_str(stmt, idx++, &info->external_path);
+               if (flag & PMINFO_APPINFO_GET_BASICINFO) {
+                       _save_column_str(stmt, idx++, &info->component);
+                       _save_column_str(stmt, idx++, &info->exec);
+                       _save_column_str(stmt, idx++, &info->nodisplay);
+                       _save_column_str(stmt, idx++, &info->type);
+                       _save_column_str(stmt, idx++, &info->onboot);
+                       _save_column_str(stmt, idx++, &info->multiple);
+                       _save_column_str(stmt, idx++, &info->autorestart);
+                       _save_column_str(stmt, idx++, &info->taskmanage);
+                       _save_column_str(stmt, idx++, &info->hwacceleration);
+                       _save_column_str(stmt, idx++, &info->screenreader);
+                       _save_column_str(stmt, idx++, &info->mainapp);
+                       _save_column_str(stmt, idx++, &info->recentimage);
+                       _save_column_str(stmt, idx++, &info->launchcondition);
+                       _save_column_str(stmt, idx++, &info->indicatordisplay);
+                       _save_column_str(stmt, idx++, &info->portraitimg);
+                       _save_column_str(stmt, idx++, &info->landscapeimg);
+                       _save_column_str(stmt, idx++,
+                                       &info->guestmode_visibility);
+                       _save_column_str(stmt, idx++, &info->permission_type);
+                       _save_column_str(stmt, idx++, &info->preload);
+                       _save_column_str(stmt, idx++, &info->submode);
+                       _save_column_str(stmt, idx++, &info->submode_mainid);
+                       _save_column_str(stmt, idx++, &info->launch_mode);
+                       _save_column_str(stmt, idx++, &info->ui_gadget);
+                       _save_column_str(stmt, idx++, &info->support_disable);
+                       _save_column_str(stmt, idx++, &info->process_pool);
+                       _save_column_str(stmt, idx++, &bg_category_str);
+                       _save_column_str(stmt, idx++, &info->package_type);
+                       _save_column_str(stmt, idx++, &info->root_path);
+                       _save_column_str(stmt, idx++, &info->api_version);
+                       _save_column_str(stmt, idx++, &info->effective_appid);
+                       _save_column_str(stmt, idx++, &info->is_disabled);
+                       _save_column_str(stmt, idx++,
+                                       &info->splash_screen_display);
+                       _save_column_str(stmt, idx++, &info->tep_name);
+                       _save_column_str(stmt, idx++, &info->zip_mount_file);
+                       _save_column_str(stmt, idx++, &info->component_type);
+                       _save_column_str(stmt, idx++, &info->package);
+                       _save_column_str(stmt, idx++, &info->package_system);
+                       _save_column_str(stmt, idx++, &info->removable);
+                       _save_column_str(stmt, idx++,
+                                       &info->package_installed_time);
+                       _save_column_str(stmt, idx++, &info->support_mode);
+                       _save_column_str(stmt, idx++, &info->support_ambient);
+                       _save_column_str(stmt, idx++, &info->setup_appid);
+                       info->background_category = __get_background_category(
+                                               bg_category_str);
+                       free(bg_category_str);
+                       bg_category_str = NULL;
+               }
+               info->for_all_users =
+                               strdup((db_uid != global_user_uid) ?
+                                               "false" : "true");
+               if (db_uid != global_user_uid) {
+                       idx = idx + 2;
+               } else {
+                       tmp_record = NULL;
+                       _save_column_str(stmt, idx++, &tmp_record);
+                       if (tmp_record != NULL) {
+                               if (strcasecmp(info->is_disabled, "false") == 0 &&
+                                               strcasecmp(tmp_record, "false") == 0) {
+                                       free(info->is_disabled);
+                                       info->is_disabled = tmp_record;
+                               } else {
+                                       free(tmp_record);
+                               }
+                       }
+                       tmp_record = NULL;
+                       _save_column_str(stmt, idx++, &tmp_record);
+                       if (tmp_record != NULL) {
+                               if (strcasecmp(info->splash_screen_display, "false") == 0 &&
+                                               strcasecmp(tmp_record, "false") == 0) {
+                                       free(info->splash_screen_display);
+                                       info->splash_screen_display = tmp_record;
+                               } else {
+                                       free(tmp_record);
+                               }
+                       }
+               }
+               if (flag & PMINFO_APPINFO_GET_LABEL) {
+                       tmp_record = NULL;
+                       _save_column_str(stmt, idx++, &tmp_record);
+                       if (_add_label_info_into_list(locale, tmp_record,
+                                       &info->label)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+               if (flag & PMINFO_APPINFO_GET_ICON) {
+                       tmp_record = NULL;
+                       _save_column_str(stmt, idx++, &tmp_record);
+                       if (_add_icon_info_into_list(locale, tmp_record,
+                                       &info->icon)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+               if (flag & PMINFO_APPINFO_GET_CATEGORY) {
+                       if (_appinfo_get_category(db, info->appid,
+                                       &info->category)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+               if (flag & PMINFO_APPINFO_GET_APP_CONTROL) {
+                       if (_appinfo_get_app_control(db, info->appid,
+                                       &info->appcontrol)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+               if (flag & PMINFO_APPINFO_GET_METADATA) {
+                       if (_appinfo_get_metadata(db, info->appid,
+                                       &info->metadata)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+               if (flag & PMINFO_APPINFO_GET_SPLASH_SCREEN) {
+                       if (_appinfo_get_splashscreens(db, info->appid,
+                                       &info->splashscreens)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
++              if (flag & PMINFO_APPINFO_GET_RES_CONTROL) {
++                      if (_appinfo_get_res_control(db, info->appid,
++                                      &info->res_control)) {
++                              ret = PMINFO_R_ERROR;
++                              goto catch;
++                      }
++              }
++
+               if (is_check_storage &&
+                               __appinfo_check_installed_storage(info) !=
+                                               PMINFO_R_OK) {
+                       ret = PMINFO_R_ERROR;
+                       pkgmgrinfo_basic_free_application(info);
+                       info = NULL;
+                       continue;
+               }
+               g_hash_table_insert(applications, (gpointer)info->appid,
+                               (gpointer)info);
+       }
+       ret = PMINFO_R_OK;
+ catch:
+       sqlite3_finalize(stmt);
+       if (constraint)
+               free(constraint);
+       if (ret != PMINFO_R_OK && info != NULL)
+               pkgmgrinfo_basic_free_application(info);
+       g_list_free_full(bind_params, free);
+       return ret;
+ }
+ API int appinfo_internal_filter_get_list(sqlite3 *db,
+               pkgmgrinfo_appinfo_filter_h filter, uid_t db_uid, uid_t uid,
+               const char *locale, GHashTable *appinfo_list)
+ {
+       int ret;
+       if (db == NULL || filter == NULL || appinfo_list == NULL) {
+               LOGE("Invalid argument");
+               return PMINFO_R_EINVAL;
+       }
+       ret = _appinfo_get_applications(db, db_uid, uid, locale, filter,
+                       PMINFO_APPINFO_GET_ALL, appinfo_list);
+       return ret;
+ }
index 0000000000000000000000000000000000000000,a03eaf9845f5272cda755f80146bc82471ed9a9f..de0ce933acbf1cf689d8ece321b225d58b899317
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,300 +1,305 @@@
 -    std::vector<std::pair<int, std::vector<std::string>>> query_args) {
+ /*
+  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ #include "query_handler.hh"
+ #include <shared_mutex>
+ #include <vector>
+ #include "pkgmgrinfo_debug.h"
+ #include "pkgmgrinfo_internal.h"
+ #include "pkgmgr_query_index.h"
+ namespace {
+ constexpr const char query_appinfo_get_localed_label[] =
+     "SELECT COALESCE((SELECT app_label FROM package_app_localized_info "
+     "WHERE app_id=? AND app_locale=?),"
+     "(SELECT app_label FROM package_app_localized_info WHERE "
+     "app_id=? AND app_locale='No Locale'))";
+ constexpr const char query_appinfo_get_datacontrol_info[] =
+     "SELECT app_id, access FROM "
+     "package_app_data_control WHERE "
+     "providerid=? AND type=?";
+ constexpr const char query_appinfo_get_datacontrol_appid[] =
+     "SELECT app_id FROM package_app_data_control "
+     "WHERE providerid=?";
+ constexpr const char query_appinfo_get_datacontrol_trusted_info[] =
+     "SELECT app_id, trusted FROM package_app_data_control "
+     "WHERE providerid=? AND type=?";
+ constexpr const char query_appinfo_get_datacontrol_privileges[] =
+     "SELECT privilege FROM package_app_data_control_privilege "
+     "WHERE providerid=? AND type=?";
+ constexpr const char query_appinfo_get_appcontrol_privileges[] =
+     "SELECT app_control, privilege FROM package_app_app_control_privilege "
+     "WHERE app_id=?";
+ constexpr const char query_plugininfo_get_appids[] =
+     "SELECT appid FROM "
+     "package_plugin_info WHERE pkgid=? AND "
+     "plugin_type=? AND plugin_name=?";
+ constexpr const char query_get_pkg_updateinfo_1[] =
+     "SELECT package, update_version, update_type "
+     "FROM package_update_info";
+ constexpr const char query_get_pkg_updateinfo_2[] =
+     "SELECT package, update_version, update_type "
+     "FROM package_update_info WHERE package=?";
+ constexpr const char query_pkginfo_set_usr_installed_storage_1[] =
+     "UPDATE package_info SET installed_storage=?, external_path=? "
+     "WHERE package=?";
+ constexpr const char query_pkginfo_set_usr_installed_storage_2[] =
+     "UPDATE package_app_info SET app_installed_storage=?, "
+     "app_external_path=? WHERE package=?";
+ constexpr const char query_certinfo_compare_pkg_certinfo[] =
+     "SELECT package, "
+     "COALESCE(author_signer_cert, -1) FROM package_cert_info WHERE "
+     "package IN (?, ?)";
+ constexpr const char query_certinfo_compare_app_certinfo[] =
+     "SELECT app_id, package FROM "
+     "package_app_info WHERE app_id IN (?, ?)";
+ constexpr const char query_pkginfo_delete_certinfo[] =
+     "UPDATE package_cert_info SET "
+     "package_count = package_count - 1 WHERE package=?";
+ // For pkgmgr_parser
+ constexpr const char query_insert_package_plugin_execution_info[] =
+     "INSERT INTO package_plugin_info "
+     "(pkgid, appid, plugin_type, plugin_name) "
+     "VALUES (?, ?, ?, ?)";
+ constexpr const char query_delete_package_plugin_execution_info[] =
+     "DELETE FROM package_plugin_info WHERE pkgid=?";
+ constexpr const char query_update_global_app_disable[] =
+     "INSERT OR REPLACE INTO package_app_info_for_uid ("
+     "  app_id, uid, is_disabled, is_splash_screen_enabled) "
+     "VALUES (?, ?, ?,"
+     "  (SELECT app_splash_screen_display FROM package_app_info"
+     "   WHERE app_id=?))";
+ constexpr const char query_update_app_disable_info[] =
+     "UPDATE package_app_info SET app_disable=? "
+     "WHERE app_id=?";
+ constexpr const char query_update_pkg_disable_info[] =
+     "UPDATE package_info SET package_disable=? "
+     "WHERE package=?";
+ constexpr const char query_update_global_app_splash_screen_display_info[] =
+     "INSERT OR REPLACE INTO package_app_info_for_uid("
+     "  app_id, uid, is_splash_screen_enabled) "
+     "VALUES (?, ?, ?)";
+ constexpr const char query_update_app_splash_screen_display_info[] =
+     "UPDATE package_app_info SET app_splash_screen_display=? "
+     "WHERE app_id=?";
+ constexpr const char query_update_app_label_info[] =
+     "UPDATE package_app_localized_info SET app_label=? "
+     "WHERE app_id=? AND app_label IS NOT NULL";
+ constexpr const char query_update_app_icon_info[] =
+     "UPDATE package_app_localized_info SET app_icon=? "
+     "WHERE app_id=? AND app_icon IS NOT NULL";
+ constexpr const char query_update_tep_info[] =
+     "UPDATE package_info SET package_tep_name=? "
+     "WHERE package=?";
+ constexpr const char query_register_pkg_update_info[] =
+     "UPDATE package_update_info "
+     "SET update_version=?, update_type=? "
+     "WHERE package=?";
+ constexpr const char query_unregister_pkg_update_info[] =
+     "UPDATE package_update_info "
+     "SET update_type='none' WHERE package=?";
+ constexpr const char query_unregister_all_pkg_update_info[] =
+     "UPDATE package_update_info "
+     "SET update_type='none'";
+ class QueryMaker {
+  public:
+   std::vector<const char*> query_raw_ = {
+     query_appinfo_get_localed_label,
+     query_appinfo_get_datacontrol_info,
+     query_appinfo_get_datacontrol_appid,
+     query_appinfo_get_datacontrol_trusted_info,
+     query_appinfo_get_datacontrol_privileges,
+     query_appinfo_get_appcontrol_privileges,
+     query_plugininfo_get_appids,
+     query_get_pkg_updateinfo_1,
+     query_get_pkg_updateinfo_2,
+     query_pkginfo_set_usr_installed_storage_1,
+     query_pkginfo_set_usr_installed_storage_2,
+     query_certinfo_compare_pkg_certinfo,
+     query_certinfo_compare_app_certinfo,
+     query_pkginfo_delete_certinfo,
+     query_insert_package_plugin_execution_info,
+     query_delete_package_plugin_execution_info,
+     query_update_global_app_disable,
+     query_update_app_disable_info,
+     query_update_pkg_disable_info,
+     query_update_global_app_splash_screen_display_info,
+     query_update_app_splash_screen_display_info,
+     query_update_app_label_info,
+     query_update_app_icon_info,
+     query_update_tep_info,
+     query_register_pkg_update_info,
+     query_unregister_pkg_update_info,
+     query_unregister_all_pkg_update_info,
+   };
+   const char* GetQuery(int index) {
+     return query_raw_[index];
+   }
+ };
+ QueryMaker __query_maker;
+ void __free_argument(gpointer data) {
+   query_args* args = (query_args*)data;
+   g_list_free(args->argument);
+   free(args);
+ }
+ void __free_query_list(GList* queries, GList* args_list) {
+   g_list_free(queries);
+   g_list_free_full(args_list, __free_argument);
+ }
+ }  // namespace
+ namespace pkgmgr_server {
+ namespace database {
+ QueryHandler::QueryHandler(uid_t uid, int pid)
+     : AbstractDBHandler(uid, pid), uid_(uid) {}
+ QueryHandler::~QueryHandler() {}
+ void QueryHandler::SetQueryArgs(
 -std::vector<std::vector<std::string>> QueryHandler::GetResult() {
++    std::vector<pkgmgr_common::parcel::QueryArgs> query_args) {
+   query_args_ = std::move(query_args);
+ }
+ std::string QueryHandler::GetString() { return std::string(); }
+ int QueryHandler::GetInt() { return 0; }
+ int QueryHandler::GetRecordCount() { return 0; }
 -    for (auto& argument : i.second)
 -      arg->argument = g_list_append(arg->argument, (gpointer)argument.c_str());
++std::vector<pkgmgr_common::parcel::StrArgs> QueryHandler::GetResult() {
+   return std::move(result_);
+ }
+ int QueryHandler::Execute() {
+   std::shared_lock<std::shared_timed_mutex> s(lock_);
+   if (!Connect()) {
+     _LOGE("Failed to connect database");
+     return PMINFO_R_ERROR;
+   }
+   GList* queries = nullptr;
+   GList* args_list = nullptr;
+   for (auto& i : query_args_) {
+     const char* query = __query_maker.GetQuery(i.first);
+     if (query == nullptr) {
+       _LOGE("Failed to get query");
+       __free_query_list(queries, args_list);
+       return PMINFO_R_ERROR;
+     }
+     queries = g_list_append(queries, (gpointer)query);
+     query_args* arg = (query_args*)calloc(1, sizeof(query_args));
+     if (arg == nullptr) {
+       _LOGE("Out of memory");
+       __free_query_list(queries, args_list);
+       return PMINFO_R_ERROR;
+     }
+     arg->len = i.second.size();
 -          std::vector<std::string> vt;
++    for (auto& argument : i.second) {
++      arg->argument = g_list_append(arg->argument,
++          gpointer(argument ? (*argument).c_str() : nullptr));
++    }
+     args_list = g_list_append(args_list, arg);
+   }
+   std::vector<std::pair<sqlite3*, uid_t>> conn_list = GetConnection();
+   int ret;
+   if (GetOpType() == pkgmgr_common::DBOperationType::OPERATION_TYPE_READ) {
+     for (auto& conn : conn_list) {
+       for (GList* it = args_list; it; it = it->next) {
+         GList* list = nullptr;
+         int row = 0;
+         int col = 0;
+         query_args* params = (query_args*)it->data;
+         ret = get_query_result(conn.first, (const char *)queries->data,
+             params->argument, &list, &row, &col);
+         if (ret == PMINFO_R_ERROR) {
+           _LOGE("Failed to execute query");
+           __free_query_list(queries, args_list);
+           return ret;
+         }
+         GList* tmp = list;
+         for (int i = 0; i < row; ++i) {
 -            vt.emplace_back(reinterpret_cast<char *>(tmp->data));
++          pkgmgr_common::parcel::StrArgs vt;
+           for (int j = 0; j < col; ++j) {
++            if (!tmp->data)
++              vt.emplace_back(std::nullopt);
++            else
++              vt.emplace_back(reinterpret_cast<char *>(tmp->data));
+             tmp = tmp->next;
+           }
+           result_.emplace_back(std::move(vt));
+         }
+         g_list_free_full(list, free);
+       }
+     }
+     __free_query_list(queries, args_list);
+     return ret;
+   } else {
+     for (auto& conn : conn_list) {
+       ret = execute_write_queries(conn.first, queries, args_list);
+       if (ret != PMINFO_R_OK) {
+         _LOGE("Failed to execute");
+         break;
+       }
+     }
+     __free_query_list(queries, args_list);
+     return ret;
+   }
+   return ret;
+ }
+ }  // namespace database
+ }  // namespace pkgmgr_server
index 0000000000000000000000000000000000000000,5492af37fc814af250e5eeec9d22e1e95982e8b6..7b39a3ad65717cf6f51479ccac33b4a16b682765
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,61 +1,62 @@@
 -  void SetQueryArgs(std::vector<std::pair<int, std::vector<std::string>>> query_args);
+ /*
+  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ #ifndef QUERY_HANDLER_HH_
+ #define QUERY_HANDLER_HH_
+ #include <string>
+ #include <vector>
+ #include <sys/types.h>
+ #include "abstract_db_handler.hh"
+ #include "db_type.hh"
+ #include "pkgmgrinfo_basic.h"
+ #include "pkgmgrinfo_private.h"
++#include "query_parcelable.hh"
+ namespace pkgmgr_server {
+ namespace database {
+ #ifndef EXPORT_API
+ #define EXPORT_API __attribute__((visibility("default")))
+ #endif
+ class EXPORT_API QueryHandler : public AbstractDBHandler {
+  public:
+   QueryHandler(uid_t uid, int pid);
+   ~QueryHandler();
 -  std::vector<std::vector<std::string>> GetResult();
++  void SetQueryArgs(std::vector<pkgmgr_common::parcel::QueryArgs> query_args);
+   bool BindString(std::string value);
+   bool BindInt(int value);
+   std::string GetString();
+   int GetInt();
+   int GetRecordCount();
+   int Execute() override;
 -  std::vector<std::pair<int, std::vector<std::string>>> query_args_;
 -  std::vector<std::vector<std::string>> result_;
++  std::vector<pkgmgr_common::parcel::StrArgs> GetResult();
+  private:
+   uid_t uid_;
+   std::vector<std::string> query_;
++  std::vector<pkgmgr_common::parcel::QueryArgs> query_args_;
++  std::vector<pkgmgr_common::parcel::StrArgs> result_;
+ };
+ }  // namespace database
+ }  // namespace pkgmgr_server
+ #endif  // QUERY_HANDLER_HH_
index 0000000000000000000000000000000000000000,9f3b7b1dea1a39789b05d32adc75d90f481fa886..f3d50787cd9c4d8ef29cbad7146742c51a0d4289
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,2394 +1,2697 @@@
 -              __BIND_TEXT(db, stmt, idx++, app->component);
+ /*
+  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ #define _GNU_SOURCE
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <stdbool.h>
+ #include <unistd.h>
+ #include <ctype.h>
+ #include <sys/smack.h>
+ #include <linux/limits.h>
+ #include <libgen.h>
+ #include <sys/stat.h>
+ #include <sqlite3.h>
+ #include <glib.h>
+ #include <system_info.h>
+ #include "pkgmgr_parser.h"
+ #include "pkgmgrinfo_basic.h"
+ #include "pkgmgrinfo_internal.h"
+ #include "pkgmgrinfo_private.h"
+ #include "pkgmgrinfo_debug.h"
+ #include "pkgmgr-info.h"
+ #define LDPI "ldpi"
+ #define MDPI "mdpi"
+ #define HDPI "hdpi"
+ #define XHDPI "xhdpi"
+ #define XXHDPI "xxhdpi"
+ #define LDPI_MIN 0
+ #define LDPI_MAX 240
+ #define MDPI_MIN 241
+ #define MDPI_MAX 300
+ #define HDPI_MIN 301
+ #define HDPI_MAX 380
+ #define XHDPI_MIN 381
+ #define XHDPI_MAX 480
+ #define XXHDPI_MIN 481
+ #define XXHDPI_MAX 600
+ static const char join_localized_info[] =
+       " LEFT OUTER JOIN package_localized_info"
+       "  ON pi.package=package_localized_info.package"
+       "  AND package_localized_info.package_locale=?";
+ static const char join_privilege_info[] =
+       " LEFT OUTER JOIN package_privilege_info"
+       "  ON pi.package=package_privilege_info.package";
++static const char join_res_info[] =
++      " LEFT OUTER JOIN package_res_info"
++      "  ON pi.package=package_res_info.package";
+ static int _get_filtered_query(pkgmgrinfo_filter_x *filter,
+               const char *locale, uid_t uid,
+               char **query, GList **bind_params)
+ {
+       int joined = 0;
+       int size;
+       char buf[MAX_QUERY_LEN] = { '\0' };
+       char buf2[MAX_QUERY_LEN] = { '\0' };
+       char *condition = NULL;
+       GSList *list = NULL;
+       if (filter == NULL)
+               return PMINFO_R_OK;
+       snprintf(buf, sizeof(buf), "%s", " WHERE 1=1 ");
+       for (list = filter->list; list; list = list->next) {
+               joined |= __get_filter_condition(list->data, uid, &condition,
+                               bind_params);
+               if (condition == NULL)
+                       continue;
+               strncat(buf, " AND ", sizeof(buf) - strlen(buf) - 1);
+               strncat(buf, condition, sizeof(buf) - strlen(buf) - 1);
+               free(condition);
+               condition = NULL;
+       }
+       if (joined & E_PMINFO_PKGINFO_JOIN_LOCALIZED_INFO) {
+               strncat(buf2, join_localized_info,
+                               sizeof(buf2) - strlen(buf2) - 1);
+               *bind_params = g_list_append(*bind_params, strdup(locale));
+       }
+       if (joined & E_PMINFO_PKGINFO_JOIN_PRIVILEGE_INFO)
+               strncat(buf2, join_privilege_info,
+                               sizeof(buf2) - strlen(buf2) - 1);
++      if (joined & E_PMINFO_PKGINFO_JOIN_RES_INFO)
++              strncat(buf2, join_res_info,
++                              sizeof(buf2) - strlen(buf2) - 1);
+       size = strlen(buf2) + strlen(buf) + 1;
+       *query = (char *)calloc(1, size);
+       if (*query == NULL)
+               return PMINFO_R_ERROR;
+       snprintf(*query, size, "%s%s", buf2, buf);
+       return PMINFO_R_OK;
+ }
+ static int __bind_params(sqlite3_stmt *stmt, GList *params)
+ {
+       GList *tmp_list = NULL;
+       int idx = 0;
+       int ret;
+       if (stmt == NULL || params == NULL)
+               return PMINFO_R_EINVAL;
+       tmp_list = params;
+       while (tmp_list) {
+               ret = sqlite3_bind_text(stmt, ++idx,
+                               (char *)tmp_list->data, -1, SQLITE_STATIC);
+               if (ret != SQLITE_OK)
+                       return PMINFO_R_ERROR;
+               tmp_list = tmp_list->next;
+       }
+       return PMINFO_R_OK;
+ }
+ static bool __check_package_storage_status(pkgmgrinfo_filter_x *tmp_filter)
+ {
+       GSList *tmp_list = NULL;
+       pkgmgrinfo_node_x *tmp_node = NULL;
+       int property = -1;
+       property = _pminfo_pkginfo_convert_to_prop_bool(
+                               PMINFO_PKGINFO_PROP_PACKAGE_CHECK_STORAGE);
+       for (tmp_list = tmp_filter->list; tmp_list != NULL;
+                       tmp_list = g_slist_next(tmp_list)) {
+               tmp_node = (pkgmgrinfo_node_x *)tmp_list->data;
+               if (property == tmp_node->prop) {
+                       if (strcmp(tmp_node->value, "true") == 0)
+                               return true;
+                       else
+                               return false;
+               }
+       }
+       return true;
+ }
+ static int _pkginfo_add_description_info_into_list(const char *locale,
+               char *record, GList **description)
+ {
+       description_x *info;
+       info = calloc(1, sizeof(description_x));
+       if (info == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+       info->lang = strdup(locale);
+       info->text = record;
+       *description = g_list_prepend(*description, info);
+       return PMINFO_R_OK;
+ }
+ static int _pkginfo_get_plugin_execution_info(sqlite3 *db, const char *pkgid,
+               GList **plugins)
+ {
+       static const char query_raw[] =
+               "SELECT appid, plugin_type, plugin_name FROM package_plugin_info "
+               "WHERE pkgid=%Q";
+       int ret;
+       char *query;
+       sqlite3_stmt *stmt;
+       plugin_x *plugin;
+       query = sqlite3_mprintf(query_raw, pkgid);
+       if (query == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+       ret = sqlite3_prepare_v2(db, query, strlen(query),
+                       &stmt, NULL);
+       sqlite3_free(query);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               plugin = calloc(1, sizeof(plugin_x));
+               if (!plugin) {
+                       LOGE("out of memory");
+                       sqlite3_finalize(stmt);
+                       return PMINFO_R_ERROR;
+               }
+               plugin->pkgid = strdup(pkgid);
+               _save_column_str(stmt, 0, &plugin->appid);
+               _save_column_str(stmt, 1, &plugin->plugin_type);
+               _save_column_str(stmt, 2, &plugin->plugin_name);
+               *plugins = g_list_prepend(*plugins,
+                               (gpointer)plugin);
+       }
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
+ static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid,
+               GList **privileges)
+ {
+       static const char query_raw[] =
+               "SELECT DISTINCT privilege, type FROM package_privilege_info "
+               "WHERE package=%Q";
+       int ret;
+       char *query;
+       sqlite3_stmt *stmt;
+       privilege_x *privilege;
+       query = sqlite3_mprintf(query_raw, pkgid);
+       if (query == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+       ret = sqlite3_prepare_v2(db, query, strlen(query),
+                       &stmt, NULL);
+       sqlite3_free(query);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               privilege = calloc(1, sizeof(privilege_x));
+               if (!privilege) {
+                       LOGE("failed to alloc memory");
+                       sqlite3_finalize(stmt);
+                       return PMINFO_R_ERROR;
+               }
+               _save_column_str(stmt, 0, &privilege->value);
+               _save_column_str(stmt, 1, &privilege->type);
+               *privileges = g_list_prepend(*privileges,
+                               (gpointer)privilege);
+       }
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
+ static int _pkginfo_get_appdefined_privilege(sqlite3 *db, const char *pkgid,
+               GList **privileges)
+ {
+       static const char query_raw[] =
+               "SELECT DISTINCT privilege, license, type FROM "
+               "package_appdefined_privilege_info WHERE package=%Q";
+       int ret;
+       char *query;
+       sqlite3_stmt *stmt;
+       appdefined_privilege_x *privilege;
+       query = sqlite3_mprintf(query_raw, pkgid);
+       if (query == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+       ret = sqlite3_prepare_v2(db, query, strlen(query),
+                       &stmt, NULL);
+       sqlite3_free(query);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               privilege = calloc(1, sizeof(appdefined_privilege_x));
+               if (!privilege) {
+                       LOGE("failed to alloc memory");
+                       sqlite3_finalize(stmt);
+                       return PMINFO_R_ERROR;
+               }
+               _save_column_str(stmt, 0, &privilege->value);
+               _save_column_str(stmt, 1, &privilege->license);
+               _save_column_str(stmt, 2, &privilege->type);
+               *privileges = g_list_prepend(*privileges,
+                               (gpointer)privilege);
+       }
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
+ static int _pkginfo_get_dependency(sqlite3 *db, const char *pkgid,
+               GList **dependencies)
+ {
+       static const char query_raw[] =
+               "SELECT DISTINCT depends_on, type, required_version "
+               "FROM package_dependency_info WHERE package=%Q";
+       int ret;
+       char *query;
+       sqlite3_stmt *stmt;
+       dependency_x *dependency;
+       query = sqlite3_mprintf(query_raw, pkgid);
+       if (query == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       sqlite3_free(query);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               dependency = calloc(1, sizeof(dependency_x));
+               if (!dependency) {
+                       LOGE("failed to alloc memory");
+                       sqlite3_finalize(stmt);
+                       return PMINFO_R_ERROR;
+               }
+               _save_column_str(stmt, 0, &dependency->depends_on);
+               _save_column_str(stmt, 1, &dependency->type);
+               _save_column_str(stmt, 2, &dependency->required_version);
+               *dependencies = g_list_prepend(*dependencies,
+                               (gpointer)dependency);
+       }
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
++static int _pkginfo_get_res_allowed_packages(sqlite3 *db, const char *pkgid,
++              GList **allowed_packages)
++{
++      static const char query_raw[] =
++              "SELECT DISTINCT allowed_package, required_privilege "
++              "FROM package_res_allowed_package WHERE package=%Q";
++      int ret;
++      char *query;
++      char *package;
++      char *privilege;
++      sqlite3_stmt *stmt;
++      res_allowed_package_x *allowed_package_x;
++      GList *l;
++
++      query = sqlite3_mprintf(query_raw, pkgid);
++      if (query == NULL) {
++              LOGE("out of memory");
++              return PMINFO_R_ERROR;
++      }
++
++      ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
++      sqlite3_free(query);
++      if (ret != SQLITE_OK) {
++              LOGE("prepare failed: %s", sqlite3_errmsg(db));
++              return PMINFO_R_ERROR;
++      }
++
++      while (sqlite3_step(stmt) == SQLITE_ROW) {
++              allowed_package_x = NULL;
++              package = NULL;
++              privilege = NULL;
++
++              _save_column_str(stmt, 0, &package);
++              if (!package)
++                      continue;
++
++              for (l = *allowed_packages; l; l = l->next) {
++                      allowed_package_x = (res_allowed_package_x *)l->data;
++                      if (!strcmp(package, (char *)l->data))
++                              break;
++                      allowed_package_x = NULL;
++              }
++
++              if (allowed_package_x) {
++                      free(package);
++              } else {
++                      allowed_package_x = calloc(1,
++                                      sizeof(res_allowed_package_x));
++                      if (allowed_package_x == NULL) {
++                              LOGE("failed to alloc memory");
++                              sqlite3_finalize(stmt);
++                              free(package);
++                              return PMINFO_R_ERROR;
++                      }
++                      allowed_package_x->allowed_package = package;
++                      *allowed_packages = g_list_prepend(*allowed_packages,
++                                      (gpointer)allowed_package_x);
++              }
++
++              _save_column_str(stmt, 1, &privilege);
++              if (!privilege)
++                      continue;
++
++              allowed_package_x->required_privileges = g_list_prepend(
++                              allowed_package_x->required_privileges,
++                              privilege);
++      }
++
++      sqlite3_finalize(stmt);
++
++      return PMINFO_R_OK;
++}
++
++static int _pkginfo_get_res_info(sqlite3 *db, const char *pkgid,
++              char **res_type, char **res_version,
++              GList **res_allowed_packages)
++{
++      static const char query_raw[] =
++              "SELECT DISTINCT res_type, res_version "
++              "FROM package_res_info WHERE package=%Q";
++      int ret;
++      char *query;
++      sqlite3_stmt *stmt;
++
++      query = sqlite3_mprintf(query_raw, pkgid);
++      if (query == NULL) {
++              LOGE("out of memory");
++              return PMINFO_R_ERROR;
++      }
++
++      ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
++      sqlite3_free(query);
++      if (ret != SQLITE_OK) {
++              LOGE("prepare failed: %s", sqlite3_errmsg(db));
++              return PMINFO_R_ERROR;
++      }
++
++      if (sqlite3_step(stmt) != SQLITE_ROW) {
++              sqlite3_finalize(stmt);
++              return PMINFO_R_OK;
++      }
++
++      _save_column_str(stmt, 0, res_type);
++      _save_column_str(stmt, 1, res_version);
++
++      if (_pkginfo_get_res_allowed_packages(db, pkgid,
++                      res_allowed_packages) != PMINFO_R_OK) {
++              sqlite3_finalize(stmt);
++              return PMINFO_R_ERROR;
++      }
++
++      sqlite3_finalize(stmt);
++
++      return PMINFO_R_OK;
++}
++
+ static int _pkginfo_get_packages(sqlite3 *db, uid_t uid, const char *locale,
+               pkgmgrinfo_filter_x *filter, int flag, GHashTable *packages)
+ {
+       static const char query_raw[] =
+               "SELECT DISTINCT pi.package, pi.installed_storage, pi.external_path";
+       static const char query_basic[] =
+               ", pi.package_version, pi.install_location, "
+               "pi.package_removable, pi.package_preload, pi.package_readonly, "
+               "pi.package_update, pi.package_appsetting, pi.package_system, "
+               "pi.package_type, pi.package_size, pi.installed_time, "
+               "pi.storeclient_id, pi.mainapp_id, pi.package_url, pi.root_path, "
+               "pi.csc_path, pi.package_nodisplay, pi.package_api_version, "
+               "pi.package_support_disable, pi.package_tep_name, "
+               "pi.package_zip_mount_file, pi.package_support_mode";
+       static const char query_author[] =
+               ", pi.author_name, pi.author_email, pi.author_href";
+       static const char query_label[] =
+               ", COALESCE("
+               "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
+               "(SELECT package_label FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
+       static const char query_icon[] =
+               ", COALESCE("
+               "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
+               "(SELECT package_icon FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
+       static const char query_description[] =
+               ", COALESCE("
+               "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale=?), "
+               "(SELECT package_description FROM package_localized_info WHERE pi.package=package AND package_locale='No Locale'))";
++      static const char query_res_type[] =
++              ", (SELECT res_type FROM package_res_info WHERE pi.package=package)";
++      static const char query_res_version[] =
++              ", (SELECT res_version FROM package_res_info WHERE pi.package=package)";
+       static const char query_from_clause[] = " FROM package_info as pi";
+       int ret = PMINFO_R_ERROR;
+       int idx = 0;
+       char *tmp_record = NULL;
+       char *constraints = NULL;
+       char query[MAX_QUERY_LEN] = { '\0' };
+       package_x *info = NULL;
+       author_x *author = NULL;
+       GList *bind_params = NULL;
+       sqlite3_stmt *stmt = NULL;
+       bool is_check_storage = true;
+       const uid_t global_user_uid = GLOBAL_USER;
+       if (db == NULL || locale == NULL || filter == NULL) {
+               LOGE("Invalid parameter");
+               return PMINFO_R_EINVAL;
+       }
+       is_check_storage = __check_package_storage_status(filter);
+       snprintf(query, MAX_QUERY_LEN - 1, "%s", query_raw);
+       if (flag & PMINFO_APPINFO_GET_BASICINFO)
+               strncat(query, query_basic, sizeof(query) - strlen(query) - 1);
+       if (flag & PMINFO_PKGINFO_GET_AUTHOR)
+               strncat(query, query_author, sizeof(query) - strlen(query) - 1);
+       if (flag & PMINFO_PKGINFO_GET_LABEL) {
+               strncat(query, query_label, sizeof(query) - strlen(query) - 1);
+               bind_params = g_list_append(bind_params, strdup(locale));
+       }
+       if (flag & PMINFO_PKGINFO_GET_ICON) {
+               strncat(query, query_icon, sizeof(query) - strlen(query) - 1);
+               bind_params = g_list_append(bind_params, strdup(locale));
+       }
+       if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
+               strncat(query, query_description,
+                               sizeof(query) - strlen(query) - 1);
+               bind_params = g_list_append(bind_params, strdup(locale));
+       }
++      if (flag & PMINFO_PKGINFO_GET_RES_INFO) {
++              strncat(query, query_res_type,
++                              sizeof(query) - strlen(query) - 1);
++              strncat(query, query_res_version,
++                              sizeof(query) - strlen(query) - 1);
++      }
+       strncat(query, query_from_clause, sizeof(query) - strlen(query) - 1);
+       ret = _get_filtered_query(filter, locale, uid,
+                       &constraints, &bind_params);
+       if (ret != PMINFO_R_OK) {
+               LOGE("Failed to get WHERE clause");
+               goto catch;
+       }
+       if (constraints)
+               strncat(query, constraints, sizeof(query) - strlen(query) - 1);
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               ret = PMINFO_R_ERROR;
+               goto catch;
+       }
+       ret = __bind_params(stmt, bind_params);
+       if (ret != SQLITE_OK) {
+               LOGE("Failed to bind parameters");
+               goto catch;
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               info = calloc(1, sizeof(package_x));
+               if (info == NULL) {
+                       LOGE("out of memory");
+                       ret = PMINFO_R_ERROR;
+                       goto catch;
+               }
+               info->locale = strdup(locale);
+               if (info->locale == NULL) {
+                       LOGE("Out of memory");
+                       ret = PMINFO_R_ERROR;
+                       goto catch;
+               }
+               idx = 0;
+               _save_column_str(stmt, idx++, &info->package);
+               _save_column_str(stmt, idx++, &info->installed_storage);
+               _save_column_str(stmt, idx++, &info->external_path);
+               if (flag & PMINFO_APPINFO_GET_BASICINFO) {
+                       _save_column_str(stmt, idx++, &info->version);
+                       _save_column_str(stmt, idx++, &info->installlocation);
+                       _save_column_str(stmt, idx++, &info->removable);
+                       _save_column_str(stmt, idx++, &info->preload);
+                       _save_column_str(stmt, idx++, &info->readonly);
+                       _save_column_str(stmt, idx++, &info->update);
+                       _save_column_str(stmt, idx++, &info->appsetting);
+                       _save_column_str(stmt, idx++, &info->system);
+                       _save_column_str(stmt, idx++, &info->type);
+                       _save_column_str(stmt, idx++, &info->package_size);
+                       _save_column_str(stmt, idx++, &info->installed_time);
+                       _save_column_str(stmt, idx++, &info->storeclient_id);
+                       _save_column_str(stmt, idx++, &info->mainapp_id);
+                       _save_column_str(stmt, idx++, &info->package_url);
+                       _save_column_str(stmt, idx++, &info->root_path);
+                       _save_column_str(stmt, idx++, &info->csc_path);
+                       _save_column_str(stmt, idx++, &info->nodisplay_setting);
+                       _save_column_str(stmt, idx++, &info->api_version);
+                       _save_column_str(stmt, idx++, &info->support_disable);
+                       _save_column_str(stmt, idx++, &info->tep_name);
+                       _save_column_str(stmt, idx++, &info->zip_mount_file);
+                       _save_column_str(stmt, idx++, &info->support_mode);
+               }
+               info->for_all_users =
+                       strdup((uid != global_user_uid) ? "false" : "true");
+               if (_pkginfo_get_plugin_execution_info(db,
+                               info->package, &info->plugin)) {
+                       ret = PMINFO_R_ERROR;
+                       goto catch;
+               }
+               if (flag & PMINFO_PKGINFO_GET_AUTHOR) {
+                       /* TODO : author should be retrieved at package_localized_info */
+                       author = calloc(1, sizeof(author_x));
+                       if (author == NULL) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+                       _save_column_str(stmt, idx++, &author->text);
+                       _save_column_str(stmt, idx++, &author->email);
+                       _save_column_str(stmt, idx++, &author->href);
+                       info->author = g_list_prepend(info->author, author);
+               }
+               if (flag & PMINFO_PKGINFO_GET_LABEL) {
+                       tmp_record = NULL;
+                       _save_column_str(stmt, idx++, &tmp_record);
+                       if (_add_label_info_into_list(locale,
+                                       tmp_record, &info->label)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+               if (flag & PMINFO_PKGINFO_GET_ICON) {
+                       tmp_record = NULL;
+                       _save_column_str(stmt, idx++, &tmp_record);
+                       if (_add_icon_info_into_list(locale,
+                                       tmp_record, &info->icon)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+               if (flag & PMINFO_PKGINFO_GET_DESCRIPTION) {
+                       tmp_record = NULL;
+                       _save_column_str(stmt, idx++, &tmp_record);
+                       if (_pkginfo_add_description_info_into_list(locale,
+                                       tmp_record, &info->description)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+               if (flag & PMINFO_PKGINFO_GET_PRIVILEGE) {
+                       if (_pkginfo_get_privilege(db, info->package,
+                                               &info->privileges)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+               if (flag & PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE) {
+                       if (_pkginfo_get_appdefined_privilege(db, info->package,
+                                               &info->appdefined_privileges)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
+               if (flag & PMINFO_PKGINFO_GET_DEPENDENCY) {
+                       if (_pkginfo_get_dependency(db, info->package,
+                                               &info->dependencies)) {
+                               ret = PMINFO_R_ERROR;
+                               goto catch;
+                       }
+               }
++              if (flag & PMINFO_PKGINFO_GET_RES_INFO) {
++                      if (_pkginfo_get_res_info(db, info->package,
++                                      &info->res_type,
++                                      &info->res_version,
++                                      &info->res_allowed_packages) < 0) {
++                              ret = PMINFO_R_ERROR;
++                              goto catch;
++                      }
++              }
++
+               if (is_check_storage &&
+                               __pkginfo_check_installed_storage(info) !=
+                                               PMINFO_R_OK) {
+                       ret = PMINFO_R_ERROR;
+                       pkgmgrinfo_basic_free_package(info);
+                       info = NULL;
+                       continue;
+               }
+               g_hash_table_insert(packages, (gpointer)info->package,
+                               (gpointer)info);
+       }
+       ret = PMINFO_R_OK;
+ catch:
+       sqlite3_finalize(stmt);
+       if (constraints)
+               free(constraints);
+       if (ret != PMINFO_R_OK && info != NULL)
+               pkgmgrinfo_basic_free_package(info);
+       g_list_free_full(bind_params, free);
+       return ret;
+ }
+ API int pkginfo_internal_filter_get_list(
+               sqlite3 *db, pkgmgrinfo_pkginfo_filter_h filter,
+               uid_t uid, const char *locale, GHashTable *pkginfo_list)
+ {
+       int ret;
+       if (filter == NULL || pkginfo_list == NULL) {
+               LOGE("Invalid argument");
+               return PMINFO_R_EINVAL;
+       }
+       ret = _pkginfo_get_packages(db, uid, locale, filter,
+                       PMINFO_PKGINFO_GET_ALL, pkginfo_list);
+       return ret;
+ }
+ API int get_query_result(sqlite3 *db, const char *query, GList *param,
+               GList **list, int *row, int *col)
+ {
+       int ret = 0;
+       int col_cnt = 0;
+       int row_cnt = 0;
+       int idx = 0;
+       sqlite3_stmt *stmt = NULL;
+       char *result = NULL;
+       if (db == NULL || query == NULL) {
+               LOGE("Invalid parameter");
+               return PMINFO_R_EINVAL;
+       }
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+       if (g_list_length(param) != 0) {
+               ret = __bind_params(stmt, param);
+               if (ret != PMINFO_R_OK) {
+                       LOGE("failed to bind parameters: %s", sqlite3_errmsg(db));
+                       return ret;
+               }
+       }
+       col_cnt = sqlite3_column_count(stmt);
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               row_cnt++;
+               for (idx = 0; idx < col_cnt; ++idx) {
+                       _save_column_str(stmt, idx, &result);
+                       *list = g_list_append(*list, result);
+                       result = NULL;
+               }
+       }
+       *row = row_cnt;
+       *col = col_cnt;
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
+ static int _get_depends_on(sqlite3 *db, const char *pkgid, GQueue **queue,
+               GHashTable **table, GList **pkg_list)
+ {
+       static const char query[] =
+               "SELECT package, depends_on, type, required_version "
+               "FROM package_dependency_info WHERE depends_on=?";
+       int ret;
+       sqlite3_stmt *stmt;
+       dependency_x *req;
+       /* already checked */
+       if (!g_hash_table_insert(*table, strdup(pkgid), GINT_TO_POINTER(1)))
+               return PMINFO_R_OK;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return PMINFO_R_ERROR;
+       }
+       ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
+       if (ret != SQLITE_OK) {
+               LOGE("bind failed: %s", sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               return PMINFO_R_ERROR;
+       }
+       while (sqlite3_step(stmt) == SQLITE_ROW) {
+               req = calloc(1, sizeof(dependency_x));
+               if (req == NULL) {
+                       LOGE("out of memory");
+                       sqlite3_finalize(stmt);
+                       return PMINFO_R_ERROR;
+               }
+               _save_column_str(stmt, 0, &req->pkgid);
+               _save_column_str(stmt, 1, &req->depends_on);
+               _save_column_str(stmt, 2, &req->type);
+               _save_column_str(stmt, 3, &req->required_version);
+               *pkg_list = g_list_prepend(*pkg_list, req);
+               g_queue_push_tail(*queue, strdup(req->pkgid));
+       }
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
+ static void __free_depends_on(gpointer data)
+ {
+       struct dependency_x *dep = (struct dependency_x *)data;
+       free(dep->pkgid);
+       free(dep->depends_on);
+       free(dep->type);
+       free(dep->required_version);
+       free(dep);
+ }
+ API int pkginfo_internal_filter_get_depends_on(sqlite3 *db, const char *pkgid,
+               GList **list)
+ {
+       GQueue *queue;
+       GHashTable *table;
+       char *item;
+       int ret;
+       if (db == NULL || pkgid == NULL) {
+               LOGE("Invalid parameter");
+               return PMINFO_R_EINVAL;
+       }
+       queue = g_queue_new();
+       if (queue == NULL) {
+               LOGE("out of memory");
+               return PMINFO_R_ERROR;
+       }
+       table = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
+       g_queue_push_tail(queue, strdup(pkgid));
+       while (!g_queue_is_empty(queue)) {
+               item = g_queue_pop_head(queue);
+               ret = _get_depends_on(db, item, &queue, &table, list);
+               free(item);
+               if (ret != PMINFO_R_OK) {
+                       LOGE("failed to get pkgs depends on %s", pkgid);
+                       g_hash_table_destroy(table);
+                       g_list_free_full(*list, __free_depends_on);
+                       g_queue_free_full(queue, free);
+                       return PMINFO_R_ERROR;
+               }
+       }
+       g_hash_table_destroy(table);
+       g_queue_free_full(queue, free);
+       return PMINFO_R_OK;
+ }
+ static int __execute_query(sqlite3 *db, const char *query, GList *param)
+ {
+       int ret = 0;
+       sqlite3_stmt *stmt = NULL;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       if (g_list_length(param) != 0) {
+               ret = __bind_params(stmt, param);
+               if (ret != PMINFO_R_OK) {
+                       LOGE("failed to bind parameters: %s", sqlite3_errmsg(db));
+                       return ret;
+               }
+       }
+       ret = sqlite3_step(stmt);
+       if (ret != SQLITE_DONE && ret != SQLITE_OK) {
+               LOGE("step failed:%d %s", ret, sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               return -1;
+       }
+       sqlite3_finalize(stmt);
+       return PMINFO_R_OK;
+ }
+ API int execute_write_queries(sqlite3 *db, GList *queries, GList *params_list)
+ {
+       int i;
+       query_args *tmp_ptr = NULL;
+       if (db == NULL || queries == NULL) {
+               _LOGE("Invalid parameter");
+               return PMINFO_R_EINVAL;
+       }
+       __BEGIN_TRANSACTION(db);
+       for (i = 0; i < g_list_length(queries); ++i) {
+               tmp_ptr = (query_args *)g_list_nth_data(params_list, i);
+               if (tmp_ptr == NULL) {
+                       _LOGE("Failed to get parameter list");
+                       sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
+                       return PMINFO_R_ERROR;
+               }
+               __DO_TRANSACTION(db,
+                               __execute_query(db, g_list_nth_data(queries, i),
+                                               tmp_ptr->argument));
+       }
+       __END_TRANSACTION(db);
+       return PMINFO_R_OK;
+ }
+ static int __check_dpi(const char *dpi_char, int dpi_int)
+ {
+       if (dpi_char == NULL)
+               return -1;
+       if (strcasecmp(dpi_char, LDPI) == 0) {
+               if (dpi_int >= LDPI_MIN && dpi_int <= LDPI_MAX)
+                       return 0;
+               else
+                       return -1;
+       } else if (strcasecmp(dpi_char, MDPI) == 0) {
+               if (dpi_int >= MDPI_MIN && dpi_int <= MDPI_MAX)
+                       return 0;
+               else
+                       return -1;
+       } else if (strcasecmp(dpi_char, HDPI) == 0) {
+               if (dpi_int >= HDPI_MIN && dpi_int <= HDPI_MAX)
+                       return 0;
+               else
+                       return -1;
+       } else if (strcasecmp(dpi_char, XHDPI) == 0) {
+               if (dpi_int >= XHDPI_MIN && dpi_int <= XHDPI_MAX)
+                       return 0;
+               else
+                       return -1;
+       } else if (strcasecmp(dpi_char, XXHDPI) == 0) {
+               if (dpi_int >= XXHDPI_MIN && dpi_int <= XXHDPI_MAX)
+                       return 0;
+               else
+                       return -1;
+       } else
+               return -1;
+ }
+ static void __find_appcontrol_splashscreen_with_dpi(gpointer data,
+               gpointer user_data)
+ {
+       splashscreen_x *ss = (splashscreen_x *)data;
+       GList **list = (GList **)user_data;
+       int dpi = -1;
+       int ret;
+       if (ss->operation == NULL || ss->dpi == NULL)
+               return;
+       ret = system_info_get_platform_int(
+                       "http://tizen.org/feature/screen.dpi", &dpi);
+       if (ret != SYSTEM_INFO_ERROR_NONE)
+               return;
+       if (__check_dpi(ss->dpi, dpi) != 0)
+               return;
+       *list = g_list_prepend(*list, ss);
+ }
+ static void __find_appcontrol_splashscreen(gpointer data, gpointer user_data)
+ {
+       splashscreen_x *ss = (splashscreen_x *)data;
+       GList **list = (GList **)user_data;
+       splashscreen_x *ss_tmp;
+       GList *tmp;
+       if (ss->operation == NULL || ss->dpi)
+               return;
+       for (tmp = *list; tmp; tmp = tmp->next) {
+               ss_tmp = (splashscreen_x *)tmp->data;
+               if (ss_tmp->operation
+                       && strcmp(ss_tmp->operation, ss->operation) == 0
+                       && strcmp(ss_tmp->orientation, ss->orientation) == 0)
+                       return;
+       }
+       *list = g_list_prepend(*list, ss);
+ }
+ static gint __compare_splashscreen_with_orientation_dpi(gconstpointer a,
+               gconstpointer b)
+ {
+       splashscreen_x *ss = (splashscreen_x *)a;
+       const char *orientation = (const char *)b;
+       int dpi = -1;
+       int ret;
+       if (ss->operation || ss->dpi == NULL)
+               return -1;
+       ret = system_info_get_platform_int(
+                       "http://tizen.org/feature/screen.dpi", &dpi);
+       if (ret != SYSTEM_INFO_ERROR_NONE)
+               return -1;
+       if (strcasecmp(ss->orientation, orientation) == 0 &&
+                       __check_dpi(ss->dpi, dpi) == 0)
+               return 0;
+       return -1;
+ }
+ static gint __compare_splashscreen_with_orientation(gconstpointer a,
+               gconstpointer b)
+ {
+       splashscreen_x *ss = (splashscreen_x *)a;
+       const char *orientation = (const char *)b;
+       if (ss->operation || ss->dpi)
+               return -1;
+       if (strcasecmp(ss->orientation, orientation) == 0)
+               return 0;
+       return -1;
+ }
+ static splashscreen_x *__find_default_splashscreen(GList *splashscreens,
+               const char *orientation)
+ {
+       GList *tmp;
+       tmp = g_list_find_custom(splashscreens, orientation,
+                       (GCompareFunc)
+                       __compare_splashscreen_with_orientation_dpi);
+       if (tmp)
+               return (splashscreen_x *)tmp->data;
+       tmp = g_list_find_custom(splashscreens, orientation,
+                       (GCompareFunc)__compare_splashscreen_with_orientation);
+       if (tmp)
+               return (splashscreen_x *)tmp->data;
+       return NULL;
+ }
+ static GList *__find_splashscreens(GList *splashscreens)
+ {
+       GList *list = NULL;
+       splashscreen_x *ss;
+       if (splashscreens == NULL)
+               return NULL;
+       g_list_foreach(splashscreens,
+                       __find_appcontrol_splashscreen_with_dpi, &list);
+       g_list_foreach(splashscreens,
+                       __find_appcontrol_splashscreen, &list);
+       ss = __find_default_splashscreen(splashscreens, "portrait");
+       if (ss)
+               list = g_list_prepend(list, ss);
+       ss = __find_default_splashscreen(splashscreens, "landscape");
+       if (ss)
+               list = g_list_prepend(list, ss);
+       return list;
+ }
+ static int __insert_splashscreen_info(sqlite3 *db, application_x *app,
+               GList *ss_list)
+ {
+       static const char query[] =
+               "INSERT INTO package_app_splash_screen (app_id, src, type,"
+               "  orientation, indicatordisplay, operation, color_depth) "
+               "VALUES (?, ?, ?, ?, ?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *tmp;
+       splashscreen_x *ss;
+       if (app->splashscreens == NULL)
+               return 0;
+       if (ss_list == NULL)
+               return 0;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (tmp = ss_list; tmp; tmp = tmp->next) {
+               ss = (splashscreen_x *)tmp->data;
+               if (ss == NULL)
+                       continue;
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, app->appid);
+               __BIND_TEXT(db, stmt, idx++, ss->src);
+               __BIND_TEXT(db, stmt, idx++, ss->type);
+               __BIND_TEXT(db, stmt, idx++, ss->orientation);
+               __BIND_TEXT(db, stmt, idx++, ss->indicatordisplay);
+               __BIND_TEXT(db, stmt, idx++, ss->operation);
+               __BIND_TEXT(db, stmt, idx++, ss->color_depth);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static void __trimfunc(GList *trim_list)
+ {
+       char *trim_data;
+       char *prev = NULL;
+       GList *list = g_list_first(trim_list);
+       while (list) {
+               trim_data = (char *)list->data;
+               if (trim_data) {
+                       if (prev) {
+                               if (strcmp(trim_data, prev) == 0) {
+                                       trim_list = g_list_remove(trim_list,
+                                                       trim_data);
+                                       list = g_list_first(trim_list);
+                                       prev = NULL;
+                                       continue;
+                               } else
+                                       prev = trim_data;
+                       } else {
+                               prev = trim_data;
+                       }
+               }
+               list = g_list_next(list);
+       }
+ }
+ static int __insert_package_appdefined_privilege_info(sqlite3 *db,
+               manifest_x *mfx)
+ {
+       static const char query[] =
+               "INSERT INTO package_appdefined_privilege_info "
+               "(package, privilege, license, type) "
+               "VALUES (?, ?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *tmp;
+       appdefined_privilege_x *priv;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (tmp = mfx->appdefined_privileges; tmp; tmp = tmp->next) {
+               priv = (appdefined_privilege_x *)tmp->data;
+               if (priv == NULL)
+                       continue;
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, mfx->package);
+               __BIND_TEXT(db, stmt, idx++, priv->value);
+               __BIND_TEXT(db, stmt, idx++, priv->license);
+               __BIND_TEXT(db, stmt, idx++, priv->type);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_package_dependency_info(sqlite3 *db, manifest_x *mfx)
+ {
+       static const char query[] =
+               "INSERT INTO package_dependency_info"
+               "  (package, depends_on, type, required_version) "
+               "VALUES (?, ?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *tmp;
+       dependency_x *dep;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (tmp = mfx->dependencies; tmp; tmp = tmp->next) {
+               dep = (dependency_x *)tmp->data;
+               if (dep == NULL)
+                       continue;
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, mfx->package);
+               __BIND_TEXT(db, stmt, idx++, dep->depends_on);
+               __BIND_TEXT(db, stmt, idx++, dep->type);
+               __BIND_TEXT(db, stmt, idx++, dep->required_version);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_mainapp_localized_info(sqlite3 *db, application_x *app,
+               const char *locale, const char *label, const char *icon)
+ {
+       static const char query[] =
+               "INSERT OR REPLACE INTO package_localized_info ("
+               "  package, package_locale, package_label, package_icon,"
+               "  package_description, package_license, package_author) "
+               "VALUES (?, ?,"
+               "  COALESCE((SELECT package_label FROM package_localized_info"
+               "            WHERE package=? AND package_locale=?), ?),"
+               "  COALESCE((SELECT package_icon FROM package_localized_info"
+               "            WHERE package=? AND package_icon=?), ?),"
+               "  (SELECT package_description FROM package_localized_info"
+               "   WHERE package=? AND package_locale=?),"
+               "  (SELECT package_description FROM package_localized_info"
+               "   WHERE package=? AND package_locale=?),"
+               "  (SELECT package_description FROM package_localized_info"
+               "   WHERE package=? AND package_locale=?))";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx = 1;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       __BIND_TEXT(db, stmt, idx++, app->package);
+       __BIND_TEXT(db, stmt, idx++, locale);
+       __BIND_TEXT(db, stmt, idx++, app->package);
+       __BIND_TEXT(db, stmt, idx++, locale);
+       __BIND_TEXT(db, stmt, idx++, label);
+       __BIND_TEXT(db, stmt, idx++, app->package);
+       __BIND_TEXT(db, stmt, idx++, locale);
+       __BIND_TEXT(db, stmt, idx++, icon);
+       __BIND_TEXT(db, stmt, idx++, app->package);
+       __BIND_TEXT(db, stmt, idx++, locale);
+       __BIND_TEXT(db, stmt, idx++, app->package);
+       __BIND_TEXT(db, stmt, idx++, locale);
+       __BIND_TEXT(db, stmt, idx++, app->package);
+       __BIND_TEXT(db, stmt, idx++, locale);
+       ret = sqlite3_step(stmt);
+       if (ret != SQLITE_DONE) {
+               _LOGE("step failed: %s", sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               return -1;
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static gint __comparefunc(gconstpointer a, gconstpointer b, gpointer userdata)
+ {
+       if (a == NULL || b == NULL)
+               return 0;
+       if (strcmp((char *)a, (char *)b) == 0)
+               return 0;
+       if (strcmp((char *)a, (char *)b) < 0)
+               return -1;
+       if (strcmp((char *)a, (char *)b) > 0)
+               return 1;
+       return 0;
+ }
+ static GList *__create_locale_list(GList *lbls, GList *lcns, GList *icns,
+               GList *dcns, GList *aths)
+ {
+       GList *locale = NULL;
+       GList *tmp;
+       label_x *lbl;
+       license_x *lcn;
+       icon_x *icn;
+       description_x *dcn;
+       author_x *ath;
+       for (tmp = lbls; tmp; tmp = tmp->next) {
+               lbl = (label_x *)tmp->data;
+               if (lbl == NULL)
+                       continue;
+               if (lbl->lang)
+                       locale = g_list_insert_sorted_with_data(
+                                       locale, (gpointer)lbl->lang,
+                                       __comparefunc, NULL);
+       }
+       for (tmp = lcns; tmp; tmp = tmp->next) {
+               lcn = (license_x *)tmp->data;
+               if (lcn == NULL)
+                       continue;
+               if (lcn->lang)
+                       locale = g_list_insert_sorted_with_data(
+                                       locale, (gpointer)lcn->lang,
+                                       __comparefunc, NULL);
+       }
+       for (tmp = icns; tmp; tmp = tmp->next) {
+               icn = (icon_x *)tmp->data;
+               if (icn == NULL)
+                       continue;
+               if (icn->lang)
+                       locale = g_list_insert_sorted_with_data(
+                                       locale, (gpointer)icn->lang,
+                                       __comparefunc, NULL);
+       }
+       for (tmp = dcns; tmp; tmp = tmp->next) {
+               dcn = (description_x *)tmp->data;
+               if (dcn == NULL)
+                       continue;
+               if (dcn->lang)
+                       locale = g_list_insert_sorted_with_data(
+                                       locale, (gpointer)dcn->lang,
+                                       __comparefunc, NULL);
+       }
+       for (tmp = aths; tmp; tmp = tmp->next) {
+               ath = (author_x *)tmp->data;
+               if (ath == NULL)
+                       continue;
+               if (ath->lang)
+                       locale = g_list_insert_sorted_with_data(
+                                       locale, (gpointer)ath->lang,
+                                       __comparefunc, NULL);
+       }
+       __trimfunc(locale);
+       return locale;
+ }
+ static gint __check_icon_resolution(const char *orig_icon_path,
+               char **new_icon_path)
+ {
+       int ret;
+       char *dpi_path[2];
+       char *icon_filename;
+       char modified_iconpath[BUFSIZE];
+       char icon_path[BUFSIZE];
+       int i;
+       int dpi = -1;
+       if (orig_icon_path == NULL)
+               return -1;
+       ret = system_info_get_platform_int(
+                       "http://tizen.org/feature/screen.dpi", &dpi);
+       if (ret != SYSTEM_INFO_ERROR_NONE)
+               return -1;
+       if (dpi >= LDPI_MIN && dpi <= LDPI_MAX) {
+               dpi_path[0] = "LDPI";
+               dpi_path[1] = "ldpi";
+       } else if (dpi >= MDPI_MIN && dpi <= MDPI_MAX) {
+               dpi_path[0] = "MDPI";
+               dpi_path[1] = "mdpi";
+       } else if (dpi >= HDPI_MIN && dpi <= HDPI_MAX) {
+               dpi_path[0] = "HDPI";
+               dpi_path[1] = "hdpi";
+       } else if (dpi >= XHDPI_MIN && dpi <= XHDPI_MAX) {
+               dpi_path[0] = "XHDPI";
+               dpi_path[1] = "xhdpi";
+       } else if (dpi >= XXHDPI_MIN && dpi <= XXHDPI_MAX) {
+               dpi_path[0] = "XXHDPI";
+               dpi_path[1] = "xxhdpi";
+       } else {
+               _LOGE("Unidentified dpi[%d]", dpi);
+               return -1;
+       }
+       icon_filename = strrchr(orig_icon_path, '/');
+       if (icon_filename == NULL)
+               return -1;
+       snprintf(icon_path,
+                       strlen(orig_icon_path) - (strlen(icon_filename) - 1),
+                       "%s", orig_icon_path);
+       for (i = 0; i < 2; i++) {
+               ret = snprintf(modified_iconpath, BUFSIZE - 1, "%s/%s%s",
+                               icon_path, dpi_path[i], icon_filename);
+               if (ret < 0 || ret > BUFSIZE - 1) {
+                       _LOGE("snprintf fail");
+                       return -1;
+               }
+               if (access(modified_iconpath, F_OK) != -1) {
+                       /* if exists, return modified icon path */
+                       *new_icon_path = strdup(modified_iconpath);
+                       return 0;
+               }
+       }
+       return -1;
+ }
+ static gint __compare_icon(gconstpointer a, gconstpointer b)
+ {
+       icon_x *icon = (icon_x *)a;
+       char *icon_path;
+       if (icon->lang != NULL && strcasecmp(icon->lang, DEFAULT_LOCALE) != 0)
+               return -1;
+       if (icon->dpi != NULL)
+               return -1;
+       if (__check_icon_resolution(icon->text, &icon_path) == 0) {
+               free(icon->text);
+               icon->text = icon_path;
+       }
+       return 0;
+ }
+ static gint __compare_icon_with_lang(gconstpointer a, gconstpointer b)
+ {
+       icon_x *icon = (icon_x *)a;
+       char *lang = (char *)b;
+       char *icon_path;
+       if (icon->dpi != NULL)
+               return -1;
+       if (strcasecmp(icon->lang, lang) == 0) {
+               if (strcasecmp(icon->lang, DEFAULT_LOCALE) == 0) {
+                       /* icon for no locale. check existance of
+                        * folder-hierachied default icons
+                        */
+                       if (__check_icon_resolution(icon->text,
+                                               &icon_path) == 0) {
+                               free(icon->text);
+                               icon->text = icon_path;
+                       }
+               }
+               return 0;
+       }
+       return -1;
+ }
+ static gint __compare_icon_with_dpi(gconstpointer a, gconstpointer b)
+ {
+       icon_x *icon = (icon_x *)a;
+       int dpi = GPOINTER_TO_INT(b);
+       if (icon->lang != NULL && strcasecmp(icon->lang, DEFAULT_LOCALE) != 0)
+               return -1;
+       if (icon->dpi == NULL)
+               return -1;
+       if (__check_dpi(icon->dpi, dpi) == 0)
+               return 0;
+       return -1;
+ }
+ static gint __compare_icon_with_lang_dpi(gconstpointer a, gconstpointer b)
+ {
+       int ret;
+       icon_x *icon = (icon_x *)a;
+       char *lang = (char *)b;
+       int dpi = -1;
+       ret = system_info_get_platform_int(
+                       "http://tizen.org/feature/screen.dpi", &dpi);
+       if (ret != SYSTEM_INFO_ERROR_NONE)
+               return -1;
+       if (strcasecmp(icon->lang, lang) == 0 &&
+                       __check_dpi(icon->dpi, dpi) == 0)
+               return 0;
+       return -1;
+ }
+ static char *__find_icon(GList *icons, const char *lang)
+ {
+       GList *tmp;
+       icon_x *icon;
+       int dpi = 0;
+       int ret;
+       /* first, find icon whose locale and dpi with given lang and
+        * system's dpi has matched
+        */
+       tmp = g_list_find_custom(icons, lang,
+                       (GCompareFunc)__compare_icon_with_lang_dpi);
+       if (tmp != NULL) {
+               icon = (icon_x *)tmp->data;
+               return (char *)icon->text;
+       }
+       /* if first has failed, find icon whose locale has matched */
+       tmp = g_list_find_custom(icons, lang,
+                       (GCompareFunc)__compare_icon_with_lang);
+       if (tmp != NULL) {
+               icon = (icon_x *)tmp->data;
+               return (char *)icon->text;
+       }
+       /* if second has failed, find icon whose dpi has matched with
+        * system's dpi
+        */
+       ret = system_info_get_platform_int(
+                       "http://tizen.org/feature/screen.dpi", &dpi);
+       if (ret == SYSTEM_INFO_ERROR_NONE) {
+               tmp = g_list_find_custom(icons, GINT_TO_POINTER(dpi),
+                               (GCompareFunc)__compare_icon_with_dpi);
+               if (tmp != NULL) {
+                       icon = (icon_x *)tmp->data;
+                       return (char *)icon->text;
+               }
+       }
+       /* last, find default icon marked as "No Locale" */
+       tmp = g_list_find_custom(icons, NULL, (GCompareFunc)__compare_icon);
+       if (tmp != NULL) {
+               icon = (icon_x *)tmp->data;
+               return (char *)icon->text;
+       }
+       return NULL;
+ }
+ static void __extract_data(const char *locale, GList *lbls, GList *lcns,
+               GList *icns, GList *dcns, GList *aths, char **label,
+               char **license, char **icon, char **description, char **author)
+ {
+       GList *tmp;
+       label_x *lbl;
+       license_x *lcn;
+       description_x *dcn;
+       author_x *ath;
+       for (tmp = lbls; tmp; tmp = tmp->next) {
+               lbl = (label_x *)tmp->data;
+               if (lbl == NULL)
+                       continue;
+               if (lbl->lang) {
+                       if (strcmp(lbl->lang, locale) == 0) {
+                               *label = (char *)lbl->text;
+                               break;
+                       }
+               }
+       }
+       for (tmp = lcns; tmp; tmp = tmp->next) {
+               lcn = (license_x *)tmp->data;
+               if (lcn == NULL)
+                       continue;
+               if (lcn->lang) {
+                       if (strcmp(lcn->lang, locale) == 0) {
+                               *license = (char *)lcn->text;
+                               break;
+                       }
+               }
+       }
+       *icon = __find_icon(icns, locale);
+       for (tmp = dcns; tmp; tmp = tmp->next) {
+               dcn = (description_x *)tmp->data;
+               if (dcn == NULL)
+                       continue;
+               if (dcn->lang) {
+                       if (strcmp(dcn->lang, locale) == 0) {
+                               *description = (char *)dcn->text;
+                               break;
+                       }
+               }
+       }
+       for (tmp = aths; tmp; tmp = tmp->next) {
+               ath = (author_x *)tmp->data;
+               if (ath == NULL)
+                       continue;
+               if (ath->lang) {
+                       if (strcmp(ath->lang, locale) == 0) {
+                               *author = (char *)ath->text;
+                               break;
+                       }
+               }
+       }
+ }
+ static int __insert_app_localized_info(sqlite3 *db, application_x *app)
+ {
+       static const char query[] =
+               "INSERT INTO package_app_localized_info (app_id, app_locale,"
+               "  app_label, app_icon) "
+               "VALUES (?, ?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *tmp;
+       GList *locales;
+       const char *locale;
+       char *label;
+       char *icon;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       locales = __create_locale_list(app->label, NULL, app->icon, NULL, NULL);
+       for (tmp = locales; tmp; tmp = tmp->next) {
+               locale = (const char *)tmp->data;
+               label = NULL;
+               icon = NULL;
+               __extract_data(locale, app->label, NULL, app->icon, NULL, NULL,
+                               &label, NULL, &icon, NULL, NULL);
+               if (!label && !icon)
+                       continue;
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, app->appid);
+               __BIND_TEXT(db, stmt, idx++, locale);
+               __BIND_TEXT(db, stmt, idx++, label);
+               __BIND_TEXT(db, stmt, idx++, icon);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       g_list_free(locales);
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+               if (strcasecmp(app->mainapp, "true") == 0) {
+                       if (__insert_mainapp_localized_info(db, app, locale,
+                                               label, icon))
+                               _LOGE("insert mainapp localized info failed");
+               }
+       }
+       g_list_free(locales);
+       sqlite3_finalize(stmt);
+       return 0;
+ }
++static int __insert_app_res_control(sqlite3 *db, application_x *app)
++{
++      static const char query[] =
++              "INSERT INTO package_app_res_control (app_id, res_type,"
++              "  min_res_version, max_res_version, auto_close) "
++              "VALUES (?, ?, ?, ?, ?)";
++      int ret;
++      sqlite3_stmt *stmt;
++      int idx;
++      GList *tmp;
++      res_control_x *rc;
++
++      if (app->res_control == NULL)
++              return 0;
++
++      ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
++      if (ret != SQLITE_OK) {
++              _LOGE("prepare failed: %s", sqlite3_errmsg(db));
++              return -1;
++      }
++
++      for (tmp = app->res_control; tmp; tmp = tmp->next) {
++              rc = (res_control_x *)tmp->data;
++              if (rc == NULL)
++                      continue;
++              idx = 1;
++              __BIND_TEXT(db, stmt, idx++, app->appid);
++              __BIND_TEXT(db, stmt, idx++, rc->res_type);
++              __BIND_TEXT(db, stmt, idx++, rc->min_res_version);
++              __BIND_TEXT(db, stmt, idx++, rc->max_res_version);
++              __BIND_TEXT(db, stmt, idx++, rc->auto_close);
++
++              ret = sqlite3_step(stmt);
++              if (ret != SQLITE_DONE) {
++                      _LOGE("step failed: %s", sqlite3_errmsg(db));
++                      sqlite3_finalize(stmt);
++                      return -1;
++              }
++
++              sqlite3_reset(stmt);
++      }
++
++      sqlite3_finalize(stmt);
++
++      return 0;
++}
++
+ static int __insert_package_privilege_info(sqlite3 *db, manifest_x *mfx)
+ {
+       static const char query[] =
+               "INSERT INTO package_privilege_info (package, privilege, type) "
+               "VALUES (?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *tmp;
+       privilege_x *priv;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (tmp = mfx->privileges; tmp; tmp = tmp->next) {
+               priv = (privilege_x *)tmp->data;
+               if (priv == NULL)
+                       continue;
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, mfx->package);
+               __BIND_TEXT(db, stmt, idx++, priv->value);
+               __BIND_TEXT(db, stmt, idx++, priv->type);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_app_data_control_privilege_info(sqlite3 *db,
+               datacontrol_x *datacontrol)
+ {
+       static const char query[] =
+               "INSERT INTO package_app_data_control_privilege (providerid,"
+               "  privilege, type) VALUES (?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *privileges;
+       char *priv;
+       if (datacontrol == NULL)
+               return 0;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (privileges = datacontrol->privileges; privileges;
+                       privileges = privileges->next) {
+               priv = (char *)privileges->data;
+               if (priv == NULL)
+                       continue;
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, datacontrol->providerid);
+               __BIND_TEXT(db, stmt, idx++, priv);
+               __BIND_TEXT(db, stmt, idx++, datacontrol->type);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_datacontrol_info(sqlite3 *db, application_x *app)
+ {
+       static const char query[] =
+               "INSERT INTO package_app_data_control (app_id, providerid,"
+               "  access, type, trusted) VALUES (?, ?, ?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *tmp;
+       datacontrol_x *dc;
+       if (app->datacontrol == NULL)
+               return 0;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (tmp = app->datacontrol; tmp; tmp = tmp->next) {
+               dc = (datacontrol_x *)tmp->data;
+               if (dc == NULL)
+                       continue;
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, app->appid);
+               __BIND_TEXT(db, stmt, idx++, dc->providerid);
+               __BIND_TEXT(db, stmt, idx++, dc->access);
+               __BIND_TEXT(db, stmt, idx++, dc->type);
+               __BIND_TEXT(db, stmt, idx++, dc->trusted);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               if (dc->privileges &&
+                               __insert_app_data_control_privilege_info(
+                                               db, dc)) {
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_category_info(sqlite3 *db, application_x *app)
+ {
+       static const char query[] =
+               "INSERT INTO package_app_app_category (app_id, category) "
+               "VALUES (?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *tmp;
+       const char *category;
+       if (app->category == NULL)
+               return 0;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (tmp = app->category; tmp; tmp = tmp->next) {
+               category = (const char *)tmp->data;
+               if (category == NULL)
+                       continue;
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, app->appid);
+               __BIND_TEXT(db, stmt, idx++, category);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_metadata_info(sqlite3 *db, application_x *app)
+ {
+       static const char query[] =
+               "INSERT INTO package_app_app_metadata (app_id,"
+               "  md_key, md_value) VALUES (?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *tmp;
+       metadata_x *md;
+       if (app->metadata == NULL)
+               return 0;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (tmp = app->metadata; tmp; tmp = tmp->next) {
+               md = (metadata_x *)tmp->data;
+               if (md == NULL)
+                       continue;
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, app->appid);
+               __BIND_TEXT(db, stmt, idx++, md->key);
+               __BIND_TEXT(db, stmt, idx++, md->value);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_appcontrol_privilege_info(sqlite3 *db, const char *appid,
+               appcontrol_x *ac)
+ {
+       static const char query[] =
+               "INSERT INTO package_app_app_control_privilege (app_id,"
+               "  app_control, privilege) VALUES (?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       char app_control[BUFSIZE];
+       GList *tmp;
+       char *privilege;
+       if (ac == NULL)
+               return 0;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (tmp = ac->privileges; tmp; tmp = tmp->next) {
+               privilege = (char *)tmp->data;
+               if (privilege == NULL || !strlen(privilege))
+                       continue;
+               idx = 1;
+               snprintf(app_control, sizeof(app_control), "%s|%s|%s",
+                               ac->operation ? (strlen(ac->operation) > 0 ?
+                                       ac->operation : "NULL") : "NULL",
+                               ac->uri ? (strlen(ac->uri) > 0 ?
+                                       ac->uri : "NULL") : "NULL",
+                               ac->mime ? (strlen(ac->mime) > 0 ?
+                                       ac->mime : "NULL") : "NULL");
+               __BIND_TEXT(db, stmt, idx++, appid);
+               __BIND_TEXT(db, stmt, idx++, app_control);
+               __BIND_TEXT(db, stmt, idx++, privilege);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_appcontrol_info(sqlite3 *db, application_x *app)
+ {
+       static const char query[] =
+               "INSERT INTO package_app_app_control (app_id, app_control,"
+               "  visibility, app_control_id) "
+               "VALUES (?, ?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       char app_control[BUFSIZE];
+       GList *tmp;
+       appcontrol_x *ac;
+       if (app->appcontrol == NULL)
+               return 0;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (tmp = app->appcontrol; tmp; tmp = tmp->next) {
+               ac = (appcontrol_x *)tmp->data;
+               if (ac == NULL)
+                       continue;
+               idx = 1;
+               snprintf(app_control, sizeof(app_control), "%s|%s|%s",
+                               ac->operation ? (strlen(ac->operation) > 0 ?
+                                       ac->operation : "NULL") : "NULL",
+                               ac->uri ? (strlen(ac->uri) > 0 ?
+                                       ac->uri : "NULL") : "NULL",
+                               ac->mime ? (strlen(ac->mime) > 0 ?
+                                       ac->mime : "NULL") : "NULL");
+               __BIND_TEXT(db, stmt, idx++, app->appid);
+               __BIND_TEXT(db, stmt, idx++, app_control);
+               __BIND_TEXT(db, stmt, idx++, ac->visibility);
+               __BIND_TEXT(db, stmt, idx++, ac->id);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               if (__insert_appcontrol_privilege_info(db, app->appid, ac)) {
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static const char *__get_bool(char *value, bool is_true)
+ {
+       if (value != NULL) {
+               if (!strcmp(value, ""))
+                       return (is_true) ? "true" : "false";
+               return value;
+       }
+       return (is_true) ? "true" : "false";
+ }
+ #define EFFECTIVE_APPID_KEY "http://tizen.org/metadata/effective-appid"
+ static const char *__find_effective_appid(GList *metadata_list)
+ {
+       GList *tmp;
+       metadata_x *md;
+       for (tmp = metadata_list; tmp; tmp = tmp->next) {
+               md = (metadata_x *)tmp->data;
+               if (md == NULL || md->key == NULL)
+                       continue;
+               if (strcmp(md->key, EFFECTIVE_APPID_KEY) == 0) {
+                       if (md->value)
+                               return md->value;
+               }
+       }
+       return NULL;
+ }
+ static int __convert_background_category(GList *category_list)
+ {
+       int ret = 0;
+       GList *tmp;
+       char *category_data;
+       if (category_list == NULL)
+               return 0;
+       for (tmp = category_list; tmp; tmp = tmp->next) {
+               category_data = (char *)tmp->data;
+               if (category_data == NULL)
+                       continue;
+               if (!strcmp(category_data, APP_BG_CATEGORY_MEDIA_STR))
+                       ret |= APP_BG_CATEGORY_MEDIA_VAL;
+               else if (!strcmp(category_data, APP_BG_CATEGORY_DOWNLOAD_STR))
+                       ret |= APP_BG_CATEGORY_DOWNLOAD_VAL;
+               else if (!strcmp(category_data, APP_BG_CATEGORY_BGNETWORK_STR))
+                       ret |= APP_BG_CATEGORY_BGNETWORK_VAL;
+               else if (!strcmp(category_data, APP_BG_CATEGORY_LOCATION_STR))
+                       ret |= APP_BG_CATEGORY_LOCATION_VAL;
+               else if (!strcmp(category_data, APP_BG_CATEGORY_SENSOR_STR))
+                       ret |= APP_BG_CATEGORY_SENSOR_VAL;
+               else if (!strcmp(category_data, APP_BG_CATEGORY_IOTCOMM_STR))
+                       ret |= APP_BG_CATEGORY_IOTCOMM_VAL;
+               else if (!strcmp(category_data, APP_BG_CATEGORY_SYSTEM))
+                       ret |= APP_BG_CATEGORY_SYSTEM_VAL;
+               else
+                       _LOGE("Unidentified category [%s]", category_data);
+       }
+       return ret;
+ }
++static int __insert_package_res_info_allowed_package(sqlite3 *db,
++              const char *pkgid, GList *rap_list)
++{
++      static const char query[] =
++              "INSERT INTO package_res_allowed_package (package,"
++              "  allowed_package, required_privilege) VALUES (?, ?, ?)";
++      int ret;
++      int idx;
++      sqlite3_stmt *stmt;
++      GList *tmp;
++      GList *priv_list;
++      res_allowed_package_x *rap;
++
++      if (rap_list == NULL)
++              return 0;
++
++      ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
++      if (ret != SQLITE_OK) {
++              _LOGE("prepare failed: %s", sqlite3_errmsg(db));
++              return -1;
++      }
++
++      for (tmp = rap_list; tmp; tmp = tmp->next) {
++              rap = (res_allowed_package_x *)tmp->data;
++              if (rap == NULL)
++                      continue;
++
++              if (!rap->required_privileges) {
++                      idx = 1;
++                      __BIND_TEXT(db, stmt, idx++, pkgid);
++                      __BIND_TEXT(db, stmt, idx++, rap->allowed_package);
++                      __BIND_TEXT(db, stmt, idx++, NULL);
++
++                      ret = sqlite3_step(stmt);
++                      if (ret != SQLITE_DONE) {
++                              _LOGE("step failed: %s", sqlite3_errmsg(db));
++                              sqlite3_finalize(stmt);
++                              return -1;
++                      }
++
++                      sqlite3_reset(stmt);
++                      continue;
++              }
++
++              for (priv_list = rap->required_privileges; priv_list;
++                              priv_list = priv_list->next) {
++                      idx = 1;
++                      __BIND_TEXT(db, stmt, idx++, pkgid);
++                      __BIND_TEXT(db, stmt, idx++, rap->allowed_package);
++                      __BIND_TEXT(db, stmt, idx++, (char *)priv_list->data);
++
++                      ret = sqlite3_step(stmt);
++                      if (ret != SQLITE_DONE) {
++                              _LOGE("step failed: %s", sqlite3_errmsg(db));
++                              sqlite3_finalize(stmt);
++                              return -1;
++                      }
++
++                      sqlite3_reset(stmt);
++              }
++      }
++
++      sqlite3_finalize(stmt);
++
++      return 0;
++}
++
++static int __insert_package_res_info(sqlite3 *db, manifest_x *mfx)
++{
++      static const char query[] =
++              "INSERT INTO package_res_info (package, res_type,"
++              "  res_version) VALUES (?, ?, ?)";
++      int ret;
++      sqlite3_stmt *stmt;
++      int idx;
++
++      if (mfx->res_type == NULL || mfx->res_version == NULL)
++              return 0;
++
++      ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
++      if (ret != SQLITE_OK) {
++              _LOGE("prepare failed: %s", sqlite3_errmsg(db));
++              return -1;
++      }
++
++      idx = 1;
++      __BIND_TEXT(db, stmt, idx++, mfx->package);
++      __BIND_TEXT(db, stmt, idx++, mfx->res_type);
++      __BIND_TEXT(db, stmt, idx++, mfx->res_version);
++
++      ret = sqlite3_step(stmt);
++      if (ret != SQLITE_DONE) {
++              _LOGE("step failed: %s", sqlite3_errmsg(db));
++              sqlite3_finalize(stmt);
++              return -1;
++      }
++
++      if (__insert_package_res_info_allowed_package(db, mfx->package,
++                      mfx->res_allowed_packages) < 0) {
++              sqlite3_finalize(stmt);
++              return -1;
++      }
++
++      sqlite3_finalize(stmt);
++
++      return 0;
++}
++
+ static int __insert_application_info(sqlite3 *db, manifest_x *mfx)
+ {
+       static const char query[] =
+               "INSERT INTO package_app_info (app_id, app_component,"
+               "  app_exec, app_nodisplay, app_type, app_onboot, app_multiple,"
+               "  app_autorestart, app_taskmanage, app_hwacceleration,"
+               "  app_screenreader, app_mainapp, app_recentimage,"
+               "  app_launchcondition, app_indicatordisplay, app_portraitimg,"
+               "  app_landscapeimg, app_guestmodevisibility,"
+               "  app_permissiontype, app_preload, app_submode,"
+               "  app_submode_mainid, app_installed_storage, app_process_pool,"
+               "  app_launch_mode, app_ui_gadget, app_support_mode,"
+               "  app_support_disable, component_type, package, app_tep_name,"
+               "  app_zip_mount_file, app_background_category,"
+               "  app_package_type, app_root_path, app_api_version,"
+               "  app_effective_appid, app_splash_screen_display,"
+               "  app_package_system, app_removable,"
+               "  app_package_installed_time, app_support_ambient,"
+               "  app_external_path, app_setup_appid) "
+               "VALUES (?, ?, "
+               "  ?, LOWER(?), ?, LOWER(?), LOWER(?),"
+               "  LOWER(?), LOWER(?), ?,"
+               "  ?, LOWER(?), ?,"
+               "  ?, LOWER(?), ?,"
+               "  ?, LOWER(?),"
+               "  ?, LOWER(?), LOWER(?),"
+               "  ?, ?, LOWER(?),"
+               "  COALESCE(?, 'single'), LOWER(?), ?,"
+               "  LOWER(?), ?, ?, ?,"
+               "  ?, ?,"
+               "  ?, ?, ?,"
+               "  ?, LOWER(?),"
+               "  LOWER(?), LOWER(?),"
+               "  ?, LOWER(?),"
+               "  ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *tmp;
+       application_x *app;
+       int bg_category;
+       const char *effective_appid;
+       GList *ss_list;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       for (tmp = mfx->application; tmp; tmp = tmp->next) {
+               app = (application_x *)tmp->data;
+               if (app == NULL)
+                       continue;
+               bg_category = __convert_background_category(
+                               app->background_category);
+               effective_appid = __find_effective_appid(app->metadata);
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, app->appid);
++              __BIND_TEXT(db, stmt, idx++, app->component_type);
+               __BIND_TEXT(db, stmt, idx++, app->exec);
+               __BIND_TEXT(db, stmt, idx++, __get_bool(app->nodisplay, false));
+               __BIND_TEXT(db, stmt, idx++, app->type);
+               __BIND_TEXT(db, stmt, idx++, __get_bool(app->onboot, false));
+               __BIND_TEXT(db, stmt, idx++, __get_bool(app->multiple, false));
+               __BIND_TEXT(db, stmt, idx++,
+                               __get_bool(app->autorestart, false));
+               __BIND_TEXT(db, stmt, idx++,
+                               __get_bool(app->taskmanage, false));
+               __BIND_TEXT(db, stmt, idx++, app->hwacceleration);
+               __BIND_TEXT(db, stmt, idx++, app->screenreader);
+               __BIND_TEXT(db, stmt, idx++, __get_bool(app->mainapp, false));
+               __BIND_TEXT(db, stmt, idx++, app->recentimage);
+               __BIND_TEXT(db, stmt, idx++, app->launchcondition);
+               __BIND_TEXT(db, stmt, idx++,
+                               __get_bool(app->indicatordisplay, true));
+               __BIND_TEXT(db, stmt, idx++, app->portraitimg);
+               __BIND_TEXT(db, stmt, idx++, app->landscapeimg);
+               __BIND_TEXT(db, stmt, idx++,
+                               __get_bool(app->guestmode_visibility, true));
+               __BIND_TEXT(db, stmt, idx++, app->permission_type);
+               __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->preload, false));
+               __BIND_TEXT(db, stmt, idx++, __get_bool(app->submode, false));
+               __BIND_TEXT(db, stmt, idx++, app->submode_mainid);
+               __BIND_TEXT(db, stmt, idx++, mfx->installed_storage);
+               __BIND_TEXT(db, stmt, idx++,
+                               __get_bool(app->process_pool, false));
+               __BIND_TEXT(db, stmt, idx++, app->launch_mode);
+               __BIND_TEXT(db, stmt, idx++, __get_bool(app->ui_gadget, false));
+               __BIND_TEXT(db, stmt, idx++,
+                               app->support_mode ? app->support_mode : "0");
+               __BIND_TEXT(db, stmt, idx++,
+                               __get_bool(mfx->support_disable, false));
+               __BIND_TEXT(db, stmt, idx++, app->component_type);
+               __BIND_TEXT(db, stmt, idx++, mfx->package);
+               __BIND_TEXT(db, stmt, idx++, mfx->tep_name);
+               __BIND_TEXT(db, stmt, idx++, mfx->zip_mount_file);
+               __BIND_INT(db, stmt, idx++, bg_category);
+               __BIND_TEXT(db, stmt, idx++, mfx->type ? mfx->type : "tpk");
+               __BIND_TEXT(db, stmt, idx++, mfx->root_path);
+               __BIND_TEXT(db, stmt, idx++, app->api_version);
+               __BIND_TEXT(db, stmt, idx++, effective_appid);
+               __BIND_TEXT(db, stmt, idx++,
+                               __get_bool(app->splash_screen_display, true));
+               __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->system, false));
+               __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->removable, false));
+               __BIND_TEXT(db, stmt, idx++, mfx->installed_time);
+               __BIND_TEXT(db, stmt, idx++,
+                               __get_bool(app->support_ambient, false));
+               __BIND_TEXT(db, stmt, idx++, mfx->external_path);
+               __BIND_TEXT(db, stmt, idx++, app->setup_appid);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+               if (__insert_appcontrol_info(db, app)) {
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               if (__insert_category_info(db, app)) {
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               if (__insert_metadata_info(db, app)) {
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               if (__insert_datacontrol_info(db, app)) {
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               ss_list = __find_splashscreens(app->splashscreens);
+               if (__insert_splashscreen_info(db, app, ss_list)) {
+                       g_list_free(ss_list);
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               g_list_free(ss_list);
+               if (__insert_app_localized_info(db, app)) {
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
++              if (__insert_app_res_control(db, app)) {
++                      sqlite3_finalize(stmt);
++                      return -1;
++              }
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_package_update_info(sqlite3 *db, manifest_x *mfx)
+ {
+       static const char query[] =
+               "INSERT INTO package_update_info (package, update_version) "
+               "VALUES (?, ?)";
+       int ret;
+       int idx;
+       sqlite3_stmt *stmt;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       idx = 1;
+       __BIND_TEXT(db, stmt, idx++, mfx->package);
+       __BIND_TEXT(db, stmt, idx, mfx->version);
+       ret = sqlite3_step(stmt);
+       if (ret != SQLITE_DONE) {
+               _LOGE("step failed: %s", sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               return -1;
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_package_localized_info(sqlite3 *db, manifest_x *mfx)
+ {
+       static const char query[] =
+               "INSERT INTO package_localized_info (package, package_locale,"
+               "  package_label, package_icon, package_description,"
+               "  package_license, package_author) "
+               "VALUES (?, ?, ?, ?, ?, ?, ?)";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx;
+       GList *tmp;
+       GList *locales;
+       const char *locale;
+       char *label;
+       char *icon;
+       char *description;
+       char *license;
+       char *author;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       locales = __create_locale_list(mfx->label, mfx->license, mfx->icon,
+                       mfx->description, mfx->author);
+       for (tmp = locales; tmp; tmp = tmp->next) {
+               locale = (const char *)tmp->data;
+               label = NULL;
+               icon = NULL;
+               description = NULL;
+               license = NULL;
+               author = NULL;
+               __extract_data(locale, mfx->label, mfx->license, mfx->icon,
+                               mfx->description, mfx->author,
+                               &label, &license, &icon, &description, &author);
+               if (!label && !license && !icon && !description && !author)
+                       continue;
+               idx = 1;
+               __BIND_TEXT(db, stmt, idx++, mfx->package);
+               __BIND_TEXT(db, stmt, idx++, locale);
+               __BIND_TEXT(db, stmt, idx++, label);
+               __BIND_TEXT(db, stmt, idx++, icon);
+               __BIND_TEXT(db, stmt, idx++, description);
+               __BIND_TEXT(db, stmt, idx++, license);
+               __BIND_TEXT(db, stmt, idx++, author);
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_DONE) {
+                       _LOGE("step failed: %s", sqlite3_errmsg(db));
+                       g_list_free(locales);
+                       sqlite3_finalize(stmt);
+                       return -1;
+               }
+               sqlite3_reset(stmt);
+       }
+       g_list_free(locales);
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ static int __insert_package_info(sqlite3 *db, manifest_x *mfx)
+ {
+       static const char query[] =
+               "INSERT INTO package_info (package, package_type,"
+               "  package_version, package_api_version, package_tep_name,"
+               "  package_zip_mount_file, install_location, package_size,"
+               "  package_removable, package_preload, package_readonly,"
+               "  package_update, package_appsetting, package_nodisplay,"
+               "  package_system, author_name, author_email, author_href,"
+               "  installed_time, installed_storage, storeclient_id,"
+               "  mainapp_id, package_url, root_path, external_path,"
+               "  csc_path, package_support_mode, package_support_disable) "
+               "VALUES (?, ?,"
+               "  ?, ?, ?,"
+               "  ?, ?, ?,"
+               "  LOWER(?), LOWER(?), LOWER(?),"
+               "  LOWER(?), LOWER(?), LOWER(?),"
+               "  LOWER(?), ?, ?, ?,"
+               "  ?, ?, ?,"
+               "  ?, ?, ?, ?,"
+               "  ?, ?, LOWER(?))";
+       int ret;
+       sqlite3_stmt *stmt;
+       int idx = 1;
+       const char *author_name = NULL;
+       const char *author_email = NULL;
+       const char *author_href = NULL;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       if (mfx->author && mfx->author->data) {
+               author_name = ((author_x *)mfx->author->data)->text;
+               author_email = ((author_x *)mfx->author->data)->email;
+               author_href = ((author_x *)mfx->author->data)->href;
+       }
+       __BIND_TEXT(db, stmt, idx++, mfx->package);
+       __BIND_TEXT(db, stmt, idx++, mfx->type);
+       __BIND_TEXT(db, stmt, idx++, mfx->version);
+       __BIND_TEXT(db, stmt, idx++, mfx->api_version);
+       __BIND_TEXT(db, stmt, idx++, mfx->tep_name);
+       __BIND_TEXT(db, stmt, idx++, mfx->zip_mount_file);
+       __BIND_TEXT(db, stmt, idx++, mfx->installlocation);
+       __BIND_TEXT(db, stmt, idx++, mfx->package_size);
+       __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->removable, true));
+       __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->preload, false));
+       __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->readonly, false));
+       __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->update, false));
+       __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->appsetting, false));
+       __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->nodisplay_setting, false));
+       __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->system, false));
+       __BIND_TEXT(db, stmt, idx++, author_name);
+       __BIND_TEXT(db, stmt, idx++, author_email);
+       __BIND_TEXT(db, stmt, idx++, author_href);
+       __BIND_TEXT(db, stmt, idx++, mfx->installed_time);
+       __BIND_TEXT(db, stmt, idx++, mfx->installed_storage);
+       __BIND_TEXT(db, stmt, idx++, mfx->storeclient_id);
+       __BIND_TEXT(db, stmt, idx++, mfx->mainapp_id);
+       __BIND_TEXT(db, stmt, idx++, mfx->package_url);
+       __BIND_TEXT(db, stmt, idx++, mfx->root_path);
+       __BIND_TEXT(db, stmt, idx++, mfx->external_path);
+       __BIND_TEXT(db, stmt, idx++, mfx->csc_path);
+       __BIND_TEXT(db, stmt, idx++,
+                       mfx->support_mode ? mfx->support_mode : "0");
+       __BIND_TEXT(db, stmt, idx++, __get_bool(mfx->support_disable, false));
+       ret = sqlite3_step(stmt);
+       if (ret != SQLITE_DONE) {
+               _LOGE("step failed: %s", sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               return -1;
+       }
+       sqlite3_finalize(stmt);
+       if (__insert_package_update_info(db, mfx))
+               return -1;
+       if (__insert_package_localized_info(db, mfx))
+               return -1;
+       if (__insert_application_info(db, mfx))
+               return -1;
+       if (__insert_package_privilege_info(db, mfx))
+               return -1;
+       if (__insert_package_appdefined_privilege_info(db, mfx))
+               return -1;
+       if (__insert_package_dependency_info(db, mfx))
+               return -1;
++      if (__insert_package_res_info(db, mfx))
++              return -1;
+       return 0;
+ }
+ static int __delete_package_info(sqlite3 *db, const char *pkgid)
+ {
+       static const char query[] =
+               "DELETE FROM package_info WHERE package=?";
+       int ret;
+       sqlite3_stmt *stmt;
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (ret != SQLITE_OK) {
+               _LOGE("prepare failed: %s", sqlite3_errmsg(db));
+               return -1;
+       }
+       __BIND_TEXT(db, stmt, 1, pkgid);
+       ret = sqlite3_step(stmt);
+       if (ret != SQLITE_DONE) {
+               _LOGE("step failed: %s", sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               return -1;
+       }
+       sqlite3_finalize(stmt);
+       return 0;
+ }
+ API int pkgmgr_parser_delete_pkg_info(sqlite3 *db,
+               const char *package, uid_t uid)
+ {
+       if (db == NULL || package == NULL) {
+               _LOGE("invalid parameter");
+               return PM_PARSER_R_EINVAL;
+       }
+       __BEGIN_TRANSACTION(db);
+       __DO_TRANSACTION(db, __delete_package_info(db, package));
+       __END_TRANSACTION(db);
+       return PM_PARSER_R_OK;
+ }
+ API int pkgmgr_parser_update_pkg_info(sqlite3 *db, manifest_x *mfx, uid_t uid)
+ {
+       if (db == NULL || mfx == NULL) {
+               _LOGE("invalid parameter");
+               return PM_PARSER_R_EINVAL;
+       }
+       __BEGIN_TRANSACTION(db);
+       __DO_TRANSACTION(db, __delete_package_info(db, mfx->package));
+       __DO_TRANSACTION(db, __insert_package_info(db, mfx));
+       __END_TRANSACTION(db);
+       return PM_PARSER_R_OK;
+ }
+ API int pkgmgr_parser_insert_pkg_info(sqlite3 *db, manifest_x *mfx, uid_t uid)
+ {
+       if (db == NULL || mfx == NULL) {
+               _LOGE("invalid parameter");
+               return PM_PARSER_R_EINVAL;
+       }
+       __BEGIN_TRANSACTION(db);
+       __DO_TRANSACTION(db, __insert_package_info(db, mfx));
+       __END_TRANSACTION(db);
+       return PM_PARSER_R_OK;
+ }
index 0000000000000000000000000000000000000000,4c8375b0e0232060045f30e9c5f6a8ee03b6ab54..39da2e75cde57ef83c3e5834cd9dee87fedea9a6
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,64 +1,64 @@@
 -        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
+ // Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ // Use of this source code is governed by an apache-2.0 license that can be
+ // found in the LICENSE file.
+ #include "command_request_handler.hh"
+ #include <string>
+ #include "db_handle_provider.hh"
+ #include "parcelable_factory.hh"
+ #include "pkginfo_parcelable.hh"
+ #include "pkgmgrinfo_debug.h"
+ #include "pkgmgrinfo_type.h"
+ namespace pcp = pkgmgr_common::parcel;
+ namespace pkgmgr_server {
+ namespace request_handler {
+ bool CommandRequestHandler::HandleRequest(unsigned char* data, int size,
+                                              const std::string& locale) {
+   auto abstract_parcel =
+       pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
+   if (abstract_parcel == nullptr ||
+       abstract_parcel->GetType() != pcp::ParcelableType::Command) {
+     _LOGE("Invalid parcel or type");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
++        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   auto* parcel = dynamic_cast<pcp::CommandParcelable*>(abstract_parcel.get());
+   if (parcel == nullptr) {
+     _LOGE("Parcel is empty");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -        PMINFO_R_OK, std::vector<std::vector<std::string>>{});
++        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   if (parcel->GetCmd() == CommandType::RemoveCache) {
+     database::DBHandleProvider::GetInst(
+         parcel->GetUid()).UnsetMemoryMode(GetPID());
+     result_ = std::make_shared<pcp::ResultParcelable>(
++        PMINFO_R_OK, std::vector<pcp::StrArgs>{});
+     return true;
+   }
+   return true;
+ }
+ std::vector<uint8_t> CommandRequestHandler::ExtractResult() {
+   tizen_base::Parcel parcel;
+   parcel.WriteParcelable(*result_);
+   std::vector<uint8_t> raw = parcel.GetRaw();
+   result_.reset();
+   return raw;
+ }
+ }  // namespace request_handler
+ }  // namespace pkgmgr_server
index 0000000000000000000000000000000000000000,8eab01c9a5c463989448d78301bcd1fdd2080835..7d86c62863520fd9a5a13c6d4b59332ed8d64f57
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,70 +1,70 @@@
 -        PM_PARSER_R_ERROR, std::vector<std::vector<std::string>>{});
+ // Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ // Use of this source code is governed by an apache-2.0 license that can be
+ // found in the LICENSE file.
+ #include "create_db_request_handler.hh"
+ #include <string>
+ #include "parcelable_factory.hh"
+ #include "create_db_parcelable.hh"
+ #include "create_db_handler.hh"
+ #include "db_type.hh"
+ #include "pkgmgr_parser.h"
+ #include "pkgmgrinfo_debug.h"
+ namespace pcp = pkgmgr_common::parcel;
+ namespace psd = pkgmgr_server::database;
+ namespace pkgmgr_server {
+ namespace request_handler {
+ bool CreateDBRequestHandler::HandleRequest(unsigned char* data, int size,
+                                            const std::string& locale) {
+   auto abstract_parcel =
+       pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
+   if (abstract_parcel == nullptr ||
+       abstract_parcel->GetType() != pcp::ParcelableType::CreateDB) {
+     _LOGE("Invalid parcel or type");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -        PM_PARSER_R_ERROR, std::vector<std::vector<std::string>>{});
++        PM_PARSER_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   auto* parcel = dynamic_cast<pcp::CreateDBParcelable*>(abstract_parcel.get());
+   if (parcel == nullptr) {
+     _LOGE("Parcel is empty");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -      ret, std::vector<std::vector<std::string>>{});
++        PM_PARSER_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   psd::CreateDBHandler db(parcel->GetUid(), GetPID());
+   db.SetOpType(pkgmgr_common::DBOperationType::OPERATION_TYPE_CREATE);
+   int ret = PM_PARSER_R_ERROR;
+   ret = db.Execute();
+   result_ = std::make_shared<pcp::ResultParcelable>(
++      ret, std::vector<pcp::StrArgs>{});
+   return true;
+ }
+ std::vector<uint8_t> CreateDBRequestHandler::ExtractResult() {
+   tizen_base::Parcel parcel;
+   parcel.WriteParcelable(*result_);
+   std::vector<uint8_t> raw = parcel.GetRaw();
+   result_.reset();
+   return raw;
+ }
+ }  // namespace request_handler
+ }  // namespace pkgmgr_server
index 0000000000000000000000000000000000000000,72e1109bd097e35a6a8e0075137214501a447c54..f3da77a222df1b8444649282043e9e7364272dbd
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,66 +1,66 @@@
 -        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
+ // Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ // Use of this source code is governed by an apache-2.0 license that can be
+ // found in the LICENSE file.
+ #include "query_request_handler.hh"
+ #include <string>
+ #include "parcelable_factory.hh"
+ #include "query_handler.hh"
+ #include "query_parcelable.hh"
+ #include "pkgmgrinfo_debug.h"
+ namespace pcp = pkgmgr_common::parcel;
+ namespace psd = pkgmgr_server::database;
+ namespace pkgmgr_server {
+ namespace request_handler {
+ bool QueryRequestHandler::HandleRequest(unsigned char* data, int size,
+                                         const std::string& locale) {
+   auto abstract_parcel =
+       pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
+   if (abstract_parcel == nullptr ||
+       abstract_parcel->GetType() != pcp::ParcelableType::Query) {
+     _LOGE("Invalid parcel or type");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
++        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   auto* parcel = dynamic_cast<pcp::QueryParcelable*>(abstract_parcel.get());
+   if (parcel == nullptr) {
+     _LOGE("Parcel is empty");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -  db.SetQueryArgs(parcel->GetQueryArgs());
++        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   psd::QueryHandler db(parcel->GetUid(), GetPID());
+   db.SetLocale(locale);
++  db.SetQueryArgs(parcel->ExtractQueryArgs());
+   db.SetDBType(parcel->GetDBType());
+   db.SetOpType(parcel->GetOpType());
+   int ret = db.Execute();
+   result_ = std::make_shared<pcp::ResultParcelable>(ret, db.GetResult());
+   return true;
+ }
+ std::vector<uint8_t> QueryRequestHandler::ExtractResult() {
+   tizen_base::Parcel parcel;
+   parcel.WriteParcelable(*result_);
+   std::vector<uint8_t> raw = parcel.GetRaw();
+   result_.reset();
+   return raw;
+ }
+ }  // namespace request_handler
+ }  // namespace pkgmgr_server
index 0000000000000000000000000000000000000000,765a5444e191acadd32f92d413968015ea9970b5..b216e182b20ed1d494963bc2af7059c9a14ece9f
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,65 +1,65 @@@
 -        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
+ // Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ // Use of this source code is governed by an apache-2.0 license that can be
+ // found in the LICENSE file.
+ #include "set_cert_request_handler.hh"
+ #include <string>
+ #include "certinfo_parcelable.hh"
+ #include "cert_set_db_handler.hh"
+ #include "parcelable_factory.hh"
+ #include "pkgmgrinfo_debug.h"
+ namespace pcp = pkgmgr_common::parcel;
+ namespace psd = pkgmgr_server::database;
+ namespace pkgmgr_server {
+ namespace request_handler {
+ bool SetCertRequestHandler::HandleRequest(unsigned char* data, int size,
+                                           const std::string& locale) {
+   auto abstract_parcel =
+       pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
+   if (abstract_parcel == nullptr ||
+       abstract_parcel->GetType() != pcp::ParcelableType::CertInfo) {
+     _LOGE("Invalid parcel");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -        PMINFO_R_ERROR, std::vector<std::vector<std::string>>{});
++        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   auto* parcel = dynamic_cast<pcp::CertInfoParcelable*>(abstract_parcel.get());
+   if (parcel == nullptr) {
+     _LOGE("Parcel is empty");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -      ret, std::vector<std::vector<std::string>>{});
++        PMINFO_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   psd::CertSetDBHandler db(parcel->GetUid(), GetPID());
+   db.SetLocale(locale);
+   db.SetCertHandle(const_cast<pkgmgr_certinfo_x*>(parcel->GetCertInfo()));
+   int ret = db.Execute();
+   result_ = std::make_shared<pcp::ResultParcelable>(
++      ret, std::vector<pcp::StrArgs>{});
+   return true;
+ }
+ std::vector<uint8_t> SetCertRequestHandler::ExtractResult() {
+   tizen_base::Parcel parcel;
+   parcel.WriteParcelable(*result_);
+   std::vector<uint8_t> raw = parcel.GetRaw();
+   result_.reset();
+   return raw;
+ }
+ }  // namespace request_handler
+ }  // namespace pkgmgr_server
index 0000000000000000000000000000000000000000,eb687deea4ca7e3e93e7d97dc999c758772f58d3..ab94515e42c478182969e95aee5e296e5dbce213
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,77 +1,77 @@@
 -        PM_PARSER_R_ERROR, std::vector<std::vector<std::string>>{});
+ // Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ // Use of this source code is governed by an apache-2.0 license that can be
+ // found in the LICENSE file.
+ #include "set_pkginfo_request_handler.hh"
+ #include <string>
+ #include "parcelable_factory.hh"
+ #include "pkginfo_parcelable.hh"
+ #include "pkg_set_db_handler.hh"
+ #include "pkgmgr_parser.h"
+ #include "pkgmgrinfo_debug.h"
+ namespace pcp = pkgmgr_common::parcel;
+ namespace psd = pkgmgr_server::database;
+ namespace pkgmgr_server {
+ namespace request_handler {
+ bool SetPkginfoRequestHandler::HandleRequest(unsigned char* data, int size,
+                                              const std::string& locale) {
+   auto abstract_parcel =
+       pcp::ParcelableFactory::GetInst().CreateParcel(data, size);
+   if (abstract_parcel == nullptr ||
+       abstract_parcel->GetType() != pcp::ParcelableType::PkgInfo) {
+     _LOGE("Invalid parcel or type");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -        PM_PARSER_R_ERROR, std::vector<std::vector<std::string>>{});
++        PM_PARSER_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   auto* parcel = dynamic_cast<pcp::PkgInfoParcelable*>(abstract_parcel.get());
+   if (parcel == nullptr) {
+     _LOGE("Parcel is empty");
+     result_ = std::make_shared<pcp::ResultParcelable>(
 -      ret, std::vector<std::vector<std::string>>{});
++        PM_PARSER_R_ERROR, std::vector<pcp::StrArgs>{});
+     return false;
+   }
+   psd::PkgSetDBHandler db(parcel->GetUid(), GetPID());
+   db.SetLocale(locale);
+   db.SetWriteType(parcel->GetWriteType());
+   int ret = PM_PARSER_R_ERROR;
+   for (auto& i : parcel->GetPkgInfo()) {
+     db.SetPkgInfo(i);
+     ret = db.Execute();
+     if (ret != PM_PARSER_R_OK) {
+       _LOGE("Failed to set pkginfo");
+       break;
+     }
+   }
+   result_ = std::make_shared<pcp::ResultParcelable>(
++      ret, std::vector<pcp::StrArgs>{});
+   return true;
+ }
+ std::vector<uint8_t> SetPkginfoRequestHandler::ExtractResult() {
+   tizen_base::Parcel parcel;
+   parcel.WriteParcelable(*result_);
+   std::vector<uint8_t> raw = parcel.GetRaw();
+   result_.reset();
+   return raw;
+ }
+ }  // namespace request_handler
+ }  // namespace pkgmgr_server
index 27b2ab3f00163edf1e9307ca015e365688eda10d,5c22a7fb5d34e14935ec090eb6953d6b4021addc..73dbb7997aae6f4660f7e7b5f6460ef3dc0c7b80
@@@ -25,8 -30,15 +30,15 @@@ TARGET_LINK_LIBRARIES(${TARGET_PKGMGR_I
  SET_TARGET_PROPERTIES(${TARGET_PKGMGR_INFO_UNIT_TEST} PROPERTIES COMPILE_FLAGS ${CFLAGS} "-fPIE -fpic")
  SET_TARGET_PROPERTIES(${TARGET_PKGMGR_INFO_UNIT_TEST} PROPERTIES LINK_FLAGS "-pie")
  set_target_properties(${TARGET_PKGMGR_INFO_UNIT_TEST} PROPERTIES COMPILE_FLAGS "${unit_test_pkgs_CFLAGS_str}")
 -target_link_libraries(${TARGET_PKGMGR_INFO_UNIT_TEST} ${unit_test_pkgs_LDFLAGS})
 +target_link_libraries(${TARGET_PKGMGR_INFO_UNIT_TEST} PRIVATE ${unit_test_pkgs_LDFLAGS})
  
+ SET_TARGET_PROPERTIES(${TARGET_PKGMGR_INFO_UNIT_TEST} PROPERTIES
+   LINK_FLAGS "-Wl,\
+ --wrap=fopen,\
+ --wrap=fopen64,\
+ --wrap=fgets,\
+ --wrap=fclose")
  ADD_TEST(
    NAME ${TARGET_PKGMGR_INFO_UNIT_TEST}
    COMMAND ${TARGET_PKGMGR_INFO_UNIT_TEST}
index 80fc93a049c3312673a9b0f2955a2dcc207259a4,406212af0f74bc5ba7c6680114e923c1ea8c9616..fe466675d326f73e8554fc5c1ab3950cc9b9e991
@@@ -69,8 -67,7 +67,7 @@@ application_x* GetTestApplication(std::
    application->guestmode_visibility = strdup("test_guestmode_visibility");
    application->component = strdup("test_component");
    application->permission_type = strdup("test_permission_type");
--  application->component_type = strdup("test_component_type");
++  application->component_type = strdup("test_component");
    application->preload = strdup("test_preload");
    application->submode = strdup("test_submode");
    application->submode_mainid = strdup("test_submode_mainid");
@@@ -406,6 -434,6 +444,8 @@@ package_x* GetTestPackage(std::string p
    package->backend_installer = strdup("test_backend_installer");
    package->external_path = strdup("test_external_path");
    package->use_system_certs = strdup("test_use_system_certs");
++  package->res_type = strdup("test_res_type");
++  package->res_version = strdup("test_res_version");
  
    icon_x* icon = reinterpret_cast<icon_x*>(calloc(1, sizeof(icon_x)));
    icon->text = strdup("test_text");
@@@ -628,47 -690,18 +713,40 @@@ bool IsEqualPackage(package_x* packageA
      STR_EQ(dependency_a->type, dependency_b->type);
    }
  
-   INT_EQ(g_list_length(packageA->plugin), g_list_length(packageB->plugin));
-   for (GList *a = packageA->plugin, *b = packageB->plugin;
-       a && b; a = a->next, b = b->next) {
-     plugin_x *plugin_a = reinterpret_cast<plugin_x *>(a->data);
-     plugin_x *plugin_b = reinterpret_cast<plugin_x *>(b->data);
-     STR_EQ(plugin_a->appid, plugin_b->appid);
-     STR_EQ(plugin_a->pkgid, plugin_b->pkgid);
-     STR_EQ(plugin_a->plugin_name, plugin_b->plugin_name);
-     STR_EQ(plugin_a->plugin_type, plugin_b->plugin_type);
-   }
 +  INT_EQ(g_list_length(packageA->res_allowed_packages),
 +      g_list_length(packageB->res_allowed_packages));
 +  for (GList* a = packageA->res_allowed_packages,
 +      *b = packageB->res_allowed_packages; a && b; a = a->next, b = b->next) {
 +    res_allowed_package_x* allowed_package_a =
 +        reinterpret_cast<res_allowed_package_x*>(a->data);
 +    res_allowed_package_x* allowed_package_b =
 +        reinterpret_cast<res_allowed_package_x*>(b->data);
 +    STR_EQ(allowed_package_a->allowed_package,
 +        allowed_package_b->allowed_package);
 +
 +    INT_EQ(g_list_length(allowed_package_a->required_privileges),
 +        g_list_length(allowed_package_b->required_privileges));
 +
 +    for (GList* a = allowed_package_a->required_privileges,
 +        *b = allowed_package_b->required_privileges; a && b;
 +        a = a->next, b = b->next) {
 +      STR_EQ(reinterpret_cast<char*>(a->data),
 +          reinterpret_cast<char*>(b->data));
 +    }
 +  }
 +
-   INT_EQ(g_list_length(packageA->application),
-       g_list_length(packageB->application));
-   for (GList *a = packageA->application, *b = packageB->application;
-       a && b; a = a->next, b = b->next) {
-     application_x *application_a = reinterpret_cast<application_x *>(a->data);
-     application_x *application_b = reinterpret_cast<application_x *>(b->data);
+   return true;
+ }
  
-     if (!IsEqualApplication(application_a, application_b))
+ bool IsEqualPackagesStructure(const std::vector<package_x*>& packagesA,
+     const std::vector<package_x*>&packagesB) {
+   if (packagesA.size() != packagesB.size())
+     return false;
+   for (unsigned int i = 0; i < packagesA.size(); ++i) {
+     if (!IsEqualPackage(packagesA[i], packagesB[i]))
+       return false;
+     if (!IsEqualPackageExtraInfo(packagesA[i], packagesB[i]))
        return false;
    }
  
index e1e913e452fa41db6cb6fa86d5e7bf2be28d4fcc,54461a27fc0d33269a5ca55a19bdcd8797a13a6b..f5472d1e860fc912c5cc4b69c2476d476c144bef
@@@ -197,15 -177,14 +195,15 @@@ TEST_F(ParcelTest, ResultParcelable) 
  
  TEST_F(ParcelTest, QueryParcelable) {
    tizen_base::Parcel parcel;
 -  std::vector<std::pair<int, std::vector<std::string>>> query_args = {
 +  std::vector<std::pair<int, std::vector<const char*>>> query_args = {
      { 0, { "arg1", "arg2" } },
 -    { 1, { "arg1" } }
 +    { 1, { "arg1" } },
 +    { 2, { nullptr, "arg2" } }
    };
  
 -  pp::QueryParcelable origin_parcelable(0, query_args,
 +  pp::QueryParcelable origin_parcelable(0, std::move(query_args),
-       pcb::AbstractDBHandler::DBType::DB_TYPE_FILE_PKGDB,
-       pcb::AbstractDBHandler::OperationType::OPERATION_TYPE_READ);
+       pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB,
+       pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
    pp::QueryParcelable new_parcelable;
    parcel.WriteParcelable(origin_parcelable);
    parcel.ReadParcelable(&new_parcelable);
index 0000000000000000000000000000000000000000,6ec9b5859bcf66b85ad3830d080483374b1323c4..5ed0ccd25a4e3bf660b6451e458395a3af6ec3b1
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,474 +1,474 @@@
 -      std::vector<std::pair<int, std::vector<std::string>>>{
+ /*
+  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at
+  *
+  * http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  */
+ #include <gmock/gmock.h>
+ #include <gtest/gtest.h>
+ #include <cstdio>
+ #include "appinfo_db_handler.hh"
+ #include "create_db_handler.hh"
+ #include "depinfo_db_handler.hh"
+ #include "db_type.hh"
+ #include "parcel_utils.hh"
+ #include "pkg_get_db_handler.hh"
+ #include "pkg_set_db_handler.hh"
+ #include "query_handler.hh"
+ #include "mock/file_mock.h"
+ #include "mock/test_fixture.h"
+ #include "mock/system_info_mock.h"
+ #include "pkgmgr-info.h"
+ #include "pkgmgr_query_index.h"
+ #include "pkgmgrinfo_basic.h"
+ #define TEST_PARSER_DB "test.pkgmgr_parser.db"
+ namespace psd = pkgmgr_server::database;
+ namespace pc = pkgmgr_common;
+ class CreateParserDBHandlerMock : public psd::CreateDBHandler {
+  public:
+   CreateParserDBHandlerMock(uid_t uid, int pid)
+       : psd::CreateDBHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class PkgSetDBHandlerMock : public psd::PkgSetDBHandler {
+  public:
+   PkgSetDBHandlerMock(uid_t uid, int pid) : psd::PkgSetDBHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class PkgGetDBHandlerMock : public psd::PkgGetDBHandler {
+  public:
+   PkgGetDBHandlerMock(uid_t uid, int pid) : psd::PkgGetDBHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class AppInfoDBHandlerMock : public psd::AppInfoDBHandler {
+  public:
+   AppInfoDBHandlerMock(uid_t uid, int pid) : psd::AppInfoDBHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class DepInfoGetDBHandlerMock : public psd::DepInfoGetDBHandler {
+  public:
+   DepInfoGetDBHandlerMock(uid_t uid, int pid) :
+       psd::DepInfoGetDBHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class QueryHandlerMock : public psd::QueryHandler {
+  public:
+   QueryHandlerMock(uid_t uid, int pid) :
+       psd::QueryHandler(uid, pid) {}
+   MOCK_METHOD0(Connect, bool());
+   MOCK_METHOD0(GetConnection, std::vector<std::pair<sqlite3*, uid_t>>());
+ };
+ class Mocks : public ::testing::NiceMock<SystemInfoMock> {};
+ class ParserDBHandlerTest : public TestFixture {
+  public:
+   ParserDBHandlerTest() : TestFixture(std::make_unique<Mocks>()) {}
+   virtual ~ParserDBHandlerTest() {}
+   virtual void SetUp() {
+     sqlite3 *db;
+     ASSERT_EQ(sqlite3_open_v2(TEST_PARSER_DB, &db,
+         SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL), SQLITE_OK);
+     SetDBHandles(
+         std::vector<std::pair<sqlite3*, uid_t>> { std::make_pair(db, 0) });
+     CreateParserDBHandlerMock create_db_handler(0, 0);
+     EXPECT_CALL(create_db_handler, Connect())
+         .Times(2).WillRepeatedly(testing::Return(true));
+     EXPECT_CALL(create_db_handler, GetConnection())
+         .Times(2).WillRepeatedly(testing::Return(GetDBHandles()));
+     EXPECT_CALL(GetMock<SystemInfoMock>(),
+       system_info_get_platform_int(testing::_, testing::_))
+           .WillRepeatedly(testing::DoAll(
+                   testing::SetArgPointee<1>(120), testing::Return(0)));
+     fopen_mock_setup(true);
+     ASSERT_EQ(create_db_handler.Execute(), 0);
+     fopen_mock_setup(false);
+   }
+   virtual void TearDown() {
+     for (auto& handle : db_handles_)
+       sqlite3_close_v2(handle.first);
+     ASSERT_EQ(remove(TEST_PARSER_DB), 0);
+     std::string journal_path(TEST_PARSER_DB);
+     journal_path += "-journal";
+     ASSERT_EQ(remove(journal_path.c_str()), 0);
+   }
+   const std::vector<std::pair<sqlite3*, uid_t>>& GetDBHandles() {
+     return db_handles_;
+   }
+  private:
+   void SetDBHandles(std::vector<std::pair<sqlite3*, uid_t>>&& db_handles) {
+     db_handles_ = db_handles;
+   }
+   std::vector<std::pair<sqlite3*, uid_t>> db_handles_;
+ };
+ TEST_F(ParserDBHandlerTest, PkgSetDBHandlerTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("pkgA"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
+ }
+ TEST_F(ParserDBHandlerTest, PkgGetDBHandlerTest) {
+   std::string pkgid = "pkgA";
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage(pkgid), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
+   pkgmgrinfo_pkginfo_filter_h filter;
+   ASSERT_EQ(pkgmgrinfo_pkginfo_filter_create(&filter), PMINFO_R_OK);
+   std::unique_ptr<pkgmgrinfo_filter_x, decltype(
+       pkgmgrinfo_pkginfo_filter_destroy)*> filter_ptr(
+           reinterpret_cast<pkgmgrinfo_filter_x *>(filter),
+               pkgmgrinfo_pkginfo_filter_destroy);
+   ASSERT_EQ(pkgmgrinfo_pkginfo_filter_add_string(filter,
+       PMINFO_PKGINFO_PROP_PACKAGE_ID, pkgid.c_str()), PMINFO_R_OK);
+   ASSERT_EQ(pkgmgrinfo_pkginfo_filter_add_bool(filter,
+       PMINFO_PKGINFO_PROP_PACKAGE_DISABLE, false), PMINFO_R_OK);
+   PkgGetDBHandlerMock pkg_get_db_handler(0, 0);
+   pkg_get_db_handler.SetFilter(filter_ptr.get());
+   pkg_get_db_handler.SetLocale("test_lang");
+   EXPECT_CALL(pkg_get_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_get_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_get_db_handler.Execute(), 0);
+   auto lpkginfo_list = pkg_get_db_handler.GetPkgHandle();
+   ASSERT_EQ(lpkginfo_list.size(), 1);
+   auto test_pkginfo = GetTestPackage(pkgid);
+   std::vector<package_x*> rpkginfo_list;
+   rpkginfo_list.emplace_back(test_pkginfo);
+   ASSERT_EQ(IsEqualPackagesInfo(lpkginfo_list, rpkginfo_list), true);
+ }
+ TEST_F(ParserDBHandlerTest, AppInfoDBHandlerTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("test_package"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
+   pkgmgrinfo_appinfo_filter_h filter;
+   std::string appid = "test_app1";
+   ASSERT_EQ(pkgmgrinfo_appinfo_filter_create(&filter), PMINFO_R_OK);
+   std::unique_ptr<pkgmgrinfo_filter_x, decltype(
+       pkgmgrinfo_appinfo_filter_destroy)*> filter_ptr(
+           reinterpret_cast<pkgmgrinfo_filter_x *>(filter),
+               pkgmgrinfo_appinfo_filter_destroy);
+   ASSERT_EQ(pkgmgrinfo_appinfo_filter_add_string(filter,
+       PMINFO_APPINFO_PROP_APP_ID, appid.c_str()), PMINFO_R_OK);
+   ASSERT_EQ(pkgmgrinfo_appinfo_filter_add_bool(filter,
+       PMINFO_APPINFO_PROP_APP_DISABLE, false), PMINFO_R_OK);
+   AppInfoDBHandlerMock appinfo_db_handler(0, 0);
+   appinfo_db_handler.SetFilter(filter_ptr.get());
+   EXPECT_CALL(appinfo_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(appinfo_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   appinfo_db_handler.SetLocale("test_lang");
+   ASSERT_EQ(appinfo_db_handler.Execute(), 0);
+   auto lappinfo_list = appinfo_db_handler.GetAppHandle();
+   ASSERT_EQ(lappinfo_list.size(), 1);
+   auto test_appinfo = GetTestApplication(appid);
+   std::vector<application_x*> rappinfo_list;
+   rappinfo_list.emplace_back(test_appinfo);
+   ASSERT_EQ(IsEqualApplicationsInfo(lappinfo_list, rappinfo_list), true);
+ }
+ TEST_F(ParserDBHandlerTest, DepInfoDBHandlerTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("test_package"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
+   DepInfoGetDBHandlerMock depinfo_get_db_handler(0, 0);
+   depinfo_get_db_handler.SetPkgID("depends_on_pkgid");
+   EXPECT_CALL(depinfo_get_db_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(depinfo_get_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(depinfo_get_db_handler.Execute(), 0);
+   auto depinfo_from_db = depinfo_get_db_handler.GetDependencyList();
+   ASSERT_EQ(depinfo_from_db.size(), 1);
+   std::vector<dependency_x*> depinfo_list;
+   depinfo_list.emplace_back(GetTestDepInfo("test_package"));
+   EXPECT_TRUE(IsEqualDepInfo(depinfo_list, depinfo_from_db));
+ }
+ TEST_F(ParserDBHandlerTest, QueryDBHandler_PluginInfoTest) {
+   const std::string pkgid = "test_pkgid";
+   const std::string appid = "test_appid";
+   const std::string plugin_type = "test_plugin_type";
+   const std::string plugin_name = "test_plugin_name";
+   QueryHandlerMock set_query_handler(0, 0);
+   set_query_handler.SetQueryArgs(
 -              std::vector<std::string>{
++      std::vector<std::pair<int, std::vector<std::optional<std::string>>>>{
+           std::make_pair(
+               QUERY_INDEX_INSERT_PACKAGE_PLUGIN_EXECUTION_INFO,
 -      std::vector<std::pair<int, std::vector<std::string>>>{
++              std::vector<std::optional<std::string>>{
+                   pkgid, appid, plugin_type, plugin_name})});
+   set_query_handler.SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
+   set_query_handler.SetOpType(
+       pkgmgr_common::DBOperationType::OPERATION_TYPE_WRITE);
+   EXPECT_CALL(set_query_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(set_query_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(set_query_handler.Execute(), 0);
+   QueryHandlerMock get_query_handler(0, 0);
+   get_query_handler.SetQueryArgs(
 -              std::vector<std::string>{pkgid, plugin_type, plugin_name})});
++      std::vector<std::pair<int, std::vector<std::optional<std::string>>>>{
+           std::make_pair(
+               QUERY_INDEX_PLUGININFO_GET_APPIDS,
 -  std::vector<std::pair<int, std::vector<std::string>>> query_args;
 -  std::vector<std::vector<std::string>> expected_label;
++              std::vector<std::optional<std::string>>{pkgid, plugin_type, plugin_name})});
+   get_query_handler.SetDBType(pkgmgr_common::DBType::DB_TYPE_FILE_PKGDB);
+   get_query_handler.SetOpType(
+       pkgmgr_common::DBOperationType::OPERATION_TYPE_READ);
+   EXPECT_CALL(get_query_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(get_query_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(get_query_handler.Execute(), 0);
+   auto result = get_query_handler.GetResult();
+   ASSERT_EQ(result.size(), 1);
+   ASSERT_EQ(result[0].size(), 1);
+   ASSERT_EQ(appid, result[0][0]);
+ }
+ TEST_F(ParserDBHandlerTest, QueryDBHandler_GetLocaledLabelTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("test_package"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
 -          std::vector<std::string>{app->appid, label->lang}));
 -      expected_label.emplace_back(std::vector<std::string>{label->text});
++  std::vector<std::pair<int, std::vector<std::optional<std::string>>>> query_args;
++  std::vector<std::vector<std::optional<std::string>>> expected_label;
+   for (GList* app_list = ptr.get()->application; app_list;
+       app_list = app_list->next) {
+     application_x* app = reinterpret_cast<application_x*>(app_list->data);
+     ASSERT_NE(app, nullptr);
+     ASSERT_NE(app->appid, nullptr);
+     ASSERT_NE(app->label, nullptr);
+     for (GList* label_list = app->label; label_list;
+         label_list = label_list->next) {
+       label_x* label = reinterpret_cast<label_x*>(label_list->data);
+       ASSERT_NE(label, nullptr);
+       ASSERT_NE(label->lang, nullptr);
+       ASSERT_NE(label->text, nullptr);
+       query_args.emplace_back(std::make_pair(
+           QUERY_INDEX_APPINFO_GET_LOCALED_LABEL,
 -  std::vector<std::pair<int, std::vector<std::string>>> query_args;
 -  std::vector<std::vector<std::string>> expected_label;
++          std::vector<std::optional<std::string>>{app->appid, label->lang}));
++      expected_label.emplace_back(std::vector<std::optional<std::string>>{label->text});
+     }
+   }
+   QueryHandlerMock query_handler(0, 0);
+   query_handler.SetQueryArgs(std::move(query_args));
+   query_handler.SetDBType(pc::DBType::DB_TYPE_FILE_PKGDB);
+   query_handler.SetOpType(pc::DBOperationType::OPERATION_TYPE_READ);
+   EXPECT_CALL(query_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(query_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(query_handler.Execute(), 0);
+   auto result = query_handler.GetResult();
+   ASSERT_EQ(result, expected_label);
+ }
+ TEST_F(ParserDBHandlerTest, QueryDBHandler_GetDataControlTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("test_package"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
 -          std::vector<std::string>{dc->providerid, dc->type}));
++  std::vector<std::pair<int, std::vector<std::optional<std::string>>>> query_args;
++  std::vector<std::vector<std::optional<std::string>>> expected_label;
+   for (GList* app_list = ptr.get()->application; app_list;
+       app_list = app_list->next) {
+     application_x* app = reinterpret_cast<application_x*>(app_list->data);
+     ASSERT_NE(app, nullptr);
+     ASSERT_NE(app->appid, nullptr);
+     ASSERT_NE(app->datacontrol, nullptr);
+     for (GList* dc_list = app->datacontrol; dc_list; dc_list = dc_list->next) {
+       datacontrol_x* dc = reinterpret_cast<datacontrol_x*>(dc_list->data);
+       ASSERT_NE(dc, nullptr);
+       ASSERT_NE(dc->providerid, nullptr);
+       ASSERT_NE(dc->type, nullptr);
+       ASSERT_NE(dc->access, nullptr);
+       query_args.emplace_back(std::make_pair(
+           QUERY_INDEX_APPINFO_GET_DATACONTROL_INFO,
 -          std::vector<std::string>{app->appid, dc->access});
++          std::vector<std::optional<std::string>>{dc->providerid, dc->type}));
+       expected_label.emplace_back(
 -  std::vector<std::pair<int, std::vector<std::string>>> query_args;
 -  std::vector<std::vector<std::string>> expected_appids;
 -  std::map<std::string, std::vector<std::string>> provider_map;
++          std::vector<std::optional<std::string>>{app->appid, dc->access});
+     }
+   }
+   QueryHandlerMock query_handler(0, 0);
+   query_handler.SetQueryArgs(std::move(query_args));
+   query_handler.SetDBType(pc::DBType::DB_TYPE_FILE_PKGDB);
+   query_handler.SetOpType(pc::DBOperationType::OPERATION_TYPE_READ);
+   EXPECT_CALL(query_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(query_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(query_handler.Execute(), 0);
+   auto result = query_handler.GetResult();
+   ASSERT_EQ(result, expected_label);
+ }
+ TEST_F(ParserDBHandlerTest, QueryDBHandler_GetDataControlAppIdTest) {
+   PkgSetDBHandlerMock pkg_set_db_handler(0, 0);
+   pkg_set_db_handler.SetWriteType(pkgmgr_common::PkgWriteType::Insert);
+   std::unique_ptr<package_x, decltype(pkgmgrinfo_basic_free_package)*> ptr(
+       GetTestPackage("test_package"), pkgmgrinfo_basic_free_package);
+   pkg_set_db_handler.SetPkgInfo(ptr.get());
+   EXPECT_CALL(pkg_set_db_handler, Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(pkg_set_db_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(pkg_set_db_handler.Execute(), 0);
 -        std::vector<std::string>{std::move(it.first)}));
++  std::vector<std::pair<int, std::vector<std::optional<std::string>>>> query_args;
++  std::vector<std::vector<std::optional<std::string>>> expected_appids;
++  std::map<std::string, std::vector<std::optional<std::string>>> provider_map;
+   for (GList* app_list = ptr.get()->application; app_list;
+       app_list = app_list->next) {
+     application_x* app = reinterpret_cast<application_x*>(app_list->data);
+     ASSERT_NE(app, nullptr);
+     ASSERT_NE(app->appid, nullptr);
+     ASSERT_NE(app->datacontrol, nullptr);
+     for (GList* dc_list = app->datacontrol; dc_list; dc_list = dc_list->next) {
+       datacontrol_x* dc = reinterpret_cast<datacontrol_x*>(dc_list->data);
+       ASSERT_NE(dc, nullptr);
+       ASSERT_NE(dc->providerid, nullptr);
+       ASSERT_NE(dc->type, nullptr);
+       ASSERT_NE(dc->access, nullptr);
+       provider_map[dc->providerid].emplace_back(app->appid);
+     }
+   }
+   for (auto& it : provider_map) {
+     query_args.emplace_back(std::make_pair(
+         QUERY_INDEX_APPINFO_GET_DATACONTROL_APPID,
++        std::vector<std::optional<std::string>>{std::move(it.first)}));
+     expected_appids.emplace_back(std::move(it.second));
+   }
+   QueryHandlerMock query_handler(0, 0);
+   query_handler.SetQueryArgs(std::move(query_args));
+   query_handler.SetDBType(pc::DBType::DB_TYPE_FILE_PKGDB);
+   query_handler.SetOpType(pc::DBOperationType::OPERATION_TYPE_READ);
+   EXPECT_CALL(query_handler,
+       Connect()).WillOnce(testing::Return(true));
+   EXPECT_CALL(query_handler, GetConnection())
+       .WillOnce(testing::Return(GetDBHandles()));
+   ASSERT_EQ(query_handler.Execute(), 0);
+   auto result = query_handler.GetResult();
+   ASSERT_NE(result.size(), 0);
+   for (auto& it : result)
+     std::sort(it.begin(), it.end());
+   for (auto& it : expected_appids)
+     std::sort(it.begin(), it.end());
+   ASSERT_EQ(result, expected_appids);
+ }