Implement remote appcontrol feature
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_appinfo.c
index da7d2ac..ed3ba9a 100644 (file)
@@ -160,6 +160,11 @@ static void __parse_appcontrol(GList **appcontrol, char *appcontrol_str)
                return;
 
        dup = strdup(appcontrol_str);
+       if (dup == NULL) {
+               _LOGE("out of memory");
+               return;
+       }
+
        do {
                ac = calloc(1, sizeof(appcontrol_x));
                if (ac == NULL) {
@@ -613,6 +618,8 @@ static int _appinfo_get_applications(uid_t db_uid, uid_t uid,
                                                strcasecmp(tmp_record, "false") == 0) {
                                        free(info->is_disabled);
                                        info->is_disabled = tmp_record;
+                               } else {
+                                       free(tmp_record);
                                }
                        }
                        tmp_record = NULL;
@@ -622,6 +629,8 @@ static int _appinfo_get_applications(uid_t db_uid, uid_t uid,
                                                strcasecmp(tmp_record, "false") == 0) {
                                        free(info->splash_screen_display);
                                        info->splash_screen_display = tmp_record;
+                               } else {
+                                       free(tmp_record);
                                }
                        }
                }
@@ -721,7 +730,8 @@ static int _pkgmgrinfo_get_appinfo(const char *appid, uid_t uid,
        if (locale == NULL)
                return PMINFO_R_ERROR;
 
-       list = g_hash_table_new(g_str_hash, g_str_equal);
+       list = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
+                       __free_applications);
        if (list == NULL) {
                free(locale);
                return PMINFO_R_ERROR;
@@ -760,6 +770,7 @@ static int _pkgmgrinfo_get_appinfo(const char *appid, uid_t uid,
        info->package = strdup(info->app_info->package);
 
        /* just free list only */
+       g_hash_table_steal(list, (gconstpointer)appid);
        g_hash_table_destroy(list);
 
        *handle = info;
@@ -2685,14 +2696,19 @@ API int pkgmgrinfo_appinfo_foreach_metadata(pkgmgrinfo_appinfo_h handle,
 }
 
 static int _appinfo_foreach_appcontrol_privileges(sqlite3 *db,
-               const char *appid, const char *app_control,
+               const char *appid, const char *operation,
                pkgmgrinfo_pkg_privilege_list_cb callback, void *user_data)
 {
        static const char query[] =
-               "SELECT privilege FROM package_app_app_control_privilege "
-               "WHERE app_id=? AND app_control=?";
+               "SELECT app_control, privilege FROM package_app_app_control_privilege "
+               "WHERE app_id=?";
        int ret;
        sqlite3_stmt *stmt;
+       const char *app_control;
+       char *dup_app_control;
+       char *token;
+       char *saveptr = NULL;
+       const char *privilege;
        int count = 0;
 
        ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
@@ -2708,19 +2724,26 @@ static int _appinfo_foreach_appcontrol_privileges(sqlite3 *db,
                return PMINFO_R_ERROR;
        }
 
-       ret = sqlite3_bind_text(stmt, 2, app_control, -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) {
-               count++;
-               ret = callback((const char *)sqlite3_column_text(stmt, 0),
-                               user_data);
-               if (ret < 0)
-                       break;
+               app_control = (const char *)sqlite3_column_text(stmt, 0);
+               if (!app_control)
+                       continue;
+
+               dup_app_control = strdup(app_control);
+               if (!dup_app_control)
+                       continue;
+
+               token = strtok_r(dup_app_control, "|", &saveptr);
+               if (token && !strcmp(token, operation)) {
+                       count++;
+                       privilege = (const char *)sqlite3_column_text(stmt, 1);
+                       ret = callback(privilege, user_data);
+                       if (ret < 0) {
+                               free(dup_app_control);
+                               break;
+                       }
+               }
+               free(dup_app_control);
        }
 
        sqlite3_finalize(stmt);
@@ -2729,7 +2752,7 @@ static int _appinfo_foreach_appcontrol_privileges(sqlite3 *db,
 }
 
 static int _pkgmgrinfo_appinfo_foreach_appcontrol_privileges(uid_t uid,
-               const char *appid, const char *app_control,
+               const char *appid, const char *operation,
                pkgmgrinfo_pkg_privilege_list_cb callback, void *user_data)
 {
        int ret;
@@ -2747,7 +2770,7 @@ static int _pkgmgrinfo_appinfo_foreach_appcontrol_privileges(uid_t uid,
                return PMINFO_R_ERROR;
        }
 
-       ret = _appinfo_foreach_appcontrol_privileges(db, appid, app_control,
+       ret = _appinfo_foreach_appcontrol_privileges(db, appid, operation,
                        callback, user_data);
        sqlite3_close_v2(db);
 
@@ -2755,26 +2778,22 @@ static int _pkgmgrinfo_appinfo_foreach_appcontrol_privileges(uid_t uid,
 }
 
 API int pkgmgrinfo_appinfo_usr_foreach_appcontrol_privileges(const char *appid,
-               const char *operation, const char *uri, const char *mime,
+               const char *operation,
                pkgmgrinfo_pkg_privilege_list_cb privilege_func,
                void *user_data, uid_t uid)
 {
        int ret;
-       char app_control[BUFSIZE];
 
        if (appid == NULL || operation == NULL || privilege_func == NULL) {
                LOGE("invalid parameter");
                return PMINFO_R_EINVAL;
        }
 
-       snprintf(app_control, sizeof(app_control), "%s|%s|%s", operation,
-                       uri ? uri : "NULL", mime ? mime : "NULL");
-
        ret = _pkgmgrinfo_appinfo_foreach_appcontrol_privileges(GLOBAL_USER,
-                       appid, app_control, privilege_func, user_data);
+                       appid, operation, privilege_func, user_data);
        if (ret == PMINFO_R_ENOENT && uid != GLOBAL_USER)
                ret = _pkgmgrinfo_appinfo_foreach_appcontrol_privileges(uid,
-                               appid, app_control, privilege_func, user_data);
+                               appid, operation, privilege_func, user_data);
 
        if (ret == PMINFO_R_ENOENT)
                ret = PMINFO_R_OK;
@@ -2783,13 +2802,12 @@ API int pkgmgrinfo_appinfo_usr_foreach_appcontrol_privileges(const char *appid,
 }
 
 API int pkgmgrinfo_appinfo_foreach_appcontrol_privileges(const char *appid,
-               const char *operation, const char *uri, const char *mime,
+               const char *operation,
                pkgmgrinfo_pkg_privilege_list_cb privilege_func,
                void *user_data)
 {
        return pkgmgrinfo_appinfo_usr_foreach_appcontrol_privileges(appid,
-                       operation, uri, mime, privilege_func, user_data,
-                       _getuid());
+                       operation, privilege_func, user_data, _getuid());
 }
 
 API int pkgmgrinfo_appinfo_foreach_appcontrol(pkgmgrinfo_appinfo_h handle,
@@ -2807,7 +2825,32 @@ API int pkgmgrinfo_appinfo_foreach_appcontrol(pkgmgrinfo_appinfo_h handle,
 
        for (tmp = info->app_info->appcontrol; tmp; tmp = tmp->next) {
                appcontrol = (appcontrol_x *)tmp->data;
-               if (appcontrol == NULL)
+               if (appcontrol == NULL || !strcasecmp(appcontrol->visibility, "remote-only"))
+                       continue;
+               ret = appcontrol_func(appcontrol->operation, appcontrol->uri, appcontrol->mime, user_data);
+               if (ret < 0)
+                       break;
+       }
+
+       return PMINFO_R_OK;
+}
+
+API int pkgmgrinfo_appinfo_foreach_remote_appcontrol(pkgmgrinfo_appinfo_h handle,
+                       pkgmgrinfo_app_control_list_cb appcontrol_func, void *user_data)
+{
+       retvm_if(handle == NULL, PMINFO_R_EINVAL, "appinfo handle is NULL");
+       retvm_if(appcontrol_func == NULL, PMINFO_R_EINVAL, "Callback function is NULL");
+       int ret;
+       pkgmgr_appinfo_x *info = (pkgmgr_appinfo_x *)handle;
+       appcontrol_x *appcontrol;
+       GList *tmp;
+
+       if (info->app_info == NULL)
+               return PMINFO_R_ERROR;
+
+       for (tmp = info->app_info->appcontrol; tmp; tmp = tmp->next) {
+               appcontrol = (appcontrol_x *)tmp->data;
+               if (appcontrol == NULL || !strcasecmp(appcontrol->visibility, "local-only"))
                        continue;
                ret = appcontrol_func(appcontrol->operation, appcontrol->uri, appcontrol->mime, user_data);
                if (ret < 0)