Add new elements for component-based application 68/200568/19
authorHwankyu Jhun <h.jhun@samsung.com>
Wed, 27 Feb 2019 01:25:45 +0000 (10:25 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Wed, 13 Mar 2019 02:34:54 +0000 (11:34 +0900)
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 <h.jhun@samsung.com>
include/pkgmgr-info.h
include/pkgmgrinfo_basic.h
include/pkgmgrinfo_type.h
parser/manifest.xsd.in
parser/manifest.xsd.ref
parser/src/pkgmgr_parser_db.c
parser/src/pkgmgr_parser_db_queries.h
src/pkgmgrinfo_appinfo.c
src/pkgmgrinfo_basic.c
src/pkgmgrinfo_compinfo.c [new file with mode: 0644]
src/pkgmgrinfo_private.h

index 9ba8de8..fa5ef22 100644 (file)
@@ -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
 **/
index 974d9b8..fd5cbc1 100644 (file)
@@ -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 {
index 870d376..5b7ee08 100644 (file)
@@ -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;
 
 /**
index c8a624a..17a1cae 100644 (file)
@@ -26,6 +26,7 @@
         <xs:element ref="packages:ime"/>
         <xs:element ref="packages:feature"/>
         <xs:element ref="packages:trust-anchor"/>
+        <xs:element ref="packages:component-based-application"/>
         <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##any" processContents="lax"/>
       </xs:choice>
       <xs:attribute name="storeclient-id" type="xs:string"/>
       <xs:anyAttribute namespace="##any" processContents="lax"/>
     </xs:complexType>
   </xs:element>
+  <xs:element name="component-based-application">
+    <xs:complexType>
+      <xs:choice maxOccurs="unbounded" minOccurs="0">
+        <xs:element ref="packages:icon"/>
+        <xs:element ref="packages:label"/>
+        <xs:element ref="packages:metadata"/>
+        <xs:element ref="packages:background-category"/>
+        <xs:element ref="packages:frame-component"/>
+        <xs:element ref="packages:service-component"/>
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##any" processContents="lax"/>
+      </xs:choice>
+      <xs:attribute name="appid" use="required" type="xs:string"/>
+      <xs:attribute name="exec" use="required"/>
+      <xs:attribute name="type" use="required" type="xs:string"/>
+      <xs:anyAttribute namespace="##any" processContents="lax"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="frame-component">
+    <xs:complexType>
+      <xs:choice maxOccurs="unbounded" minOccurs="0">
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##any" processContents="lax"/>
+      </xs:choice>
+      <xs:attribute name="id" use="required" type="xs:string"/>
+      <xs:attribute name="launch_mode" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="service-component">
+    <xs:complexType>
+      <xs:choice maxOccurs="unbounded" minOccurs="0">
+        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##any" processContents="lax"/>
+      </xs:choice>
+      <xs:attribute name="id" use="required" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
 </xs:schema>
index 253eef4..6aa3d7f 100644 (file)
@@ -26,6 +26,7 @@
         <xs:element ref="packages:ime"/>
         <xs:element ref="packages:feature"/>
         <xs:element ref="packages:trust-anchor"/>
+        <xs:element ref="packages:component-based-application"/>
       </xs:choice>
       <xs:attribute name="storeclient-id" type="xs:string"/>
       <xs:attribute name="install-location" type="packages:InstallLocationType"/>
       <xs:attribute name="color-depth" type="xs:string"/>
     </xs:complexType>
   </xs:element>
+  <xs:element name="component-based-application">
+    <xs:complexType>
+      <xs:choice maxOccurs="unbounded" minOccurs="0">
+        <xs:element ref="packages:icon"/>
+        <xs:element ref="packages:label"/>
+        <xs:element ref="packages:metadata"/>
+        <xs:element ref="packages:background-category"/>
+        <xs:element ref="packages:frame-component"/>
+        <xs:element ref="packages:service-component"/>
+      </xs:choice>
+      <xs:attribute name="appid" use="required" type="xs:string"/>
+      <xs:attribute name="exec" use="required"/>
+      <xs:attribute name="type" use="required" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="frame-component">
+    <xs:complexType>
+      <xs:attribute name="id" use="required" type="xs:string"/>
+      <xs:attribute name="launch_mode" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="service-component">
+    <xs:complexType>
+      <xs:attribute name="id" use="required" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
 </xs:schema>
index b6db523..185aecb 100644 (file)
@@ -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
+}
index d444f4c..f7c063b 100644 (file)
        "  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" \
index 3ea034f..bc42092 100644 (file)
@@ -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;
+}
index 381c0ac..1c1103a 100644 (file)
@@ -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 (file)
index 0000000..f95eccc
--- /dev/null
@@ -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 <stdio.h>
+
+#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;
+}
index 9d581b5..333381b 100644 (file)
@@ -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;