summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiyoung Yun <jy910.yun@samsung.com>2015-04-17 17:23:53 +0900
committerJiyoung Yun <jy910.yun@samsung.com>2015-05-06 13:44:45 +0900
commitb1ad68f3e3f726353e127520d170fa5a9ac4fbfc (patch)
tree86655318a89d5f159489b0885af507ba5c8bf1ab
parent17a3982add26254ffc8bd1a4431e9ee0c2435228 (diff)
downloaddeviced-b1ad68f3e3f726353e127520d170fa5a9ac4fbfc.tar.gz
deviced-b1ad68f3e3f726353e127520d170fa5a9ac4fbfc.tar.bz2
deviced-b1ad68f3e3f726353e127520d170fa5a9ac4fbfc.zip
haptic: Add exception handling of unexpectedly killed process.
When some process is killed unexpectedly, it should control to stop, close and collect the related resources. Change-Id: I4dd9a226304b7d755ac6d0d5a9ad1ba9bb79ed40 Signed-off-by: Jiyoung Yun <jy910.yun@samsung.com>
-rw-r--r--src/core/edbus-handler.c80
-rw-r--r--src/haptic/haptic.c151
2 files changed, 185 insertions, 46 deletions
diff --git a/src/core/edbus-handler.c b/src/core/edbus-handler.c
index c9f3630b..13a41bac 100644
--- a/src/core/edbus-handler.c
+++ b/src/core/edbus-handler.c
@@ -81,6 +81,9 @@ static DBusConnection *conn;
static E_DBus_Connection *edbus_conn;
static DBusPendingCall *edbus_request_name;
+static DBusHandlerResult message_filter(DBusConnection *connection,
+ DBusMessage *message, void *data);
+
static int register_edbus_interface(struct edbus_object *object)
{
if (!object) {
@@ -281,11 +284,24 @@ static void print_watch_item(void)
_D("watch sender : %s, deleted : %d",
watch->sender, watch->deleted);
DD_LIST_FOREACH(watch->func_list, e, finfo)
- _D("\tfunc : %x, deleted : %d",
+ _D("\tfunc : %p, deleted : %d",
finfo->func, finfo->deleted);
}
}
+static bool get_valid_watch_item(void)
+{
+ struct watch_info *watch;
+ dd_list *elem;
+
+ DD_LIST_FOREACH(edbus_watch_list, elem, watch) {
+ if (!watch->deleted)
+ return true;
+ }
+
+ return false;
+}
+
static void watch_idler_cb(void *data)
{
struct watch_info *watch;
@@ -294,22 +310,34 @@ static void watch_idler_cb(void *data)
dd_list *next;
dd_list *elem;
dd_list *enext;
+ char match[256];
DD_LIST_FOREACH_SAFE(edbus_watch_list, n, next, watch) {
if (!watch->deleted)
continue;
+ /* remove dbus match */
+ snprintf(match, sizeof(match), NAME_OWNER_MATCH, watch->sender);
+ dbus_bus_remove_match(conn, match, NULL);
+
+ _I("%s is not watched by dbus!", watch->sender);
+
/* remove watch func list */
DD_LIST_FOREACH_SAFE(watch->func_list, elem, enext, finfo)
free(finfo);
+
+ /* remove watch item */
DD_LIST_FREE_LIST(watch->func_list);
DD_LIST_REMOVE_LIST(edbus_watch_list, n);
free(watch->sender);
free(watch);
}
+
+ /* if the last request, remove message filter */
+ if (!get_valid_watch_item())
+ dbus_connection_remove_filter(conn, message_filter, NULL);
}
-static int remove_watch_item(struct watch_info *watch);
static DBusHandlerResult message_filter(DBusConnection *connection,
DBusMessage *message, void *data)
{
@@ -360,7 +388,7 @@ static DBusHandlerResult message_filter(DBusConnection *connection,
}
/* no interest in this item anymore */
- remove_watch_item(watch);
+ watch->deleted = true;
print_watch_item();
add_idle_request(watch_idler_cb, NULL);
@@ -387,19 +415,6 @@ static struct watch_info *get_matched_watch_item(const char *sender)
return NULL;
}
-static bool get_valid_watch_item(void)
-{
- struct watch_info *watch;
- dd_list *elem;
-
- DD_LIST_FOREACH(edbus_watch_list, elem, watch) {
- if (!watch->deleted)
- return true;
- }
-
- return false;
-}
-
static struct watch_info *add_watch_item(const char *sender)
{
DBusError err;
@@ -444,7 +459,7 @@ static struct watch_info *add_watch_item(const char *sender)
/* Add watch to watch list */
DD_LIST_APPEND(edbus_watch_list, watch);
-
+ _I("%s is watched by dbus!", sender);
return watch;
out:
@@ -456,25 +471,6 @@ out:
return NULL;
}
-static int remove_watch_item(struct watch_info *watch)
-{
- char match[256];
-
- if (!watch)
- return -EINVAL;
-
- snprintf(match, sizeof(match), NAME_OWNER_MATCH, watch->sender);
- dbus_bus_remove_match(conn, match, NULL);
-
- watch->deleted = true;
-
- /* if the last request, remove message filter */
- if (!get_valid_watch_item())
- dbus_connection_remove_filter(conn, message_filter, NULL);
-
- return 0;
-}
-
int register_edbus_watch(const char *sender,
void (*func)(const char *sender, void *data), void *data)
{
@@ -520,12 +516,11 @@ int register_edbus_watch(const char *sender,
/* add callback function to the watch list */
DD_LIST_APPEND(watch->func_list, finfo);
- print_watch_item();
- _I("%s is watched by dbus!", sender);
+ _I("register watch func(%p) of %s", func, sender);
return 0;
out:
if (isnew)
- remove_watch_item(watch);
+ watch->deleted = true;
return -EPERM;
}
@@ -559,10 +554,9 @@ int unregister_edbus_watch(const char *sender,
/* if it is the last item */
if (!matched)
- remove_watch_item(watch);
+ watch->deleted = true;
- print_watch_item();
- _I("%s is not watched by dbus!", sender);
+ _I("unregister watch func(%p) of %s", func, sender);
return 0;
}
@@ -573,7 +567,7 @@ static void unregister_edbus_watch_all(void)
struct watch_info *watch;
DD_LIST_FOREACH_SAFE(edbus_watch_list, n, next, watch)
- remove_watch_item(watch);
+ watch->deleted = true;
add_idle_request(watch_idler_cb, NULL);
}
diff --git a/src/haptic/haptic.c b/src/haptic/haptic.c
index 61ccc91b..b55bdbbb 100644
--- a/src/haptic/haptic.c
+++ b/src/haptic/haptic.c
@@ -44,6 +44,7 @@
#define HARDKEY_VIB_PRIORITY 2
#define HARDKEY_VIB_DURATION 300
#define HAPTIC_FEEDBACK_STEP 20
+#define DEFAULT_FEEDBACK_LEVEL 3
/* power on, power off vibration variable */
#define POWER_ON_VIB_DURATION 300
@@ -59,11 +60,17 @@
#define CHECK_VALID_OPS(ops, r) ((ops) ? true : !(r = -ENODEV))
+struct haptic_info {
+ char *sender;
+ dd_list *handle_list;
+};
+
/* for playing */
static int g_handle;
/* haptic operation variable */
static dd_list *h_head;
+static dd_list *haptic_handle_list;
static const struct haptic_plugin_ops *h_ops;
static enum haptic_type h_type;
static bool haptic_disabled;
@@ -78,6 +85,7 @@ static struct haptic_config haptic_conf;
static int haptic_start(void);
static int haptic_stop(void);
static int haptic_internal_init(void);
+static int remove_haptic_info(struct haptic_info *info);
void add_haptic(const struct haptic_ops *ops)
{
@@ -134,7 +142,8 @@ static int convert_magnitude_by_conf(int level)
}
}
- return -EINVAL;
+ _D("play default level");
+ return DEFAULT_FEEDBACK_LEVEL * HAPTIC_FEEDBACK_STEP;
}
static DBusMessage *edbus_get_count(E_DBus_Object *obj, DBusMessage *msg)
@@ -157,11 +166,85 @@ exit:
return reply;
}
+static void haptic_name_owner_changed(const char *sender, void *data)
+{
+ dd_list *n;
+ struct haptic_info *info = data;
+ int handle;
+
+ _I("%s (sender:%s)", __func__, sender);
+
+ if (!info)
+ return;
+
+ for (n = info->handle_list; n; n = n->next) {
+ handle = n->data;
+ h_ops->stop_device(handle);
+ h_ops->close_device(handle);
+ }
+
+ remove_haptic_info(info);
+}
+
+static struct haptic_info *add_haptic_info(const char *sender)
+{
+ struct haptic_info *info;
+
+ assert(sender);
+
+ info = calloc(1, sizeof(struct haptic_info));
+ if (!info)
+ return NULL;
+
+ info->sender = strdup(sender);
+ DD_LIST_APPEND(haptic_handle_list, info);
+
+ register_edbus_watch(sender, haptic_name_owner_changed, info);
+
+ return info;
+}
+
+static int remove_haptic_info(struct haptic_info *info)
+{
+ dd_list *n;
+ dd_list *next;
+
+ assert(info);
+
+ unregister_edbus_watch(info->sender, haptic_name_owner_changed);
+
+ DD_LIST_REMOVE(haptic_handle_list, info);
+ DD_LIST_FREE_LIST(info->handle_list);
+ free(info->sender);
+ free(info);
+
+ return 0;
+}
+
+static struct haptic_info *get_matched_haptic_info(const char *sender)
+{
+ dd_list *n;
+ struct haptic_info *info;
+ int len;
+
+ assert(sender);
+
+ len = strlen(sender) + 1;
+ DD_LIST_FOREACH(haptic_handle_list, n, info) {
+ if (!strncmp(info->sender, sender, len))
+ return info;
+ }
+
+ return NULL;
+}
+
static DBusMessage *edbus_open_device(E_DBus_Object *obj, DBusMessage *msg)
{
DBusMessageIter iter;
DBusMessage *reply;
int index, handle, ret;
+ struct haptic_info *info;
+ const char *sender;
/* Load haptic module before booting done */
if (!CHECK_VALID_OPS(h_ops, ret)) {
@@ -176,8 +259,30 @@ static DBusMessage *edbus_open_device(E_DBus_Object *obj, DBusMessage *msg)
}
ret = h_ops->open_device(index, &handle);
- if (ret >= 0)
- ret = handle;
+ if (ret < 0)
+ goto exit;
+
+ sender = dbus_message_get_sender(msg);
+ if (!sender) {
+ ret = -EPERM;
+ h_ops->close_device(handle);
+ goto exit;
+ }
+
+ info = get_matched_haptic_info(sender);
+ if (!info) {
+ info = add_haptic_info(sender);
+ if (!info) {
+ _E("fail to create haptic information");
+ ret = -EPERM;
+ h_ops->close_device(handle);
+ goto exit;
+ }
+ }
+
+ DD_LIST_APPEND(info->handle_list, handle);
+
+ ret = handle;
exit:
reply = dbus_message_new_method_return(msg);
@@ -192,6 +297,9 @@ static DBusMessage *edbus_close_device(E_DBus_Object *obj, DBusMessage *msg)
DBusMessage *reply;
unsigned int handle;
int ret;
+ struct haptic_info *info;
+ const char *sender;
+ int cnt;
if (!CHECK_VALID_OPS(h_ops, ret))
goto exit;
@@ -201,7 +309,27 @@ static DBusMessage *edbus_close_device(E_DBus_Object *obj, DBusMessage *msg)
goto exit;
}
+ sender = dbus_message_get_sender(msg);
+ if (!sender) {
+ _E("fail to get sender from dbus message");
+ ret = -EPERM;
+ goto exit;
+ }
+
ret = h_ops->close_device(handle);
+ if (ret < 0)
+ goto exit;
+
+ info = get_matched_haptic_info(sender);
+ if (!info) {
+ _E("fail to find the matched haptic info.");
+ goto exit;
+ }
+
+ DD_LIST_REMOVE(info->handle_list, handle);
+ cnt = DD_LIST_LENGTH(info->handle_list);
+ if (cnt == 0)
+ remove_haptic_info(info);
exit:
reply = dbus_message_new_method_return(msg);
@@ -440,6 +568,22 @@ exit:
return reply;
}
+static DBusMessage *edbus_show_handle_list(E_DBus_Object *obj, DBusMessage *msg)
+{
+ dd_list *n;
+ dd_list *elem;
+ struct haptic_info *info;
+ int cnt = 0;
+
+ _D(" sender\thandle");
+ DD_LIST_FOREACH(haptic_handle_list, n, info) {
+ for (elem = info->handle_list; elem; elem = elem->next)
+ _D("[%2d]%s\t%d", cnt++, info->sender, (int)elem->data);
+ }
+
+ return dbus_message_new_method_return(msg);
+}
+
static unsigned char* convert_file_to_buffer(const char *file_name, int *size)
{
FILE *pf;
@@ -657,6 +801,7 @@ static const struct edbus_method edbus_methods[] = {
{ "GetDuration", "uay", "i", edbus_get_duration },
{ "CreateEffect", "iayi", "ayi", edbus_create_effect },
{ "SaveBinary", "ays", "i", edbus_save_binary },
+ { "ShowHandleList", NULL, NULL, edbus_show_handle_list },
/* Add methods here */
};