unbreak notification callbacks, fix notification crashes

this should not have been committed as-is, and I'm very disappointed at the lack of testing here.
This commit is contained in:
Mike Blumenkrantz 2013-04-25 09:12:43 +01:00
parent 1efc663a18
commit 53d8c89791
6 changed files with 37 additions and 41 deletions

View File

@ -12,6 +12,21 @@ typedef struct _Notification_Data
static Notification_Data *n_data = NULL; static Notification_Data *n_data = NULL;
static void
_notification_free(E_Notification_Notify *notify)
{
EINA_SAFETY_ON_NULL_RETURN(notify);
eina_stringshare_del(notify->app_name);
eina_stringshare_del(notify->body);
eina_stringshare_del(notify->icon.icon);
if (notify->icon.icon_path)
eina_stringshare_del(notify->icon.icon_path);
eina_stringshare_del(notify->sumary);
if (notify->icon.raw.data)
free(notify->icon.raw.data);
free(notify);
}
static void static void
hints_dict_iter(void *data, const void *key, Eldbus_Message_Iter *var) hints_dict_iter(void *data, const void *key, Eldbus_Message_Iter *var)
{ {
@ -64,8 +79,7 @@ notify_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Messag
if (!n_data->notify_cb) if (!n_data->notify_cb)
return NULL; return NULL;
n = calloc(1, sizeof(E_Notification_Notify)); n = E_OBJECT_ALLOC(E_Notification_Notify, E_NOTIFICATION_TYPE, _notification_free);
EINA_SAFETY_ON_NULL_RETURN_VAL(n, NULL);
if (!eldbus_message_arguments_get(msg, "susssasa{sv}i", &n->app_name, if (!eldbus_message_arguments_get(msg, "susssasa{sv}i", &n->app_name,
&n->replaces_id, &n->icon.icon, &n->sumary, &n->replaces_id, &n->icon.icon, &n->sumary,
@ -73,7 +87,7 @@ notify_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Messag
&n->timeout)) &n->timeout))
{ {
ERR("Reading message."); ERR("Reading message.");
free(n); e_object_del(E_OBJECT(n));
return NULL; return NULL;
} }
eldbus_message_iter_dict_iterate(hints_iter, "sv", hints_dict_iter, n); eldbus_message_iter_dict_iterate(hints_iter, "sv", hints_dict_iter, n);
@ -82,9 +96,11 @@ notify_cb(const Eldbus_Service_Interface *iface EINA_UNUSED, const Eldbus_Messag
n->sumary = eina_stringshare_add(n->sumary); n->sumary = eina_stringshare_add(n->sumary);
n->body = eina_stringshare_add(n->body); n->body = eina_stringshare_add(n->body);
e_object_ref(E_OBJECT(n));
n->id = n_data->notify_cb(n_data->data, n); n->id = n_data->notify_cb(n_data->data, n);
reply = eldbus_message_method_return_new(msg); reply = eldbus_message_method_return_new(msg);
eldbus_message_arguments_append(reply, "u", n->id); eldbus_message_arguments_append(reply, "u", n->id);
e_object_unref(E_OBJECT(n));
return reply; return reply;
} }
@ -195,21 +211,6 @@ e_notification_server_unregister(void)
n_data = NULL; n_data = NULL;
} }
EAPI void
e_notification_notify_free(E_Notification_Notify *notify)
{
EINA_SAFETY_ON_NULL_RETURN(notify);
eina_stringshare_del(notify->app_name);
eina_stringshare_del(notify->body);
eina_stringshare_del(notify->icon.icon);
if (notify->icon.icon_path)
eina_stringshare_del(notify->icon.icon_path);
eina_stringshare_del(notify->sumary);
if (notify->icon.raw.data)
free(notify->icon.raw.data);
free(notify);
}
EAPI void EAPI void
e_notification_notify_close(E_Notification_Notify *notify, E_Notification_Notify_Closed_Reason reason) e_notification_notify_close(E_Notification_Notify *notify, E_Notification_Notify_Closed_Reason reason)
{ {

View File

@ -1,8 +1,9 @@
#ifndef E_TYPEDEFS
#ifndef _E_NOTIFICATION_H #ifndef _E_NOTIFICATION_H
#define _E_NOTIFICATION_H #define _E_NOTIFICATION_H
#include <Eldbus.h> #define E_NOTIFICATION_TYPE 0x12342166
#include <Eina.h>
typedef enum _E_Notification_Notify_Urgency typedef enum _E_Notification_Notify_Urgency
{ {
@ -21,6 +22,7 @@ typedef enum _E_Notification_Notify_Closed_Reason
typedef struct _E_Notification_Notify typedef struct _E_Notification_Notify
{ {
E_Object e_obj_inherit;
unsigned int id; unsigned int id;
const char *app_name; const char *app_name;
unsigned replaces_id; unsigned replaces_id;
@ -73,7 +75,6 @@ EAPI Eina_Bool e_notification_server_register(const E_Notification_Server_Info *
*/ */
EAPI void e_notification_server_unregister(void); EAPI void e_notification_server_unregister(void);
EAPI void e_notification_notify_free(E_Notification_Notify *notify);
EAPI void e_notification_notify_close(E_Notification_Notify *notify, E_Notification_Notify_Closed_Reason reason); EAPI void e_notification_notify_close(E_Notification_Notify *notify, E_Notification_Notify_Closed_Reason reason);
EAPI Evas_Object *e_notification_notify_raw_image_get(E_Notification_Notify *notify, Evas *evas); EAPI Evas_Object *e_notification_notify_raw_image_get(E_Notification_Notify *notify, Evas *evas);
@ -82,3 +83,5 @@ typedef void (*E_Notification_Client_Send_Cb)(void *data, unsigned int id);
EAPI Eina_Bool e_notification_client_send(E_Notification_Notify *notify, E_Notification_Client_Send_Cb cb, const void *data); EAPI Eina_Bool e_notification_client_send(E_Notification_Notify *notify, E_Notification_Client_Send_Cb cb, const void *data);
#endif #endif
#endif

View File

@ -58,7 +58,7 @@ _e_mod_notify_cb_add(void *data EINA_UNUSED, E_Notification_Notify *n)
if (n->replaces_id && (nwin = _e_mod_notify_find(n->replaces_id))) if (n->replaces_id && (nwin = _e_mod_notify_find(n->replaces_id)))
{ {
if (nwin->notify) if (nwin->notify)
e_notification_notify_free(nwin->notify); e_object_del(E_OBJECT(nwin->notify));
nwin->notify = n; nwin->notify = n;
nwin->id = _notify_id; nwin->id = _notify_id;
_e_mod_notify_refresh(nwin); _e_mod_notify_refresh(nwin);
@ -247,7 +247,7 @@ _e_mod_notify_cb_free(Ind_Notify_Win *nwin)
nwin->win = NULL; nwin->win = NULL;
e_notification_notify_close(nwin->notify, e_notification_notify_close(nwin->notify,
E_NOTIFICATION_NOTIFY_CLOSED_REASON_REQUESTED); E_NOTIFICATION_NOTIFY_CLOSED_REASON_REQUESTED);
e_notification_notify_free(nwin->notify); e_object_del(E_OBJECT(nwin->notify));
_nwins = eina_list_remove(_nwins, nwin); _nwins = eina_list_remove(_nwins, nwin);
E_FREE(nwin); E_FREE(nwin);
} }

View File

@ -14,18 +14,12 @@ static unsigned int
_notification_notify(E_Notification_Notify *n) _notification_notify(E_Notification_Notify *n)
{ {
unsigned int new_id; unsigned int new_id;
int popuped;
if (e_desklock_state_get()) return 0; if (e_desklock_state_get()) return 0;
notification_cfg->next_id++; notification_cfg->next_id++;
new_id = notification_cfg->next_id; new_id = notification_cfg->next_id;
popuped = notification_popup_notify(n, new_id);
if (!popuped)
{
n->urgency = 4;
notification_popup_notify(n, new_id); notification_popup_notify(n, new_id);
}
return new_id; return new_id;
} }

View File

@ -71,7 +71,7 @@ struct _Popup_Data
}; };
int notification_popup_notify(E_Notification_Notify *n, unsigned int id); void notification_popup_notify(E_Notification_Notify *n, unsigned int id);
void notification_popup_shutdown(void); void notification_popup_shutdown(void);
void notification_popup_close(unsigned int id); void notification_popup_close(unsigned int id);

View File

@ -28,7 +28,7 @@ _notification_timer_cb(Popup_Data *popup)
return EINA_FALSE; return EINA_FALSE;
} }
int void
notification_popup_notify(E_Notification_Notify *n, notification_popup_notify(E_Notification_Notify *n,
unsigned int id) unsigned int id)
{ {
@ -37,13 +37,13 @@ notification_popup_notify(E_Notification_Notify *n,
switch (n->urgency) switch (n->urgency)
{ {
case E_NOTIFICATION_NOTIFY_URGENCY_LOW: case E_NOTIFICATION_NOTIFY_URGENCY_LOW:
if (!notification_cfg->show_low) return 0; if (!notification_cfg->show_low) return;
break; break;
case E_NOTIFICATION_NOTIFY_URGENCY_NORMAL: case E_NOTIFICATION_NOTIFY_URGENCY_NORMAL:
if (!notification_cfg->show_normal) return 0; if (!notification_cfg->show_normal) return;
break; break;
case E_NOTIFICATION_NOTIFY_URGENCY_CRITICAL: case E_NOTIFICATION_NOTIFY_URGENCY_CRITICAL:
if (!notification_cfg->show_critical) return 0; if (!notification_cfg->show_critical) return;
break; break;
default: default:
break; break;
@ -54,7 +54,7 @@ notification_popup_notify(E_Notification_Notify *n,
if (n->replaces_id && (popup = _notification_popup_find(n->replaces_id))) if (n->replaces_id && (popup = _notification_popup_find(n->replaces_id)))
{ {
if (popup->notif) if (popup->notif)
e_notification_notify_free(popup->notif); e_object_del(E_OBJECT(popup->notif));
popup->notif = n; popup->notif = n;
popup->id = id; popup->id = id;
@ -66,9 +66,9 @@ notification_popup_notify(E_Notification_Notify *n,
popup = _notification_popup_new(n, id); popup = _notification_popup_new(n, id);
if (!popup) if (!popup)
{ {
e_notification_notify_free(n); e_object_del(E_OBJECT(n));
ERR("Error creating popup"); ERR("Error creating popup");
return 0; return;
} }
notification_cfg->popups = eina_list_append(notification_cfg->popups, popup); notification_cfg->popups = eina_list_append(notification_cfg->popups, popup);
edje_object_signal_emit(popup->theme, "notification,new", "notification"); edje_object_signal_emit(popup->theme, "notification,new", "notification");
@ -87,8 +87,6 @@ notification_popup_notify(E_Notification_Notify *n,
if (n->timeout > 0) if (n->timeout > 0)
popup->timer = ecore_timer_add(n->timeout, (Ecore_Task_Cb)_notification_timer_cb, popup); popup->timer = ecore_timer_add(n->timeout, (Ecore_Task_Cb)_notification_timer_cb, popup);
return 1;
} }
void void
@ -500,7 +498,7 @@ _notification_popdown(Popup_Data *popup,
if (popup->notif) if (popup->notif)
{ {
e_notification_notify_close(popup->notif, reason); e_notification_notify_close(popup->notif, reason);
e_notification_notify_free(popup->notif); e_object_del(E_OBJECT(popup->notif));
} }
popup->notif = NULL; popup->notif = NULL;
if (popup->pending) return; if (popup->pending) return;