From 8dcd34312e0012d1509e623daedfb43388889a94 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 27 Feb 2019 10:25:45 +0900 Subject: [PATCH] Add new elements for component-based application Requires: - https://review.tizen.org/gerrit/#/c/platform/core/appfw/pkgmgr-info/+/200568/ - https://review.tizen.org/gerrit/#/c/platform/core/appfw/tpk-manifest-handlers/+/200669/ - https://review.tizen.org/gerrit/#/c/platform/core/appfw/app-installers/+/200691/ - https://review.tizen.org/gerrit/#/c/platform/core/appfw/amd/+/200773/ Change-Id: Ib4b45d27948f48f74274f8346c624ac6710e7b42 Signed-off-by: Hwankyu Jhun --- include/pkgmgr-info.h | 12 ++++ include/pkgmgrinfo_basic.h | 7 +++ include/pkgmgrinfo_type.h | 31 ++++++++-- parser/manifest.xsd.in | 35 +++++++++++ parser/manifest.xsd.ref | 27 ++++++++ parser/src/pkgmgr_parser_db.c | 55 ++++++++++++++++- parser/src/pkgmgr_parser_db_queries.h | 10 +++ src/pkgmgrinfo_appinfo.c | 112 ++++++++++++++++++++++++++++++++++ src/pkgmgrinfo_basic.c | 17 ++++++ src/pkgmgrinfo_compinfo.c | 82 +++++++++++++++++++++++++ src/pkgmgrinfo_private.h | 6 ++ 11 files changed, 388 insertions(+), 6 deletions(-) create mode 100644 src/pkgmgrinfo_compinfo.c diff --git a/include/pkgmgr-info.h b/include/pkgmgr-info.h index 9ba8de8..fa5ef22 100644 --- a/include/pkgmgr-info.h +++ b/include/pkgmgr-info.h @@ -6467,6 +6467,18 @@ int pkgmgrinfo_archiveinfo_get_author(pkgmgrinfo_archiveinfo_h handle, int pkgmgrinfo_archiveinfo_get_icon(pkgmgrinfo_archiveinfo_h handle, const unsigned char **icon, size_t *size); +int pkgmgrinfo_appinfo_foreach_component_info(pkgmgrinfo_appinfo_h handle, + pkgmgrinfo_component_info_list_cb callback, void *user_data); + +int pkgmgrinfo_compinfo_get_appid(pkgmgrinfo_compinfo_h handle, + const char **appid); +int pkgmgrinfo_compinfo_get_compid(pkgmgrinfo_compinfo_h handle, + const char **compid); +int pkgmgrinfo_compinfo_get_type(pkgmgrinfo_compinfo_h handle, + const char **type); +int pkgmgrinfo_compinfo_get_launch_mode(pkgmgrinfo_compinfo_h handle, + const char **launch_mode); + /** * @pkgmgrinfo client API end **/ diff --git a/include/pkgmgrinfo_basic.h b/include/pkgmgrinfo_basic.h index 974d9b8..fd5cbc1 100644 --- a/include/pkgmgrinfo_basic.h +++ b/include/pkgmgrinfo_basic.h @@ -133,6 +133,12 @@ typedef struct dependency_x { char *required_version; } dependency_x; +typedef struct component_x { + char *id; + char *type; + char *launch_mode; +} component_x; + typedef struct application_x { char *appid; /*attr*/ char *exec; /*attr*/ @@ -196,6 +202,7 @@ typedef struct application_x { GList *background_category; /*element*/ GList *appcontrol; /*element*/ GList *splashscreens; /*element*/ + GList *components; /*element*/ } application_x; typedef struct package_x { diff --git a/include/pkgmgrinfo_type.h b/include/pkgmgrinfo_type.h index 870d376..5b7ee08 100644 --- a/include/pkgmgrinfo_type.h +++ b/include/pkgmgrinfo_type.h @@ -225,6 +225,11 @@ typedef void *pkgmgrinfo_appcontrol_h; typedef void *pkgmgrinfo_archiveinfo_h; /** + * @brief A handle to get component information + */ +typedef void *pkgmgrinfo_compinfo_h; + +/** * @brief type definition. */ typedef void pkgmgrinfo_client; @@ -449,6 +454,21 @@ typedef int (*pkgmgrinfo_app_splash_screen_list_cb)(const char *src, const char *color_depth, void *user_data); /** + * @fn int (*pkgmgrinfo_component_info_list_cb)( + * const pkgmgrinfo_compinfo_h handle, void *user_data); + * @brief Specifies the type of function passed to pkgmgrinfo_appinfo_foreach_component_info() + * + * @param[in] handle The handle of the component info + * @param[in] user_data The user data passed from pkgmgrinfo_appinfo_foreach_component_info() + * + * @return 0 if success, negative value(<0) if fail. Callback is not called if return value is negative.\n + * + * @see pkgmgrinfo_appinfo_foreach_component_info() + */ +typedef int (*pkgmgrinfo_component_info_list_cb)( + const pkgmgrinfo_compinfo_h handle, void *user_data); + +/** * @brief Install Location Types */ typedef enum { @@ -461,11 +481,12 @@ typedef enum { * @brief Application Component Types */ typedef enum { - PMINFO_ALL_APP = 0, /**< All Application*/ - PMINFO_UI_APP, /**< UI Application*/ - PMINFO_SVC_APP, /**< Service Application*/ - PMINFO_WIDGET_APP, /**< Widget Application*/ - PMINFO_WATCH_APP, /**< Watch Application*/ + PMINFO_ALL_APP = 0, /**< All Application*/ + PMINFO_UI_APP, /**< UI Application*/ + PMINFO_SVC_APP, /**< Service Application*/ + PMINFO_WIDGET_APP, /**< Widget Application*/ + PMINFO_WATCH_APP, /**< Watch Application*/ + PMINFO_COMPONENT_BASED_APP, /**< Component-based Application (Since 5.5)*/ } pkgmgrinfo_app_component; /** diff --git a/parser/manifest.xsd.in b/parser/manifest.xsd.in index c8a624a..17a1cae 100644 --- a/parser/manifest.xsd.in +++ b/parser/manifest.xsd.in @@ -26,6 +26,7 @@ + @@ -375,4 +376,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/parser/manifest.xsd.ref b/parser/manifest.xsd.ref index 253eef4..6aa3d7f 100644 --- a/parser/manifest.xsd.ref +++ b/parser/manifest.xsd.ref @@ -26,6 +26,7 @@ + @@ -436,4 +437,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/parser/src/pkgmgr_parser_db.c b/parser/src/pkgmgr_parser_db.c index b6db523..185aecb 100644 --- a/parser/src/pkgmgr_parser_db.c +++ b/parser/src/pkgmgr_parser_db.c @@ -331,6 +331,7 @@ static const char *parser_init_queries[] = { QUERY_CREATE_TABLE_PACKAGE_APP_SPLASH_SCREEN, QUERY_CREATE_TABLE_PACKAGE_DEPENDENCY_INFO, QUERY_CREATE_TABLE_PACKAGE_PLUGIN_INFO, + QUERY_CREATE_TABLE_PACKAGE_APP_COMPONENT_INFO, NULL, }; @@ -1210,6 +1211,51 @@ static int __insert_splashscreen_info(sqlite3 *db, application_x *app, return 0; } +static int __insert_component_info(sqlite3 *db, application_x *app) +{ + static const char query[] = + "INSERT INTO package_app_component_info (app_id, component_id, " + "type, launch_mode) VALUES(?, ?, ?, ?)"; + int ret; + sqlite3_stmt *stmt; + int idx; + GList *tmp; + component_x *c; + + if (app->components == 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->components; tmp; tmp = tmp->next) { + c = (component_x *)tmp->data; + if (c == NULL) + continue; + + idx = 1; + __BIND_TEXT(db, stmt, idx++, app->appid); + __BIND_TEXT(db, stmt, idx++, c->id); + __BIND_TEXT(db, stmt, idx++, c->type); + __BIND_TEXT(db, stmt, idx++, c->launch_mode); + + 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; @@ -2029,6 +2075,13 @@ static int __insert_application_info(sqlite3 *db, manifest_x *mfx) sqlite3_finalize(stmt); return -1; } + + if (!strcmp(app->component_type, "componentbasedapp")) { + if (__insert_component_info(db, app)) { + sqlite3_finalize(stmt); + return -1; + } + } } sqlite3_finalize(stmt); @@ -3231,4 +3284,4 @@ API int pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db( API int pkgmgr_parser_unregister_pkg_plugin_info_in_db(const char *pkgid) { return pkgmgr_parser_unregister_pkg_plugin_info_in_usr_db(pkgid, __getuid()); -} \ No newline at end of file +} diff --git a/parser/src/pkgmgr_parser_db_queries.h b/parser/src/pkgmgr_parser_db_queries.h index d444f4c..f7c063b 100644 --- a/parser/src/pkgmgr_parser_db_queries.h +++ b/parser/src/pkgmgr_parser_db_queries.h @@ -240,6 +240,16 @@ " FOREIGN KEY(app_id)\n" \ " REFERENCES package_app_info(app_id) ON DELETE CASCADE)" +#define QUERY_CREATE_TABLE_PACKAGE_APP_COMPONENT_INFO \ + "CREATE TABLE IF NOT EXISTS package_app_component_info (\n" \ + " app_id TEXT NOT NULL,\n" \ + " component_id TEXT NOT NULL,\n" \ + " type TEXT NOT NULL,\n" \ + " launch_mode TEXT NOT NULL,\n" \ + " PRIMARY KEY(app_id, component_id)\n" \ + " FOREIGN KEY(app_id)\n" \ + " REFERENCES package_app_info(app_id) ON DELETE CASCADE)" + #define QUERY_CREATE_TABLE_PACKAGE_DEPENDENCY_INFO \ "CREATE TABLE IF NOT EXISTS package_dependency_info (\n" \ " package TEXT NOT NULL,\n" \ diff --git a/src/pkgmgrinfo_appinfo.c b/src/pkgmgrinfo_appinfo.c index 3ea034f..bc42092 100644 --- a/src/pkgmgrinfo_appinfo.c +++ b/src/pkgmgrinfo_appinfo.c @@ -332,6 +332,52 @@ static int _appinfo_get_splashscreens(sqlite3 *db, const char *appid, return PMINFO_R_OK; } +static int _appinfo_get_component_info(sqlite3 *db, const char *appid, + GList **components) +{ + static const char query_raw[] = + "SELECT component_id, type, launch_mode " + "FROM package_app_component_info " + "WHERE app_id=%Q"; + int ret; + char *query; + sqlite3_stmt *stmt; + int idx; + component_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(component_x)); + if (info == NULL) { + LOGE("out of memory"); + sqlite3_finalize(stmt); + return PMINFO_R_ERROR; + } + + idx = 0; + _save_column_str(stmt, idx++, &info->id); + _save_column_str(stmt, idx++, &info->type); + _save_column_str(stmt, idx++, &info->launch_mode); + *components = g_list_append(*components, info); + } + + sqlite3_finalize(stmt); + + return PMINFO_R_OK; +} + static GList *__get_background_category(const char *value) { GList *category_list = NULL; @@ -703,6 +749,15 @@ static int _appinfo_get_applications(uid_t db_uid, uid_t uid, } } + if (info->component && + !strcmp(info->component, "componentbasedapp")) { + if (_appinfo_get_component_info(db, info->appid, + &info->components)) { + ret = PMINFO_R_ERROR; + goto catch; + } + } + if (is_check_storage && __appinfo_check_installed_storage(info) != PMINFO_R_OK) { ret = PMINFO_R_ERROR; @@ -1080,6 +1135,28 @@ static gpointer __copy_splashscreens(gconstpointer src, gpointer data) return splashscreen; } +static gpointer __copy_components(gconstpointer src, gpointer data) +{ + component_x *tmp = (component_x *)src; + component_x *component; + + component = (component_x *)calloc(1, sizeof(component_x)); + if (component == NULL) { + LOGE("memory alloc failed"); + *(int *)data = -1; + return NULL; + } + + if (tmp->id) + component->id = strdup(tmp->id); + if (tmp->type) + component->type = strdup(tmp->type); + if (tmp->launch_mode) + component->launch_mode = strdup(tmp->launch_mode); + + return component; +} + static int _appinfo_copy_appinfo(application_x **application, application_x *data) { application_x *app_info; @@ -1223,6 +1300,15 @@ static int _appinfo_copy_appinfo(application_x **application, application_x *dat return PMINFO_R_ERROR; } + ret = 0; + app_info->components = g_list_copy_deep(data->components, + __copy_components, &ret); + if (ret < 0) { + LOGE("memory alloc failed"); + pkgmgrinfo_basic_free_application(app_info); + return PMINFO_R_ERROR; + } + *application = app_info; return PMINFO_R_OK; @@ -1725,6 +1811,8 @@ static pkgmgrinfo_app_component __appcomponent_convert(const char *comp) return PMINFO_WIDGET_APP; else if (strcasecmp(comp, "watchapp") == 0) return PMINFO_WATCH_APP; + else if (strcasecmp(comp, "componentbasedapp") == 0) + return PMINFO_COMPONENT_BASED_APP; else return -1; } @@ -1740,6 +1828,8 @@ static const char *__appcomponent_str(pkgmgrinfo_app_component comp) return "widgetapp"; case PMINFO_WATCH_APP: return "watchapp"; + case PMINFO_COMPONENT_BASED_APP: + return "componentbasedapp"; default: return NULL; } @@ -3687,3 +3777,25 @@ API int pkgmgrinfo_appinfo_foreach_remote_appcontrol_v2( return PMINFO_R_OK; } + +API int pkgmgrinfo_appinfo_foreach_component_info(pkgmgrinfo_appinfo_h handle, + pkgmgrinfo_component_info_list_cb callback, void *user_data) +{ + retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL"); + retvm_if(callback == NULL, PMINFO_R_EINVAL, "callback is NULL"); + pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle; + pkgmgr_compinfo_x compinfo; + GList *tmp; + + if (info->app_info == NULL) + return PMINFO_R_ERROR; + + compinfo.appid = info->app_info->appid; + for (tmp = info->app_info->components; tmp; tmp = tmp->next) { + compinfo.comp_info = (component_x *)tmp->data; + if (callback(&compinfo, user_data) < 0) + break; + } + + return PMINFO_R_OK; +} diff --git a/src/pkgmgrinfo_basic.c b/src/pkgmgrinfo_basic.c index 381c0ac..1c1103a 100644 --- a/src/pkgmgrinfo_basic.c +++ b/src/pkgmgrinfo_basic.c @@ -232,6 +232,21 @@ static void __ps_free_splashscreen(gpointer data) free((void *)splashscreen); } +static void __ps_free_component_info(gpointer data) +{ + component_x *component = (component_x *)data; + + if (component == NULL) + return; + if (component->id) + free((void *)component->id); + if (component->type) + free((void *)component->type); + if (component->launch_mode) + free((void *)component->launch_mode); + free((void *)component); +} + static void __ps_free_privilege(gpointer data) { privilege_x *privilege = (privilege_x *)data; @@ -421,6 +436,8 @@ static void __ps_free_application(gpointer data) g_list_free_full(application->background_category, free); /*Free SplashScreen*/ g_list_free_full(application->splashscreens, __ps_free_splashscreen); + /*Free ComponentInfo*/ + g_list_free_full(application->components, __ps_free_component_info); free((void *)application); } diff --git a/src/pkgmgrinfo_compinfo.c b/src/pkgmgrinfo_compinfo.c new file mode 100644 index 0000000..f95eccc --- /dev/null +++ b/src/pkgmgrinfo_compinfo.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019 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 + +#include "pkgmgr-info.h" +#include "pkgmgrinfo_debug.h" +#include "pkgmgrinfo_private.h" + +API int pkgmgrinfo_compinfo_get_appid(pkgmgrinfo_compinfo_h handle, + const char **appid) +{ + retvm_if(handle == NULL, PMINFO_R_EINVAL, "compinfo handle is NULL"); + retvm_if(appid == NULL, PMINFO_R_EINVAL, "appid is NULL"); + pkgmgr_compinfo_x *info = (pkgmgr_compinfo_x *)handle; + + if (info->comp_info == NULL || info->appid == NULL) + return PMINFO_R_ERROR; + + *appid = info->appid; + + return PMINFO_R_OK; +} + +API int pkgmgrinfo_compinfo_get_compid(pkgmgrinfo_compinfo_h handle, + const char **compid) +{ + retvm_if(handle == NULL, PMINFO_R_EINVAL, "compinfo handle is NULL"); + retvm_if(compid == NULL, PMINFO_R_EINVAL, "compid is NULL"); + pkgmgr_compinfo_x *info = (pkgmgr_compinfo_x *)handle; + + if (info->comp_info == NULL || info->comp_info->id == NULL) + return PMINFO_R_ERROR; + + *compid = info->comp_info->id; + + return PMINFO_R_OK; +} + +API int pkgmgrinfo_compinfo_get_type(pkgmgrinfo_compinfo_h handle, + const char **type) +{ + retvm_if(handle == NULL, PMINFO_R_EINVAL, "compinfo handle is NULL"); + retvm_if(type == NULL, PMINFO_R_EINVAL, "type is NULL"); + pkgmgr_compinfo_x *info = (pkgmgr_compinfo_x *)handle; + + if (info->comp_info == NULL || info->comp_info->type == NULL) + return PMINFO_R_ERROR; + + *type = info->comp_info->type; + + return PMINFO_R_OK; +} + +API int pkgmgrinfo_compinfo_get_launch_mode(pkgmgrinfo_compinfo_h handle, + const char **launch_mode) +{ + retvm_if(handle == NULL, PMINFO_R_EINVAL, "compinfo handle is NULL"); + retvm_if(launch_mode == NULL, PMINFO_R_EINVAL, "type is NULL"); + pkgmgr_compinfo_x *info = (pkgmgr_compinfo_x *)handle; + + if (info->comp_info == NULL || info->comp_info->launch_mode == NULL) + return PMINFO_R_ERROR; + + *launch_mode = info->comp_info->launch_mode; + + return PMINFO_R_OK; +} diff --git a/src/pkgmgrinfo_private.h b/src/pkgmgrinfo_private.h index 9d581b5..333381b 100644 --- a/src/pkgmgrinfo_private.h +++ b/src/pkgmgrinfo_private.h @@ -225,6 +225,12 @@ typedef struct _pkgmgrinfo_appcontrol_x { char **subapp; } pkgmgrinfo_appcontrol_x; +/* for component-based-application */ +typedef struct _pkgmgr_compinfo_x { + const char *appid; + component_x *comp_info; +} pkgmgr_compinfo_x; + typedef struct _db_handle { sqlite3 *dbHandle; int ref; -- 2.7.4