summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorInkyun Kil <inkyun.kil@samsung.com>2017-01-10 16:42:22 +0900
committerInkyun Kil <inkyun.kil@samsung.com>2017-02-06 14:52:59 +0900
commit4259894fde81136eca754812738695dc6871fe74 (patch)
tree6e83440b844eb51951c21e5803bc01a3b84cbae5 /src
parent99befe4b26696342cca67bd2b3cbbebb3f6f2e84 (diff)
downloadlibrua-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.c40
-rw-r--r--src/rua_dbus.c224
-rw-r--r--src/rua_internal.c15
3 files changed, 279 insertions, 0 deletions
diff --git a/src/rua.c b/src/rua.c
index f8bab6a..6381870 100644
--- a/src/rua.c
+++ b/src/rua.c
@@ -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;
}