summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryoungsub ko <ys4610.ko@samsung.com>2013-05-02 15:16:25 +0900
committeryoungsub ko <ys4610.ko@samsung.com>2013-05-02 15:17:00 +0900
commit75175ca407bf56b48da2429467ef52e1e4c09f02 (patch)
tree884edb96b79580d27768486a9b78a24bf6ca5808
parent615c3d94eacc87cb6a174e95b670ff9f7eb22ac6 (diff)
downloadbadge-75175ca407bf56b48da2429467ef52e1e4c09f02.tar.gz
badge-75175ca407bf56b48da2429467ef52e1e4c09f02.tar.bz2
badge-75175ca407bf56b48da2429467ef52e1e4c09f02.zip
sync with private git
Change-Id: I28369e921ae9d208cdcafbf1c06751ce23ecd6ba
-rwxr-xr-x[-rw-r--r--]CMakeLists.txt5
-rwxr-xr-xinclude/badge.h9
-rwxr-xr-xinclude/badge_db.h44
-rwxr-xr-xinclude/badge_error.h2
-rwxr-xr-xinclude/badge_internal.h3
-rwxr-xr-xinclude/badge_ipc.h50
-rwxr-xr-xpackaging/badge.spec6
-rwxr-xr-xsrc/badge.c74
-rwxr-xr-xsrc/badge_db.c99
-rwxr-xr-xsrc/badge_internal.c206
-rwxr-xr-xsrc/badge_ipc.c620
11 files changed, 882 insertions, 236 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3ae54f2..71d3088 100644..100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,11 +16,14 @@ SET(CMAKE_SKIP_BUILD_RPATH true)
SET(INSTALL_HEADERS
badge.h
+ badge_db.h
badge_error.h
)
SET(SRCS
src/badge.c
+ src/badge_db.c
+ src/badge_ipc.c
src/badge_internal.c
)
@@ -35,6 +38,8 @@ pkg_check_modules(pkgs REQUIRED
dlog
dbus-1
dbus-glib-1
+ vconf
+ com-core
)
FOREACH(flag ${pkgs_CFLAGS})
diff --git a/include/badge.h b/include/badge.h
index f2d5d93..0abd8eb 100755
--- a/include/badge.h
+++ b/include/badge.h
@@ -54,6 +54,7 @@ enum _badge_action {
BADGE_ACTION_REMOVE,
BADGE_ACTION_UPDATE,
BADGE_ACTION_CHANGED_DISPLAY,
+ BADGE_ACTION_SERVICE_READY,
};
@@ -297,6 +298,14 @@ badge_error_e badge_register_changed_cb(badge_change_cb callback, void *data);
*/
badge_error_e badge_unregister_changed_cb(badge_change_cb callback);
+int badge_is_service_ready(void);
+
+badge_error_e badge_add_deffered_task(
+ void (*deffered_task_cb)(void *data), void *user_data);
+
+badge_error_e badge_del_deffered_task(
+ void (*deffered_task_cb)(void *data));
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/include/badge_db.h b/include/badge_db.h
new file mode 100755
index 0000000..ce593f9
--- /dev/null
+++ b/include/badge_db.h
@@ -0,0 +1,44 @@
+/*
+ * libbadge
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjoo Park <yjoo93.park@samsung.com>,
+ * Seungtaek Chung <seungtaek.chung@samsung.com>, Youngsub Ko <ys4610.ko@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+
+#ifndef __BADGE_DB_DEF_H__
+#define __BADGE_DB_DEF_H__
+
+#include <stdbool.h>
+#include <badge_error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+badge_error_e badge_db_insert(const char *pkgname, const char *writable_pkg, const char *caller);
+badge_error_e badge_db_delete(const char *pkgname, const char *caller_pkg);
+badge_error_e badge_db_set_count(const char *pkgname, const char *caller_pkg, int count);
+badge_error_e badge_db_set_display_option(const char *pkgname, const char *caller_pkg, int is_display);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* __BADGE_DB_DEF_H__ */
+
diff --git a/include/badge_error.h b/include/badge_error.h
index ea28aa1..405933a 100755
--- a/include/badge_error.h
+++ b/include/badge_error.h
@@ -51,6 +51,8 @@ typedef enum _badge_error_e {
BADGE_ERROR_FROM_DBUS = -5, /**< Error from DBus */
BADGE_ERROR_NOT_EXIST = -6, /**< Not exist */
BADGE_ERROR_PERMISSION_DENIED = -7, /**< Permission denied */
+ BADGE_ERROR_IO = -8, /**< Error from I/O */
+ BADGE_ERROR_SERVICE_NOT_READY = -9, /**< Error service not ready */
} badge_error_e;
#ifdef __cplusplus
diff --git a/include/badge_internal.h b/include/badge_internal.h
index 4c62d7b..d3b6681 100755
--- a/include/badge_internal.h
+++ b/include/badge_internal.h
@@ -69,5 +69,8 @@ char *_badge_pkgs_new(badge_error_e *err, const char *pkg1, ...);
char *_badge_pkgs_new_valist(badge_error_e *err,
const char *pkg1, va_list args);
+void badge_changed_cb_call(unsigned int action, const char *pkgname,
+ unsigned int count);
+
#endif /* __BADGE_INTERNAL_DEF_H__ */
diff --git a/include/badge_ipc.h b/include/badge_ipc.h
new file mode 100755
index 0000000..8c96026
--- /dev/null
+++ b/include/badge_ipc.h
@@ -0,0 +1,50 @@
+/*
+ * libnotification
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungtaek Chung <seungtaek.chung@samsung.com>, Mi-Ju Lee <miju52.lee@samsung.com>, Xi Zhichan <zhichan.xi@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __BADGE_IPC_H__
+#define __BADGE_IPC_H__
+
+#include <badge.h>
+
+#define BADGE_ADDR "/tmp/.badge.service"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct packet;
+
+badge_error_e badge_ipc_monitor_init(void);
+badge_error_e badge_ipc_monitor_fini(void);
+
+badge_error_e badge_ipc_request_insert(const char *pkgname, const char *writable_pkg, const char *caller);
+badge_error_e badge_ipc_request_delete(const char *pkgname, const char *caller);
+badge_error_e badge_ipc_request_set_count(const char *pkgname, const char *caller, int count);
+badge_error_e badge_ipc_request_set_display(const char *pkgname, const char *caller, int display_option);
+
+int badge_ipc_is_master_ready(void);
+badge_error_e badge_ipc_add_deffered_task(void (*deffered_task_cb)(void *data), void *user_data);
+badge_error_e badge_ipc_del_deffered_task(void (*deffered_task_cb)(void *data));
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/packaging/badge.spec b/packaging/badge.spec
index 9aa4b0d..6c8f831 100755
--- a/packaging/badge.spec
+++ b/packaging/badge.spec
@@ -1,8 +1,8 @@
%define DBDIR "/opt/dbspace"
Name: badge
Summary: badge library
-Version: 0.0.2
-Release: 2
+Version: 0.0.4
+Release: 1
Group: TBD
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
@@ -10,6 +10,8 @@ BuildRequires: pkgconfig(aul)
BuildRequires: pkgconfig(dbus-1)
BuildRequires: pkgconfig(dbus-glib-1)
BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(com-core)
BuildRequires: cmake
Requires(post): /sbin/ldconfig
requires(postun): /sbin/ldconfig
diff --git a/src/badge.c b/src/badge.c
index d5c7efc..4350b68 100755
--- a/src/badge.c
+++ b/src/badge.c
@@ -27,45 +27,23 @@
#include "badge_log.h"
#include "badge_error.h"
#include "badge_internal.h"
+#include "badge_ipc.h"
EXPORT_API
badge_error_e badge_create(const char *pkgname, const char *writable_pkg)
{
+ char *caller = NULL;
badge_error_e err = BADGE_ERROR_NONE;
- badge_h *badge = NULL;
- char *pkgs = NULL;
-
- if (!pkgname) {
- WARN("package name is NULL");
- return BADGE_ERROR_INVALID_DATA;
- }
-
- pkgs = _badge_pkgs_new(&err, writable_pkg, NULL);
- if (!pkgs) {
- ERR("fail to _badge_pkgs_new : %d", err);
- return err;
- }
-
- INFO("pkgs : %s", pkgs);
-
- badge = _badge_new(pkgname, pkgs, &err);
- if (!badge) {
- ERR("fail to _badge_new : %d", err);
- free(pkgs);
- return err;
- }
- free(pkgs);
- err = _badge_insert(badge);
- if (err != BADGE_ERROR_NONE) {
- ERR("fail to _badge_insert : %d", err);
- _badge_free(badge);
- return err;
+ caller = _badge_get_pkgname_by_pid();
+ if (!caller) {
+ ERR("fail to get caller pkgname");
+ return BADGE_ERROR_PERMISSION_DENIED;
}
- _badge_free(badge);
+ err = badge_ipc_request_insert(pkgname, writable_pkg, caller);
- return BADGE_ERROR_NONE;
+ return err;
}
EXPORT_API
@@ -78,11 +56,9 @@ badge_error_e badge_remove(const char *pkgname)
if (!caller) {
ERR("fail to get caller pkgname");
return BADGE_ERROR_PERMISSION_DENIED;
-
}
- result = _badge_remove(caller, pkgname);
- free(caller);
+ result = badge_ipc_request_delete(pkgname, caller);
return result;
}
@@ -112,9 +88,7 @@ badge_error_e badge_set_count(const char *pkgname, unsigned int count)
return BADGE_ERROR_PERMISSION_DENIED;
}
- result = _badget_set_count(caller, pkgname, count);
-
- free(caller);
+ result = badge_ipc_request_set_count(pkgname, caller, count);
return result;
}
@@ -128,9 +102,16 @@ badge_error_e badge_get_count(const char *pkgname, unsigned int *count)
EXPORT_API
badge_error_e badge_set_display(const char *pkgname, unsigned int is_display)
{
+ char *caller = NULL;
badge_error_e result = BADGE_ERROR_NONE;
- result = _badget_set_display(pkgname, is_display);
+ caller = _badge_get_pkgname_by_pid();
+ if (!caller) {
+ ERR("fail to get caller pkgname");
+ return BADGE_ERROR_PERMISSION_DENIED;
+ }
+
+ result = badge_ipc_request_set_display(pkgname, caller, is_display);
return result;
}
@@ -153,3 +134,22 @@ badge_error_e badge_unregister_changed_cb(badge_change_cb callback)
return _badge_unregister_changed_cb(callback);
}
+EXPORT_API
+int badge_is_service_ready(void)
+{
+ return badge_ipc_is_master_ready();
+}
+
+EXPORT_API
+badge_error_e badge_add_deffered_task(
+ void (*deffered_task_cb)(void *data), void *user_data)
+{
+ return badge_ipc_add_deffered_task(deffered_task_cb, user_data);
+}
+
+EXPORT_API
+badge_error_e badge_del_deffered_task(
+ void (*deffered_task_cb)(void *data))
+{
+ return badge_ipc_del_deffered_task(deffered_task_cb);
+}
diff --git a/src/badge_db.c b/src/badge_db.c
new file mode 100755
index 0000000..4246cef
--- /dev/null
+++ b/src/badge_db.c
@@ -0,0 +1,99 @@
+/*
+ * libbadge
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjoo Park <yjoo93.park@samsung.com>,
+ * Seungtaek Chung <seungtaek.chung@samsung.com>, Youngsub Ko <ys4610.ko@samsung.com>
+ *
+ * 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 <stdlib.h>
+#include <stdarg.h>
+
+#include "badge.h"
+#include "badge_log.h"
+#include "badge_error.h"
+#include "badge_internal.h"
+
+EXPORT_API
+badge_error_e badge_db_insert(const char *pkgname, const char *writable_pkg, const char *caller)
+{
+ badge_error_e err = BADGE_ERROR_NONE;
+ badge_h *badge = NULL;
+ char *pkgs = NULL;
+
+ if (!pkgname) {
+ WARN("package name is NULL");
+ return BADGE_ERROR_INVALID_DATA;
+ }
+
+ pkgs = _badge_pkgs_new(&err, writable_pkg, caller, NULL);
+ if (!pkgs) {
+ ERR("fail to _badge_pkgs_new : %d", err);
+ return err;
+ }
+
+ INFO("pkgs : %s", pkgs);
+
+ badge = _badge_new(pkgname, pkgs, &err);
+ if (!badge) {
+ ERR("fail to _badge_new : %d", err);
+ free(pkgs);
+ return err;
+ }
+ free(pkgs);
+
+ err = _badge_insert(badge);
+ if (err != BADGE_ERROR_NONE) {
+ ERR("fail to _badge_insert : %d", err);
+ _badge_free(badge);
+ return err;
+ }
+
+ _badge_free(badge);
+
+ return BADGE_ERROR_NONE;
+}
+
+EXPORT_API
+badge_error_e badge_db_delete(const char *pkgname, const char *caller)
+{
+ badge_error_e result = BADGE_ERROR_NONE;
+
+ result = _badge_remove(caller, pkgname);
+
+ return result;
+}
+
+EXPORT_API
+badge_error_e badge_db_set_count(const char *pkgname, const char *caller, int count)
+{
+ badge_error_e result = BADGE_ERROR_NONE;
+
+ result = _badget_set_count(caller, pkgname, count);
+
+ return result;
+}
+
+EXPORT_API
+badge_error_e badge_db_set_display_option(const char *pkgname, const char *caller, int is_display)
+{
+ badge_error_e result = BADGE_ERROR_NONE;
+
+ result = _badget_set_display(pkgname, is_display);
+
+ return result;
+}
diff --git a/src/badge_internal.c b/src/badge_internal.c
index bacedd2..83155a2 100755
--- a/src/badge_internal.c
+++ b/src/badge_internal.c
@@ -35,15 +35,13 @@
#include "badge_log.h"
#include "badge_error.h"
#include "badge_internal.h"
+#include "badge_ipc.h"
#define BADGE_PKGNAME_LEN 512
#define BADGE_TABLE_NAME "badge_data"
#define BADGE_OPTION_TABLE_NAME "badge_option"
#define BADGE_CHANGED_NOTI "badge_changed"
-#define BADGE_DBUS_BUS_NAME "org.tizen.libbadge"
-#define BADGE_DBUS_PATH "/org/tizen/libbadge"
-#define BADGE_DBUS_INTERFACE "org.tizen.libbadge.signal"
struct _badge_h {
char *pkgname;
@@ -56,7 +54,6 @@ struct _badge_cb_data {
};
static GList *g_badge_cb_list;
-static DBusConnection *g_badge_cb_handle;
static inline long _get_max_len(void)
{
@@ -114,65 +111,6 @@ char *_badge_get_pkgname_by_pid(void)
return pkgname;
}
-
-static void _badge_changed(unsigned int action, const char *pkgname,
- unsigned int count)
-{
- DBusConnection *connection = NULL;
- DBusMessage *message = NULL;
- DBusError err;
- dbus_bool_t ret;
-
- if (!pkgname) {
- ERR("pkgname is NULL");
- return;
- }
-
- dbus_error_init(&err);
- connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
- if (!connection) {
- ERR("Fail to dbus_bus_get : %s", err.message);
- dbus_error_free(&err);
- return;
- }
-
- message = dbus_message_new_signal(BADGE_DBUS_PATH,
- BADGE_DBUS_INTERFACE,
- BADGE_CHANGED_NOTI);
-
- if (!message) {
- ERR("fail to create dbus message");
- goto release_n_return;
- }
-
- dbus_message_append_args(message,
- DBUS_TYPE_UINT32, &action,
- DBUS_TYPE_STRING, &pkgname,
- DBUS_TYPE_UINT32, &count,
- DBUS_TYPE_INVALID);
-
- ret = dbus_connection_send(connection, message, NULL);
- if (!ret) {
- ERR("fail to send dbus message : [%u][%s][%u]",
- action, pkgname, count);
- goto release_n_return;
- }
-
- dbus_connection_flush(connection);
-
- DBG("success to emit signal [%u][%s][%u]",
- action, pkgname, count);
-
-release_n_return:
- dbus_error_free(&err);
-
- if (message)
- dbus_message_unref(message);
-
- if (connection)
- dbus_connection_unref(connection);
-}
-
static badge_error_e _badge_check_data_inserted(const char *pkgname,
sqlite3 *db)
{
@@ -505,8 +443,6 @@ badge_error_e _badge_insert(badge_h *badge)
goto return_close_db;
}
- _badge_changed(BADGE_ACTION_CREATE, badge->pkgname, 0);
-
/* inserting badge options */
ret = _badge_check_option_inserted(badge->pkgname, db);
if (ret != BADGE_ERROR_NOT_EXIST) {
@@ -536,7 +472,7 @@ badge_error_e _badge_insert(badge_h *badge)
return_close_db:
if (err_msg)
- free(err_msg);
+ sqlite3_free(err_msg);
if (sqlbuf)
sqlite3_free(sqlbuf);
@@ -597,8 +533,6 @@ badge_error_e _badge_remove(const char *caller, const char *pkgname)
goto return_close_db;
}
- _badge_changed(BADGE_ACTION_REMOVE, pkgname, 0);
-
/* treating option table */
ret = _badge_check_option_inserted(pkgname, db);
if (ret != BADGE_ERROR_ALREADY_EXIST) {
@@ -624,7 +558,7 @@ badge_error_e _badge_remove(const char *caller, const char *pkgname)
return_close_db:
if (err_msg)
- free(err_msg);
+ sqlite3_free(err_msg);
if (sqlbuf)
sqlite3_free(sqlbuf);
@@ -687,11 +621,9 @@ badge_error_e _badget_set_count(const char *caller, const char *pkgname,
goto return_close_db;
}
- _badge_changed(BADGE_ACTION_UPDATE, pkgname, count);
-
return_close_db:
if (err_msg)
- free(err_msg);
+ sqlite3_free(err_msg);
if (sqlbuf)
sqlite3_free(sqlbuf);
@@ -833,11 +765,9 @@ badge_error_e _badget_set_display(const char *pkgname,
goto return_close_db;
}
- _badge_changed(BADGE_ACTION_CHANGED_DISPLAY, pkgname, is_display);
-
return_close_db:
if (err_msg)
- free(err_msg);
+ sqlite3_free(err_msg);
if (sqlbuf)
sqlite3_free(sqlbuf);
@@ -913,7 +843,7 @@ return_close_db:
return result;
}
-static void _badge_changed_cb_call(unsigned int action, const char *pkgname,
+void badge_changed_cb_call(unsigned int action, const char *pkgname,
unsigned int count)
{
GList *list = g_badge_cb_list;
@@ -930,131 +860,14 @@ static void _badge_changed_cb_call(unsigned int action, const char *pkgname,
}
}
-static DBusHandlerResult _badge_signal_filter(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
-{
- const char *interface;
- DBusError error;
- dbus_bool_t ret;
- unsigned int action = 0;
- const char *pkgname = NULL;
- unsigned int count = 0;
-
- dbus_error_init(&error);
-
- interface = dbus_message_get_interface(msg);
- DBG("path : %s", dbus_message_get_path(msg));
- DBG("interface : %s", interface);
-
- if (g_strcmp0(BADGE_DBUS_INTERFACE, interface))
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- ret = dbus_message_is_signal(msg, interface, BADGE_CHANGED_NOTI);
- if (!ret) {
- DBG("this msg is not signal");
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- ret = dbus_message_get_args(msg, &error,
- DBUS_TYPE_UINT32, &action,
- DBUS_TYPE_STRING, &pkgname,
- DBUS_TYPE_UINT32, &count,
- DBUS_TYPE_INVALID);
- if (!ret) {
- ERR("fail to get args : %s", error.message);
- dbus_error_free(&error);
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
-
- _badge_changed_cb_call(action, pkgname, count);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static inline void __bus_rule_get(char *buf, int buf_len)
-{
- if (!buf)
- return;
- if (buf_len <= 1)
- return;
-
- snprintf(buf, buf_len,
- "path='%s',type='signal',interface='%s',member='%s'",
- BADGE_DBUS_PATH,
- BADGE_DBUS_INTERFACE,
- BADGE_CHANGED_NOTI);
-}
-
static void _badge_changed_monitor_init()
{
- DBusError err;
- DBusConnection *conn = NULL;
- char rule[1024] = {'\0', };
-
- if (g_badge_cb_handle)
- return;
-
- dbus_error_init(&err);
- conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
- if (!conn) {
- ERR("fail to get bus : %s", err.message);
- dbus_error_free(&err);
- return;
- }
- dbus_connection_setup_with_g_main(conn, NULL);
-
- __bus_rule_get(rule, sizeof(rule));
-
- dbus_bus_add_match(conn, rule, &err);
- if (dbus_error_is_set(&err)) {
- ERR("fail to dbus_bus_remove_match : %s",
- err.message);
- dbus_error_free(&err);
- dbus_connection_close(conn);
- return;
- }
-
- if (dbus_connection_add_filter(conn, _badge_signal_filter,
- NULL, NULL) == FALSE) {
- ERR("fail to dbus_connection_add_filter : %s",
- err.message);
- dbus_error_free(&err);
- dbus_connection_close(conn);
- return;
- }
-
- dbus_connection_set_exit_on_disconnect(conn, FALSE);
-
- g_badge_cb_handle = conn;
-
- return;
+ badge_ipc_monitor_init();
}
static void _badge_chanaged_monitor_fini()
{
- DBusConnection *conn = g_badge_cb_handle;
- char rule[1024] = {'\0', };
- DBusError err;
-
- if (!conn)
- return;
-
- dbus_error_init(&err);
-
- dbus_connection_remove_filter(conn, _badge_signal_filter, NULL);
-
- __bus_rule_get(rule, sizeof(rule));
-
- dbus_bus_remove_match(conn, rule, &err);
- if (dbus_error_is_set(&err)) {
- ERR("fail to dbus_bus_remove_match : %s",
- err.message);
- dbus_error_free(&err);
- }
-
- dbus_connection_close(conn);
-
- g_badge_cb_handle = NULL;
+ badge_ipc_monitor_fini();
}
static gint _badge_data_compare(gconstpointer a, gconstpointer b)
@@ -1076,8 +889,7 @@ badge_error_e _badge_register_changed_cb(badge_change_cb callback, void *data)
struct _badge_cb_data *bd = NULL;
GList *found = NULL;
- if (!g_badge_cb_handle)
- _badge_changed_monitor_init();
+ _badge_changed_monitor_init();
found = g_list_find_custom(g_badge_cb_list, (gconstpointer)callback,
_badge_data_compare);
diff --git a/src/badge_ipc.c b/src/badge_ipc.c
new file mode 100755
index 0000000..c6db5ca
--- /dev/null
+++ b/src/badge_ipc.c
@@ -0,0 +1,620 @@
+/*
+ * libbadge
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjoo Park <yjoo93.park@samsung.com>,
+ * Seungtaek Chung <seungtaek.chung@samsung.com>, Youngsub Ko <ys4610.ko@samsung.com>
+ *
+ * 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 <stdlib.h>
+#include <stdarg.h>
+
+#include <vconf.h>
+
+#include <packet.h>
+#include <com-core.h>
+#include <com-core_packet.h>
+
+#include "badge.h"
+#include "badge_log.h"
+#include "badge_error.h"
+#include "badge_internal.h"
+#include "badge_ipc.h"
+
+#define BADGE_IPC_TIMEOUT 1.0
+
+#if !defined(VCONFKEY_MASTER_STARTED)
+#define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started"
+#endif
+
+static struct info {
+ int server_fd;
+ int client_fd;
+ const char *socket_file;
+ struct {
+ int (*request_cb)(const char *appid, const char *name, int type, const char *content, const char *icon, pid_t pid, double period, int allow_duplicate, void *data);
+ void *data;
+ } server_cb;
+ int initialized;
+ int is_started_cb_set_svc;
+ int is_started_cb_set_task;
+} s_info = {
+ .server_fd = -1,
+ .client_fd = -1,
+ .socket_file = BADGE_ADDR,
+ .initialized = 0,
+ .is_started_cb_set_svc = 0,
+ .is_started_cb_set_task = 0,
+};
+
+typedef struct _task_list task_list;
+struct _task_list {
+ task_list *prev;
+ task_list *next;
+
+ void (*task_cb) (void *data);
+ void *data;
+};
+
+static task_list *g_task_list;
+
+static badge_error_e badge_ipc_monitor_register(void);
+static badge_error_e badge_ipc_monitor_deregister(void);
+static void _do_deffered_task(void);
+static void _master_started_cb_task(keynode_t *node, void *data);
+
+/*!
+ * functions to check state of master
+ */
+static inline void _set_master_started_cb(vconf_callback_fn cb) {
+ int ret = -1;
+
+ ret = vconf_notify_key_changed(VCONFKEY_MASTER_STARTED,
+ cb, NULL);
+ if (ret != 0) {
+ ERR("failed to notify key(%s) : %d",
+ VCONFKEY_MASTER_STARTED, ret);
+ }
+}
+
+static inline void _unset_master_started_cb(vconf_callback_fn cb) {
+ int ret = -1;
+
+ ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED,
+ cb);
+ if (ret != 0) {
+ ERR("failed to notify key(%s) : %d",
+ VCONFKEY_MASTER_STARTED, ret);
+ }
+}
+
+int badge_ipc_is_master_ready(void)
+{
+ int ret = -1, is_master_started = 0;
+
+ ret = vconf_get_bool(VCONFKEY_MASTER_STARTED, &is_master_started);
+ if (ret == 0 && is_master_started == 1) {
+ ERR("the master has been started");
+ } else {
+ is_master_started = 0;
+ ERR("the master has been stopped");
+ }
+
+ return is_master_started;
+}
+
+badge_error_e
+badge_ipc_add_deffered_task(
+ void (*deffered_task_cb)(void *data),
+ void *user_data)
+{
+ task_list *list = NULL;
+ task_list *list_new = NULL;
+
+ list_new =
+ (task_list *) malloc(sizeof(task_list));
+
+ if (list_new == NULL) {
+ return BADGE_ERROR_NO_MEMORY;
+ }
+
+ if (s_info.is_started_cb_set_task == 0) {
+ _set_master_started_cb(_master_started_cb_task);
+ s_info.is_started_cb_set_task = 1;
+ }
+
+ list_new->next = NULL;
+ list_new->prev = NULL;
+
+ list_new->task_cb = deffered_task_cb;
+ list_new->data = user_data;
+
+ if (g_task_list == NULL) {
+ g_task_list = list_new;
+ } else {
+ list = g_task_list;
+
+ while (list->next != NULL) {
+ list = list->next;
+ }
+
+ list->next = list_new;
+ list_new->prev = list;
+ }
+ return BADGE_ERROR_NONE;
+}
+
+badge_error_e
+badge_ipc_del_deffered_task(
+ void (*deffered_task_cb)(void *data))
+{
+ task_list *list_del = NULL;
+ task_list *list_prev = NULL;
+ task_list *list_next = NULL;
+
+ list_del = g_task_list;
+
+ if (list_del == NULL) {
+ return BADGE_ERROR_INVALID_DATA;
+ }
+
+ while (list_del->prev != NULL) {
+ list_del = list_del->prev;
+ }
+
+ do {
+ if (list_del->task_cb == deffered_task_cb) {
+ list_prev = list_del->prev;
+ list_next = list_del->next;
+
+ if (list_prev == NULL) {
+ g_task_list = list_next;
+ } else {
+ list_prev->next = list_next;
+ }
+
+ if (list_next == NULL) {
+ if (list_prev != NULL) {
+ list_prev->next = NULL;
+ }
+ } else {
+ list_next->prev = list_prev;
+ }
+
+ free(list_del);
+
+ if (g_task_list == NULL) {
+ if (s_info.is_started_cb_set_task == 1) {
+ _unset_master_started_cb(_master_started_cb_task);
+ s_info.is_started_cb_set_task = 0;
+ }
+ }
+
+ return BADGE_ERROR_NONE;
+ }
+ list_del = list_del->next;
+ } while (list_del != NULL);
+
+ return BADGE_ERROR_INVALID_DATA;
+}
+
+static void _do_deffered_task(void) {
+ task_list *list_do = NULL;
+ task_list *list_temp = NULL;
+
+ if (g_task_list == NULL) {
+ return;
+ }
+
+ list_do = g_task_list;
+ g_task_list = NULL;
+ if (s_info.is_started_cb_set_task == 1) {
+ _unset_master_started_cb(_master_started_cb_task);
+ s_info.is_started_cb_set_task = 0;
+ }
+
+ while (list_do->prev != NULL) {
+ list_do = list_do->prev;
+ }
+
+ while (list_do != NULL) {
+ if (list_do->task_cb != NULL) {
+ list_do->task_cb(list_do->data);
+ DBG("called:%p", list_do->task_cb);
+ }
+ list_temp = list_do->next;
+ free(list_do);
+ list_do = list_temp;
+ }
+}
+
+static void _master_started_cb_service(keynode_t *node,
+ void *data) {
+ int ret = BADGE_ERROR_NONE;
+
+ if (badge_ipc_is_master_ready()) {
+ ret = badge_ipc_monitor_register();
+ if (ret != BADGE_ERROR_NONE) {
+ ERR("failed to register a monitor");
+ }
+ } else {
+ ret = badge_ipc_monitor_deregister();
+ if (ret != BADGE_ERROR_NONE) {
+ ERR("failed to deregister a monitor");
+ }
+ }
+}
+
+static void _master_started_cb_task(keynode_t *node,
+ void *data) {
+
+ if (badge_ipc_is_master_ready()) {
+ _do_deffered_task();
+ }
+}
+
+/*!
+ * functions to handler services
+ */
+static struct packet *_handler_insert_badge(pid_t pid, int handle, const struct packet *packet)
+{
+ int ret = 0;
+ char *pkgname = NULL;
+
+ if (!packet) {
+ ERR("a packet is null");
+ return NULL;
+ }
+
+ DBG("");
+
+ //return code, pkgname
+ if (packet_get(packet, "is", &ret, &pkgname) == 2) {
+ if (ret == BADGE_ERROR_NONE) {
+ badge_changed_cb_call(BADGE_ACTION_CREATE, pkgname, 0);
+ } else {
+ ERR("failed to insert a new badge:%d", ret);
+ }
+ } else {
+ ERR("failed to get data from a packet");
+ }
+
+ return NULL;
+}
+
+static struct packet *_handler_delete_badge(pid_t pid, int handle, const struct packet *packet)
+{
+ int ret = 0;
+ char *pkgname = NULL;
+
+ if (!packet) {
+ ERR("a packet is null");
+ return NULL;
+ }
+
+ DBG("");
+
+ if (packet_get(packet, "is", &ret, &pkgname) == 2) {
+ if (ret == BADGE_ERROR_NONE) {
+ badge_changed_cb_call(BADGE_ACTION_REMOVE, pkgname, 0);
+ } else {
+ ERR("failed to remove a badge:%d", ret);
+ }
+ } else {
+ ERR("failed to get data from a packet");
+ }
+
+ return NULL;
+}
+
+static struct packet *_handler_set_badge_count(pid_t pid, int handle, const struct packet *packet)
+{
+ int ret = 0;
+ char *pkgname = NULL;
+ int count = 0;
+
+ if (!packet) {
+ ERR("a packet is null");
+ return NULL;
+ }
+
+ DBG("");
+
+ if (packet_get(packet, "isi", &ret, &pkgname, &count) == 3) {
+ if (ret == BADGE_ERROR_NONE) {
+ badge_changed_cb_call(BADGE_ACTION_UPDATE, pkgname, count);
+ } else {
+ ERR("failed to update count of badge:%d", ret);
+ }
+ } else {
+ ERR("failed to get data from a packet");
+ }
+
+ return NULL;
+}
+
+static struct packet *_handler_set_display_option(pid_t pid, int handle, const struct packet *packet)
+{
+ int ret = 0;
+ char *pkgname = NULL;
+ int is_display = 0;
+
+ if (!packet) {
+ ERR("a packet is null");
+ return NULL;
+ }
+
+ DBG("");
+
+ if (packet_get(packet, "isi", &ret, &pkgname, &is_display) == 3) {
+ if (ret == BADGE_ERROR_NONE) {
+ badge_changed_cb_call(BADGE_ACTION_CHANGED_DISPLAY, pkgname, is_display);
+ } else {
+ ERR("failed to update the display option of badge:%d, %d", ret, is_display);
+ }
+ } else {
+ ERR("failed to get data from a packet");
+ }
+
+ return NULL;
+}
+
+static int _handler_service_register(pid_t pid, int handle, const struct packet *packet, void *data)
+{
+ int ret;
+
+ DBG("");
+
+ if (!packet) {
+ ERR("Packet is not valid\n");
+ ret = BADGE_ERROR_INVALID_DATA;
+ } else if (packet_get(packet, "i", &ret) != 1) {
+ ERR("Packet is not valid\n");
+ ret = BADGE_ERROR_INVALID_DATA;
+ } else {
+ if (ret == BADGE_ERROR_NONE) {
+ badge_changed_cb_call(BADGE_ACTION_SERVICE_READY, NULL, 0);
+ }
+ }
+ return ret;
+}
+
+/*!
+ * functions to initialize and register a monitor
+ */
+static badge_error_e badge_ipc_monitor_register(void)
+{
+ int ret;
+ struct packet *packet;
+ static struct method service_table[] = {
+ {
+ .cmd = "insert_badge",
+ .handler = _handler_insert_badge,
+ },
+ {
+ .cmd = "delete_badge",
+ .handler = _handler_delete_badge,
+ },
+ {
+ .cmd = "set_badge_count",
+ .handler = _handler_set_badge_count,
+ },
+ {
+ .cmd = "set_disp_option",
+ .handler = _handler_set_display_option,
+ },
+ {
+ .cmd = NULL,
+ .handler = NULL,
+ },
+ };
+
+ if (s_info.initialized == 1) {
+ return BADGE_ERROR_NONE;
+ } else {
+ s_info.initialized = 1;
+ }
+
+ ERR("register a service\n");
+
+ s_info.server_fd = com_core_packet_client_init(s_info.socket_file, 0, service_table);
+ if (s_info.server_fd < 0) {
+ ERR("Failed to make a connection to the master\n");
+ return BADGE_ERROR_IO;
+ }
+
+ packet = packet_create("service_register", "");
+ if (!packet) {
+ ERR("Failed to build a packet\n");
+ return BADGE_ERROR_IO;
+ }
+
+ ret = com_core_packet_async_send(s_info.server_fd, packet, 1.0, _handler_service_register, NULL);
+ DBG("Service register sent: %d\n", ret);
+ packet_destroy(packet);
+ if (ret != 0) {
+ com_core_packet_client_fini(s_info.server_fd);
+ s_info.server_fd = BADGE_ERROR_INVALID_DATA;
+ ret = BADGE_ERROR_IO;
+ } else {
+ ret = BADGE_ERROR_NONE;
+ }
+
+ DBG("Server FD: %d\n", s_info.server_fd);
+ return ret;
+}
+
+badge_error_e badge_ipc_monitor_deregister(void)
+{
+ if (s_info.initialized == 0) {
+ return BADGE_ERROR_NONE;
+ }
+
+ com_core_packet_client_fini(s_info.server_fd);
+ s_info.server_fd = BADGE_ERROR_INVALID_DATA;
+
+ s_info.initialized = 0;
+
+ return BADGE_ERROR_NONE;
+}
+
+badge_error_e badge_ipc_monitor_init(void)
+{
+ int ret = BADGE_ERROR_NONE;
+
+ if (badge_ipc_is_master_ready()) {
+ ret = badge_ipc_monitor_register();
+ }
+
+ if (s_info.is_started_cb_set_svc == 0) {
+ _set_master_started_cb(_master_started_cb_service);
+ s_info.is_started_cb_set_svc = 1;
+ }
+
+ return ret;
+}
+
+badge_error_e badge_ipc_monitor_fini(void)
+{
+ int ret = BADGE_ERROR_NONE;
+
+ if (s_info.is_started_cb_set_svc == 1) {
+ _unset_master_started_cb(_master_started_cb_service);
+ s_info.is_started_cb_set_svc = 0;
+ }
+
+ ret = badge_ipc_monitor_deregister();
+
+ return ret;
+}
+
+
+badge_error_e badge_ipc_request_insert(const char *pkgname, const char *writable_pkg, const char *caller) {
+ int ret = 0;
+ struct packet *packet;
+ struct packet *result;
+
+ packet = packet_create("insert_badge", "sss", pkgname, writable_pkg, caller);
+ result = com_core_packet_oneshot_send(BADGE_ADDR,
+ packet,
+ BADGE_IPC_TIMEOUT);
+ packet_destroy(packet);
+
+ if (result != NULL) {
+ if (packet_get(result, "i", &ret) != 1) {
+ ERR("Failed to get a result packet");
+ packet_unref(result);
+ return BADGE_ERROR_IO;
+ }
+
+ if (ret != BADGE_ERROR_NONE) {
+ return ret;
+ }
+ } else {
+ badge_ipc_is_master_ready();
+ return BADGE_ERROR_SERVICE_NOT_READY;
+ }
+
+ return BADGE_ERROR_NONE;
+}
+
+badge_error_e badge_ipc_request_delete(const char *pkgname, const char *caller) {
+ int ret = 0;
+ struct packet *packet;
+ struct packet *result;
+
+ packet = packet_create("delete_badge", "ss", pkgname, caller);
+ result = com_core_packet_oneshot_send(BADGE_ADDR,
+ packet,
+ BADGE_IPC_TIMEOUT);
+ packet_destroy(packet);
+
+ if (result != NULL) {
+ if (packet_get(result, "i", &ret) != 1) {
+ ERR("Failed to get a result packet");
+ packet_unref(result);
+ return BADGE_ERROR_IO;
+ }
+
+ if (ret != BADGE_ERROR_NONE) {
+ return ret;
+ }
+ } else {
+ badge_ipc_is_master_ready();
+ return BADGE_ERROR_SERVICE_NOT_READY;
+ }
+
+ return BADGE_ERROR_NONE;
+}
+
+badge_error_e badge_ipc_request_set_count(const char *pkgname, const char *caller, int count) {
+ int ret = 0;
+ struct packet *packet;
+ struct packet *result;
+
+ packet = packet_create("set_badge_count", "ssi", pkgname, caller, count);
+ result = com_core_packet_oneshot_send(BADGE_ADDR,
+ packet,
+ BADGE_IPC_TIMEOUT);
+ packet_destroy(packet);
+
+ if (result != NULL) {
+ if (packet_get(result, "i", &ret) != 1) {
+ ERR("Failed to get a result packet");
+ packet_unref(result);
+ return BADGE_ERROR_IO;
+ }
+
+ if (ret != BADGE_ERROR_NONE) {
+ return ret;
+ }
+ } else {
+ badge_ipc_is_master_ready();
+ return BADGE_ERROR_SERVICE_NOT_READY;
+ }
+
+ return BADGE_ERROR_NONE;
+}
+
+badge_error_e badge_ipc_request_set_display(const char *pkgname, const char *caller, int display_option) {
+ int ret = 0;
+ struct packet *packet;
+ struct packet *result;
+
+ packet = packet_create("set_disp_option", "ssi", pkgname, caller, display_option);
+ result = com_core_packet_oneshot_send(BADGE_ADDR,
+ packet,
+ BADGE_IPC_TIMEOUT);
+ packet_destroy(packet);
+
+ if (result != NULL) {
+ if (packet_get(result, "i", &ret) != 1) {
+ ERR("Failed to get a result packet");
+ packet_unref(result);
+ return BADGE_ERROR_IO;
+ }
+
+ if (ret != BADGE_ERROR_NONE) {
+ return ret;
+ }
+ } else {
+ badge_ipc_is_master_ready();
+ return BADGE_ERROR_SERVICE_NOT_READY;
+ }
+
+ return BADGE_ERROR_NONE;
+}