Add appdefined privilege feature 68/137368/16
authorjongmyeongko <jongmyeong.ko@samsung.com>
Wed, 5 Jul 2017 10:39:47 +0000 (19:39 +0900)
committerjongmyeongko <jongmyeong.ko@samsung.com>
Tue, 25 Jul 2017 10:35:17 +0000 (19:35 +0900)
Change-Id: I4d7a285919873b9e7aa8af53d316503f19626727
Signed-off-by: jongmyeongko <jongmyeong.ko@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_basic.c
src/pkgmgrinfo_db.c
src/pkgmgrinfo_pkginfo.c

index cb63b9f..9c3dbb6 100644 (file)
@@ -2393,6 +2393,7 @@ static int get_tpk_pkg_count()
  */
 int pkgmgrinfo_pkginfo_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count);
 int pkgmgrinfo_pkginfo_usr_filter_count(pkgmgrinfo_pkginfo_filter_h handle, int *count, uid_t uid);
+
 /**
  * @fn int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
                        pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data);
@@ -2438,6 +2439,51 @@ static int list_privilege(const char *package, char *privilege)
 int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
                        pkgmgrinfo_pkg_privilege_list_cb privilege_func, void *user_data);
 
+/**
+ * @fn int pkgmgrinfo_pkginfo_foreach_appdefined_privilege(pkgmgrinfo_pkginfo_h handle,
+                       pkgmgrinfo_pkg_appdefined_privilege_list_cb privilege_func, void *user_data);
+ * @brief      This API gets the list of appdefined privilege for a particular package
+ *
+ * @par                This API is for package-manager client application
+ * @par Sync (or) Async : Synchronous API
+ * @param[in]  handle          pointer to the package info handle.
+ * @param[in]  privilege_func          callback function for list
+ * @param[in] user_data        user data to be passed to callback function
+ * @return     0 if success, error code(<0) if fail
+ * @retval     PMINFO_R_OK     success
+ * @retval     PMINFO_R_EINVAL invalid argument
+ * @retval     PMINFO_R_ERROR  internal error
+ * @pre                pkgmgrinfo_pkginfo_get_pkginfo()
+ * @post               pkgmgrinfo_pkginfo_destroy_pkginfo()
+ * @code
+int privilege_func(const char *name, const char *license_path, void *user_data)
+{
+       printf("appdefined privilege : %s", name);
+       if (license_path)
+               printf("licensed privilege, lecense path : %s", license_path);
+       return 0;
+}
+
+static int list_appdefined_privilege(const char *package)
+{
+       int ret = 0;
+       pkgmgrinfo_pkginfo_h handle;
+       ret = pkgmgrinfo_pkginfo_get_pkginfo(package, &handle);
+       if (ret != PMINFO_R_OK)
+               return -1;
+       ret = pkgmgrinfo_pkginfo_foreach_appdefined_privilege(handle, privilege_func, NULL);
+       if (ret != PMINFO_R_OK) {
+               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+               return -1;
+       }
+       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+       return 0;
+}
+ * @endcode
+ */
+int pkgmgrinfo_pkginfo_foreach_appdefined_privilege(pkgmgrinfo_pkginfo_h handle,
+                       pkgmgrinfo_pkg_appdefined_privilege_list_cb privilege_func, void *user_data);
+
 /* TODO: add doxygen comment here */
 int pkgmgrinfo_pkginfo_is_for_all_users(pkgmgrinfo_pkginfo_h handle, bool *for_all_users);
 
index e78fd61..5fa1918 100644 (file)
@@ -108,6 +108,12 @@ typedef struct privilege_x {
        char *value;
 } privilege_x;
 
