Fix memory leak
[platform/core/appfw/librua.git] / src / rua.c
index a893d24..527c66a 100644 (file)
--- a/src/rua.c
+++ b/src/rua.c
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <db-util.h>
+#include <unistd.h>
+
+#include <sqlite3.h>
 #include <aul.h>
+#include <dlog.h>
 
 #include "rua_util.h"
-#include "rua_internal.h"
 #include "rua.h"
 #include "db-schema.h"
+#include "rua_dbus.h"
+#include "rua_private.h"
 
-int rua_add_history_for_uid(char *pkg_name, char *app_path, char *arg, uid_t uid)
+API int rua_add_history_for_uid(char *pkg_name, char *app_path, char *arg, uid_t uid)
 {
        int r;
        char time_str[32] = {0,};
@@ -57,12 +61,7 @@ int rua_add_history_for_uid(char *pkg_name, char *app_path, char *arg, uid_t uid
        return r;
 }
 
-int rua_delete_history_with_pkgname(char *pkg_name)
-{
-       return rua_delete_history_with_pkgname_for_uid(pkg_name, getuid());
-}
-
-int rua_delete_history_with_pkgname_for_uid(char *pkg_name, uid_t uid)
+API int rua_delete_history_with_pkgname_for_uid(char *pkg_name, uid_t uid)
 {
        int r;
        bundle *b;
@@ -83,12 +82,12 @@ int rua_delete_history_with_pkgname_for_uid(char *pkg_name, uid_t uid)
        return r;
 }
 
-int rua_delete_history_with_apppath(char *app_path)
+API int rua_delete_history_with_pkgname(char *pkg_name)
 {
-       return rua_delete_history_with_apppath_for_uid(app_path, getuid());
+       return rua_delete_history_with_pkgname_for_uid(pkg_name, getuid());
 }
 
-int rua_delete_history_with_apppath_for_uid(char *app_path, uid_t uid)
+API int rua_delete_history_with_apppath_for_uid(char *app_path, uid_t uid)
 {
        int r;
        bundle *b;
@@ -109,12 +108,12 @@ int rua_delete_history_with_apppath_for_uid(char *app_path, uid_t uid)
        return r;
 }
 
-int rua_clear_history(void)
+API int rua_delete_history_with_apppath(char *app_path)
 {
-       return rua_clear_history_for_uid(getuid());
+       return rua_delete_history_with_apppath_for_uid(app_path, getuid());
 }
 
-int rua_clear_history_for_uid(uid_t uid)
+API int rua_clear_history_for_uid(uid_t uid)
 {
        int r;
 
@@ -127,25 +126,26 @@ int rua_clear_history_for_uid(uid_t uid)
        return r;
 }
 
-int rua_history_load_db(char ***table, int *nrows, int *ncols)
+API int rua_clear_history(void)
 {
-       return rua_history_load_db_for_uid(table, nrows, ncols, getuid());
+       return rua_clear_history_for_uid(getuid());
 }
 
-int rua_history_load_db_for_uid(char ***table, int *nrows, int *ncols, uid_t uid)
+API int rua_history_load_db_for_uid(char ***table, int *nrows, int *ncols, uid_t uid)
 {
+       static const char query[] = "SELECT "
+               "pkg_name, app_path, arg, launch_time, instance_id, "
+               "instance_name, icon, uri, image, comp_id "
+               "FROM rua_history ORDER BY launch_time DESC";
        int r;
-       char query[QUERY_MAXLEN];
        char *db_err = NULL;
        char **db_result = NULL;
        sqlite3 *db = NULL;
 
-       if (table == NULL)
-               return -1;
-       if (nrows == NULL)
-               return -1;
-       if (ncols == NULL)
+       if (table == NULL || nrows == NULL || ncols == NULL) {
+               LOGE("invalid parameter");
                return -1;
+       }
 
        r = _rua_util_check_uid(uid);
        if (r == -1)
@@ -155,32 +155,66 @@ int rua_history_load_db_for_uid(char ***table, int *nrows, int *ncols, uid_t uid
        if (r != SQLITE_OK)
                return -1;
 
-       snprintf(query, QUERY_MAXLEN,
-                "select pkg_name, app_path, arg, launch_time from %s order by launch_time desc;", RUA_HISTORY);
-
        r = sqlite3_get_table(db, query, &db_result, nrows, ncols, &db_err);
+       if (r != SQLITE_OK) {
+               LOGE("get table failed: %s", db_err);
+               sqlite3_free(db_err);
+               sqlite3_close_v2(db);
+               return -1;
+       }
 
-       if (r == SQLITE_OK)
-               *table = db_result;
-       else
-               sqlite3_free_table(db_result);
+       *table = db_result;
 
-       db_util_close(db);
+       sqlite3_close_v2(db);
 
        return r;
 }
 
-int rua_history_unload_db(char ***table)
+API int rua_history_load_db(char ***table, int *nrows, int *ncols)
 {
-       if (*table) {
-               sqlite3_free_table(*table);
-               *table = NULL;
-               return 0;
-       }
-       return -1;
+       return rua_history_load_db_for_uid(table, nrows, ncols, getuid());
+}
+
+API int rua_register_update_cb_for_uid(rua_history_update_cb callback, void *user_data, int *callback_id, uid_t uid)
+{
+       int r;
+
+       if (callback == NULL)
+               return -1;
+
+       r = _rua_util_check_uid(uid);
+       if (r == -1)
+               return r;
+
+       r = rua_dbus_signal_subscribe(callback, user_data, callback_id);
+
+       return r;
+}
+
+API int rua_register_update_cb(rua_history_update_cb callback, void *user_data, int *callback_id)
+{
+       return rua_register_update_cb_for_uid(callback, user_data, callback_id, getuid());
+}
+
+API int rua_unregister_update_cb_for_uid(int callback_id, uid_t uid)
+{
+       int r;
+
+       r = _rua_util_check_uid(uid);
+       if (r == -1)
+               return r;
+
+       r = rua_dbus_signal_unsubscribe(callback_id);
+
+       return r;
 }
 
-int rua_history_get_rec(struct rua_rec *rec, char **table, int nrows, int ncols,
+API int rua_unregister_update_cb(int callback_id)
+{
+       return rua_unregister_update_cb_for_uid(callback_id, getuid());
+}
+
+API int rua_history_get_rec(struct rua_rec *rec, char **table, int nrows, int ncols,
                        int row)
 {
        char **db_result = NULL;
@@ -196,10 +230,11 @@ int rua_history_get_rec(struct rua_rec *rec, char **table, int nrows, int ncols,
        db_result = table + ((row + 1) * ncols);
 
        tmp = db_result[RUA_COL_PKGNAME];
-       if (tmp)
+       if (tmp) {
                rec->pkg_name = tmp;
+               LOGI("get rec pkg_name %s", rec->pkg_name);
+       }
 
-       LOGI("get rec pkg_name %s", rec->pkg_name);
        tmp = db_result[RUA_COL_APPPATH];
        if (tmp)
                rec->app_path = tmp;
@@ -212,21 +247,70 @@ int rua_history_get_rec(struct rua_rec *rec, char **table, int nrows, int ncols,
        if (tmp)
                rec->launch_time = atoi(tmp);
 
+       tmp = db_result[RUA_COL_COMP_ID];
+       if (tmp && tmp[0] != '\0')
+               rec->comp_id = tmp;
+       else
+               rec->comp_id = NULL;
+
+       tmp = db_result[RUA_COL_INSTANCE_ID];
+       if (tmp && tmp[0] != '\0')
+               rec->instance_id = tmp;
+       else
+               rec->instance_id = NULL;
+
+       tmp = db_result[RUA_COL_INSTANCE_NAME];
+       if (tmp && tmp[0] != '\0')
+               rec->instance_name = tmp;
+       else
+               rec->instance_name = NULL;
+
+       tmp = db_result[RUA_COL_ICON];
+       if (tmp && tmp[0] != '\0')
+               rec->icon = tmp;
+       else
+               rec->icon = NULL;
+
+       tmp = db_result[RUA_COL_URI];
+       if (tmp && tmp[0] != '\0')
+               rec->uri = tmp;
+       else
+               rec->uri = NULL;
+
+       tmp = db_result[RUA_COL_IMAGE];
+       if (tmp && tmp[0] != '\0')
+               rec->image = tmp;
+       else
+               rec->image = NULL;
+
+       tmp = db_result[RUA_COL_COMP_ID];
+       if (tmp && tmp[0] != '\0')
+               rec->comp_id = tmp;
+       else
+               rec->comp_id = NULL;
+
        return 0;
 }
 
-int rua_is_latest_app(const char *pkg_name)
+API int rua_history_unload_db(char ***table)
 {
-       return rua_is_latest_app_for_uid(pkg_name, getuid());
+       if (*table) {
+               sqlite3_free_table(*table);
+               *table = NULL;
+               return 0;
+       }
+       return -1;
 }
 
-int rua_is_latest_app_for_uid(const char *pkg_name, uid_t uid)
+API int rua_is_latest_app_for_uid(const char *pkg_name, uid_t uid)
 {
+       static const char query[] =
+               "SELECT pkg_name FROM rua_history "
+               "ORDER BY launch_time DESC LIMIT 1";
        int r = -1;
        sqlite3_stmt *stmt;
        const unsigned char *ct;
        sqlite3 *db = NULL;
-       char *query = "select pkg_name from rua_history order by launch_time desc limit 1;";
 
        if (!pkg_name)
                return -1;
@@ -239,41 +323,77 @@ int rua_is_latest_app_for_uid(const char *pkg_name, uid_t uid)
        if (r != SQLITE_OK)
                return -1;
 
-       r = sqlite3_prepare(db, query, sizeof(query), &stmt, NULL);
+       r = sqlite3_prepare(db, query, strlen(query), &stmt, NULL);
        if (r != SQLITE_OK) {
-               db_util_close(db);
+               sqlite3_close_v2(db);
                return -1;
        }
 
        r = sqlite3_step(stmt);
-       if (r == SQLITE_ROW) {
-               ct = sqlite3_column_text(stmt, 0);
-               if (ct == NULL || ct[0] == '\0') {
-                       r = -1;
-                       goto out;
-               }
-
-               if (strncmp(pkg_name, (const char *)ct, strlen(pkg_name)) == 0) {
-                       r = 0;
-                       goto out;
-               }
+       if (r != SQLITE_ROW) {
+               if (r != SQLITE_DONE)
+                       LOGE("step failed: %s", sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               sqlite3_close_v2(db);
+               return -1;
        }
 
-out:
-       if (stmt)
-               sqlite3_finalize(stmt);
-       if (db)
-               db_util_close(db);
+       ct = sqlite3_column_text(stmt, 0);
+       if (ct == NULL || ct[0] == '\0')
+               r = -1;
+       else if (strncmp(pkg_name, (const char *)ct, strlen(pkg_name)) == 0)
+               r = 0;
+       else
+               r = -1;
+
+       sqlite3_finalize(stmt);
+       sqlite3_close_v2(db);
 
        return r;
 }
 
-int rua_init(void)
+API int rua_is_latest_app(const char *pkg_name)
+{
+       return rua_is_latest_app_for_uid(pkg_name, getuid());
+}
+
+API int rua_init(void)
 {
        return 0;
 }
 
-int rua_fini(void)
+API int rua_fini(void)
 {
        return 0;
 }
+
+API int rua_delete_history_with_instance_id(const char *app_id,
+               const char *instance_id)
+{
+       int ret;
+       bundle *b;
+
+       if (app_id == NULL) {
+               LOGE("Invalid parameter");
+               return -1;
+       }
+
+       b = bundle_create();
+       if (b == NULL) {
+               LOGE("Out of memory");
+               return -1;
+       }
+
+       bundle_add_str(b, AUL_K_RUA_PKGNAME, app_id);
+       if (instance_id)
+               bundle_add_str(b, AUL_K_RUA_INSTANCE_ID, instance_id);
+
+       ret = aul_delete_rua_history_for_uid(b, getuid());
+       bundle_free(b);
+       if (ret < 0) {
+               LOGE("Failed to delete rua history - result(%d)", ret);
+               return -1;
+       }
+
+       return 0;
+}