diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2015-04-17 17:23:53 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2015-05-06 13:44:45 +0900 |
commit | b1ad68f3e3f726353e127520d170fa5a9ac4fbfc (patch) | |
tree | 86655318a89d5f159489b0885af507ba5c8bf1ab | |
parent | 17a3982add26254ffc8bd1a4431e9ee0c2435228 (diff) | |
download | deviced-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.c | 80 | ||||
-rw-r--r-- | src/haptic/haptic.c | 151 |
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 */ }; |