+typedef struct appdefined_privilege_x {
+       char *type;
+       char *value;
+       char *license;
+} appdefined_privilege_x;
+
 typedef struct application_x {
        char *appid;    /*attr*/
        char *exec;     /*attr*/
@@ -208,6 +214,8 @@ typedef struct package_x {
        GList *description;             /**< package description, element*/
        GList *license;         /**< package license, no xml part*/
        GList *privileges;      /**< package privileges, element*/
+       GList *appdefined_privileges;   /**<package appdefined privileges, element*/
+       GList *provides_appdefined_privileges;  /**<package providing appdefined privileges, element*/
        GList *application;             /**< package's application, element*/
        GList *compatibility;           /**< package compatibility, element*/
        GList *deviceprofile;           /**< package device profile, element*/
index e138d14..175abf9 100644 (file)
@@ -110,7 +110,8 @@ typedef enum {
        PMINFO_PKGINFO_GET_AUTHOR = 0x0008,
        PMINFO_PKGINFO_GET_DESCRIPTION = 0x0010,
        PMINFO_PKGINFO_GET_PRIVILEGE = 0x0020,
-       PMINFO_PKGINFO_GET_ALL = 0x003F
+       PMINFO_PKGINFO_GET_APPDEFINED_PRIVILEGE = 0x0040,
+       PMINFO_PKGINFO_GET_ALL = 0x007F
 } pkgmgrinfo_pkginfo_get_option;
 
 /**
@@ -306,6 +307,23 @@ typedef int (*pkgmgrinfo_pkg_privilege_list_cb) (const char *privilege_name,
                                                        void *user_data);
 
 /**
+ * @fn int (*pkgmgrinfo_pkg_appdefined_privilege_list_cb) (const char *privilege_name, const char *license_path, void *user_data)
+ *
+ * @brief Specifies the type of function passed to pkgmgrinfo_pkginfo_foreach_appdefined_privilege()
+ *
+ * @param[in] privilege_name the name of the privilege
+ * @param[in] license_path the path of the license
+ * @param[in] user_data user data passed to pkgmgrinfo_pkginfo_foreach_appdefined_privilege()
+ *
+ * @return 0 if success, negative value(<0) if fail. Callback is not called if return value is negative.\n
+ *
+ * @see  pkgmgrinfo_pkginfo_foreach_appdefined_privilege()
+ */
+typedef int (*pkgmgrinfo_pkg_appdefined_privilege_list_cb) (const char *privilege_name,
+                                                       const char *license_path,
+                                                       void *user_data);
+
+/**
  * @fn int (*pkgmgrinfo_app_metadata_list_cb) (const char *metadata_key, const char *metadata_value, void *user_data)
  *
  * @brief Specifies the type of function passed to pkgmgrinfo_appinfo_foreach_metadata()
index 5934d63..a2bda79 100644 (file)
       <xs:sequence>
         <xs:choice maxOccurs="unbounded" minOccurs="0">
           <xs:element ref="packages:privilege"/>
+          <xs:element ref="packages:appdefined-privilege"/>
         </xs:choice>
       </xs:sequence>
     </xs:complexType>
       <xs:attribute name="type" type="xs:string"/>
     </xs:complexType>
   </xs:element>
+  <xs:element name="provides-appdefined-privileges">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:choice maxOccurs="unbounded" minOccurs="0">
+          <xs:element ref="packages:appdefined-privilege"/>
+        </xs:choice>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="appdefined-privilege">
+    <xs:complexType mixed="true">
+      <xs:attribute name="type" type="xs:string"/>
+      <xs:attribute name="license" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
   <xs:element name="font">
   </xs:element>
   <xs:element name="label">
index e894a76..a5eaa8e 100644 (file)
       <xs:sequence>
         <xs:choice maxOccurs="unbounded" minOccurs="0">
           <xs:element ref="packages:privilege"/>
+          <xs:element ref="packages:appdefined-privilege"/>
         </xs:choice>
       </xs:sequence>
     </xs:complexType>
       <xs:attribute name="type" type="PrivilegeType"/>
     </xs:complexType>
   </xs:element>
+  <xs:element name="provides-appdefined-privileges">
+    <xs:complexType>
+      <xs:sequence>
+        <xs:choice maxOccurs="unbounded" minOccurs="0">
+          <xs:element ref="packages:appdefined-privilege"/>
+        </xs:choice>
+      </xs:sequence>
+    </xs:complexType>
+  </xs:element>
+  <xs:element name="appdefined-privilege">
+    <xs:complexType mixed="true">
+      <xs:attribute name="type" type="PrivilegeType"/>
+      <xs:attribute name="license" type="xs:string"/>
+    </xs:complexType>
+  </xs:element>
   <xs:element name="font">
   </xs:element>
   <xs:element name="label">
index 5a079b9..0163fae 100644 (file)
@@ -298,6 +298,7 @@ static const char *parser_init_queries[] = {
        QUERY_CREATE_TABLE_PACKAGE_INFO,
        QUERY_CREATE_TABLE_PACKAGE_LOCALIZED_INFO,
        QUERY_CREATE_TABLE_PACKAGE_PRIVILEGE_INFO,
+       QUERY_CREATE_TABLE_PACKAGE_APPDEFINED_PRIVILEGE_INFO,
        QUERY_CREATE_TABLE_PACKAGE_UPDATE_INFO,
        QUERY_CREATE_TABLE_PACKAGE_APP_INFO,
        QUERY_CREATE_TABLE_PACKAGE_APP_LOCALIZED_INFO,
@@ -1560,6 +1561,50 @@ static int __insert_package_privilege_info(sqlite3 *db, manifest_x *mfx)
        return 0;
 }
 
+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;
+}
+
 /* _PRODUCT_LAUNCHING_ENHANCED_
  *  app->indicatordisplay, app->portraitimg, app->landscapeimg,
  *  app->guestmode_appstatus
@@ -1896,6 +1941,8 @@ static int __insert_package_info(sqlite3 *db, manifest_x *mfx)
                return -1;
        if (__insert_package_privilege_info(db, mfx))
                return -1;
+       if (__insert_package_appdefined_privilege_info(db, mfx))
+               return -1;
 
        return 0;
 }
index b0051a0..924f8ac 100644 (file)
        "  FOREIGN KEY(package)\n" \
        "  REFERENCES package_info(package) ON DELETE CASCADE)"
 
+#define QUERY_CREATE_TABLE_PACKAGE_APPDEFINED_PRIVILEGE_INFO \
+       "CREATE TABLE IF NOT EXISTS package_appdefined_privilege_info (\n" \
+       "  package TEXT NOT NULL,\n" \
+       "  privilege TEXT NOT NULL,\n" \
+       "  license TEXT,\n" \
+       "  type TEXT NOT NULL,\n" \
+       "  PRIMARY KEY(package, privilege, type)\n" \
+       "  FOREIGN KEY(package)\n" \
+       "  REFERENCES package_info(package) ON DELETE CASCADE)"
+
 #define QUERY_CREATE_TABLE_PACKAGE_UPDATE_INFO \
        "CREATE TABLE IF NOT EXISTS package_update_info (\n" \
        "  package TEXT NOT NULL,\n" \
index f18a359..7724e87 100644 (file)
@@ -221,6 +221,20 @@ static void __ps_free_privilege(gpointer data)
        free((void *)privilege);
 }
 
+static void __ps_free_appdefined_privilege(gpointer data)
+{
+       appdefined_privilege_x *privilege = (appdefined_privilege_x *)data;
+       if (privilege == NULL)
+               return;
+       if (privilege->type)
+               free((void *)privilege->type);
+       if (privilege->value)
+               free((void *)privilege->value);
+       if (privilege->license)
+               free((void *)privilege->license);
+       free((void *)privilege);
+}
+
 static void __ps_free_datacontrol(gpointer data)
 {
        datacontrol_x *datacontrol = (datacontrol_x *)data;
@@ -450,6 +464,12 @@ API void pkgmgrinfo_basic_free_package(package_x *package)
        g_list_free_full(package->license, __ps_free_license);
        /*Free Privileges*/
        g_list_free_full(package->privileges, __ps_free_privilege);
+       /*Free AppDefined Privileges*/
+       g_list_free_full(package->appdefined_privileges,
+               __ps_free_appdefined_privilege);
+       /*Free Providing AppDefined Privileges*/
+       g_list_free_full(package->provides_appdefined_privileges,
+               __ps_free_appdefined_privilege);
        /*Free Application*/
        g_list_free_full(package->application, __ps_free_application);
        /*Free Compatibility*/
index f468368..fc19d5c 100644 (file)
@@ -301,6 +301,7 @@ static const char *parserdb_tables[] = {
        "package_app_data_control",
        "package_localized_info",
        "package_privilege_info",
+       "package_appdefined_privilege_info",
        "package_app_data_control_privilege",
        NULL
 };
index 1ddc766..98c5d89 100644 (file)
@@ -219,6 +219,49 @@ static int _pkginfo_get_privilege(sqlite3 *db, const char *pkgid,
        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");
+                       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_append(*privileges,
+                               (gpointer)privilege);
+       }
+
+       sqlite3_finalize(stmt);
+
+       return PMINFO_R_OK;
+}
+
 static const char join_localized_info[] =
        " LEFT OUTER JOIN package_localized_info"
        "  ON pi.package=package_localized_info.package"
@@ -527,6 +570,14 @@ static int _pkginfo_get_packages(uid_t uid, const char *locale,
                        }
                }
 
