diff options
author | Inkyun Kil <inkyun.kil@samsung.com> | 2017-01-10 16:42:22 +0900 |
---|---|---|
committer | Inkyun Kil <inkyun.kil@samsung.com> | 2017-02-06 14:52:59 +0900 |
commit | 4259894fde81136eca754812738695dc6871fe74 (patch) | |
tree | 6e83440b844eb51951c21e5803bc01a3b84cbae5 /src | |
parent | 99befe4b26696342cca67bd2b3cbbebb3f6f2e84 (diff) | |
download | librua-4259894fde81136eca754812738695dc6871fe74.tar.gz librua-4259894fde81136eca754812738695dc6871fe74.tar.bz2 librua-4259894fde81136eca754812738695dc6871fe74.zip |
Add new api for subscribing db update callback
- To inform task-manager of updated rua list.
Change-Id: Ia7e8cb28221e21bd383a5171dd97dc2bf9b78737
Signed-off-by: Inkyun Kil <inkyun.kil@samsung.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/rua.c | 40 | ||||
-rw-r--r-- | src/rua_dbus.c | 224 | ||||
-rw-r--r-- | src/rua_internal.c | 15 |
3 files changed, 279 insertions, 0 deletions
@@ -24,6 +24,7 @@ #include "rua_internal.h" #include "rua.h" #include "db-schema.h" +#include "rua_dbus.h" int rua_add_history_for_uid(char *pkg_name, char *app_path, char *arg, uid_t uid) { @@ -172,6 +173,45 @@ int rua_history_load_db_for_uid(char ***table, int *nrows, int *ncols, uid_t uid return r; } +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()); +} + +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; +} + +int rua_unregister_update_cb(int callback_id) +{ + return rua_unregister_update_cb_for_uid(callback_id, getuid()); +} + +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_unload_db(char ***table) { if (*table) { diff --git a/src/rua_dbus.c b/src/rua_dbus.c new file mode 100644 index 0000000..132bb4a --- /dev/null +++ b/src/rua_dbus.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2017 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <glib.h> +#include <gio/gio.h> + +#include "rua.h" +#include "rua_dbus.h" + +#define RUA_INTERFACE "org.tizen.rua" +#define RUA_PATH "/org/tizen/rua" +#define RUA_SIGNAL_DATA_UPDATE "dataupdate" + +struct cb_data +{ + int callback_id; + rua_history_update_cb callback; + void *user_data; +}; + +static GDBusConnection *conn; +static guint s_id; + +static gint atomic_callback_id; +static GHashTable* callback_hash_table; + +static void __foreach_callback(gpointer key, gpointer value, + gpointer user_data); +static void __signal_handler(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data); +static void __rua_dbus_init(void); +static void __rua_dbus_exit(void); + +int rua_dbus_send_update_signal(update_type type) +{ + __rua_dbus_init(); + GError *err = NULL; + + if (g_dbus_connection_emit_signal(conn, + NULL, + RUA_PATH, + RUA_INTERFACE, + RUA_SIGNAL_DATA_UPDATE, + g_variant_new("(i)", type), + &err) == FALSE) { + LOGE("g_dbus_connection_emit_signal() is failed. %s", + err->message); + __rua_dbus_exit(); + return -1; + } + + if (g_dbus_connection_flush_sync(conn, NULL, &err) == FALSE) { + LOGE("g_dbus_connection_flush_sync() is failed. %s", + err->message); + __rua_dbus_exit(); + return -1; + } + + g_clear_error(&err); + + __rua_dbus_exit(); + + return 0; +} + +int rua_dbus_signal_subscribe(rua_history_update_cb callback, + void *user_data, int *callback_id) +{ + struct cb_data *cd = NULL; + + if (s_id == 0) { + __rua_dbus_init(); + + s_id = g_dbus_connection_signal_subscribe(conn, + NULL, + RUA_INTERFACE, + RUA_SIGNAL_DATA_UPDATE, + RUA_PATH, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + __signal_handler, + NULL, + NULL); + + if (s_id == 0) { + LOGE("g_dbus_connection_signal_subscribe() is failed."); + __rua_dbus_exit(); + return -1; + } + + if (!callback_hash_table) { + callback_hash_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, free); + if (!callback_hash_table) { + LOGE("out of memory : g_hash_table_new() is failed"); + __rua_dbus_exit(); + return -1; + } + } + } + + cd = (struct cb_data *)malloc(sizeof(struct cb_data)); + if (!cd) { + LOGE("out of memory : malloc() is failed"); + return -1; + } + + g_atomic_int_inc(&atomic_callback_id); + + cd->callback = callback; + cd->user_data = user_data; + cd->callback_id = atomic_callback_id; + + g_hash_table_insert(callback_hash_table, + GINT_TO_POINTER(cd->callback_id), (gpointer)cd); + + *callback_id = cd->callback_id; + + return 0; +} + +int rua_dbus_signal_unsubscribe(int callback_id) +{ + gboolean result = FALSE; + guint table_size = 0; + + result = g_hash_table_remove(callback_hash_table, GINT_TO_POINTER(callback_id)); + if (!result) { + LOGE("g_hash_table_remove failed(%d is wrong)", callback_id); + return -1; + } + + table_size = g_hash_table_size(callback_hash_table); + if (s_id && table_size == 0) { + g_dbus_connection_signal_unsubscribe(conn, s_id); + g_hash_table_destroy(callback_hash_table); + __rua_dbus_exit(); + callback_hash_table = NULL; + s_id = 0; + } + + return 0; +} + +static void __foreach_callback(gpointer key, gpointer value, + gpointer user_data) +{ + char **table = NULL; + int nrows = 0; + int ncols = 0; + int r = 0; + + struct cb_data *cd = (struct cb_data *)value; + + r = rua_history_load_db(&table, &nrows, &ncols); + if (r == -1) + return; + + if (cd->callback) { + cd->callback(table, nrows, ncols, cd->user_data); + } +} + +static void __signal_handler(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + int update_type; + + LOGI("__signal_handler"); + if (g_strcmp0(signal_name, RUA_SIGNAL_DATA_UPDATE)) + return; + + g_variant_get(parameters, "(i)", &update_type); + + g_hash_table_foreach(callback_hash_table, __foreach_callback, NULL); +} + +static void __rua_dbus_init(void) +{ + if (!conn) { + GError *err = NULL; + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + if (!conn) { + LOGE("g_bus_get_sync() is failed. %s", err->message); + g_error_free(err); + return; + } + } +} + +static void __rua_dbus_exit(void) +{ + if (conn) { + g_object_unref(conn); + conn = NULL; + } +} diff --git a/src/rua_internal.c b/src/rua_internal.c index 7995262..bc17818 100644 --- a/src/rua_internal.c +++ b/src/rua_internal.c @@ -20,6 +20,7 @@ #include "rua_internal.h" #include "db-schema.h" #include "rua_util.h" +#include "rua_dbus.h" static int __exec(sqlite3 *db, char *query) { @@ -120,6 +121,13 @@ int rua_usr_db_delete_history(bundle *b, uid_t uid) result = -1; } + r = rua_dbus_send_update_signal(DELETE); + if (r == -1) { + LOGE("[RUA SEND SIGNAL ERROR] \n"); + db_util_close(db); + return -1; + } + if (db != NULL) db_util_close(db); @@ -183,6 +191,13 @@ int rua_usr_db_add_history(struct rua_rec *rec, uid_t uid) return -1; } + r = rua_dbus_send_update_signal(ADD); + if (r == -1) { + LOGE("[RUA SEND SIGNAL ERROR] \n"); + db_util_close(db); + return -1; + } + db_util_close(db); return r; } |