+               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 (is_check_storage &&
                                __pkginfo_check_installed_storage(info) != PMINFO_R_OK) {
                        ret = PMINFO_R_ERROR;
@@ -1901,6 +1952,35 @@ API int pkgmgrinfo_pkginfo_foreach_privilege(pkgmgrinfo_pkginfo_h handle,
        return PMINFO_R_OK;
 }
 
+API int pkgmgrinfo_pkginfo_foreach_appdefined_privilege(
+               pkgmgrinfo_pkginfo_h handle,
+               pkgmgrinfo_pkg_appdefined_privilege_list_cb privilege_func,
+               void *user_data)
+{
+       retvm_if(handle == NULL, PMINFO_R_EINVAL, "pkginfo handle is NULL");
+       retvm_if(privilege_func == NULL, PMINFO_R_EINVAL,
+                       "Callback function is NULL");
+       int ret;
+       appdefined_privilege_x *privilege;
+       GList *tmp;
+       pkgmgr_pkginfo_x *info = (pkgmgr_pkginfo_x *)handle;
+
+       if (info->pkg_info == NULL)
+               return PMINFO_R_ERROR;
+
+       for (tmp = info->pkg_info->appdefined_privileges; tmp;
+                       tmp = tmp->next) {
+               privilege = (appdefined_privilege_x *)tmp->data;
+               if (privilege == NULL)
+                       continue;
+               ret = privilege_func(privilege->value, privilege->license,
+                               user_data);
+               if (ret < 0)
+                       break;
+       }
+       return PMINFO_R_OK;
+}
+
 int __compare_package_version(const char *version, int *major,
                int *minor, int *macro, int *nano)
 {