919f0188e1f63d855f5f8707e7dd33745667ed8e
[platform/core/api/notification.git] / src / notification_status.c
1 /*
2  *  libnotification
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Seungtaek Chung <seungtaek.chung@samsung.com>, Mi-Ju Lee <miju52.lee@samsung.com>, Xi Zhichan <zhichan.xi@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <vconf.h>
28 #include <E_DBus.h>
29 #include <Ecore.h>
30 #include <Elementary.h>
31 #include <Eina.h>
32
33 #include <notification.h>
34 #include <notification_db.h>
35 #include <notification_noti.h>
36 #include <notification_debug.h>
37 #include <notification_private.h>
38 #include <notification_status.h>
39
40 #define PATH_NAME    "/Org/Tizen/System/Notification/Status_message"
41 #define INTERFACE_NAME "org.tizen.system.notification.status_message"
42 #define MEMBER_NAME     "status_message"
43
44 static Eina_List *toast_list;
45 static Eina_List *toast_popup;
46
47 struct _message_cb_data {
48         notification_status_message_cb callback;
49         void *data;
50         E_DBus_Connection *dbus_connection;
51         E_DBus_Signal_Handler *dbus_hdlr;
52 };
53
54 static struct _message_cb_data md;
55
56 int _post_toast_message(char *message);
57
58 static void popup_timeout_cb(void *data, Evas_Object *obj, void *event_info)
59 {
60         char *msg = NULL;
61         int count = 0;
62
63         evas_object_del(toast_popup);
64         toast_popup = NULL;
65         evas_object_del((Evas_Object *)data);
66
67         count = eina_list_count(toast_list);
68
69         if (count == 1){
70                 msg = (char *)eina_list_data_get(toast_list);
71                 free(msg);
72
73                 eina_list_free(toast_list);
74                 toast_list = NULL;
75         } else if (count > 1) {
76                 msg = (char *)eina_list_data_get(toast_list);
77                 toast_list = eina_list_remove(toast_list, msg);
78                 free(msg);
79                 _post_toast_message((char *)eina_list_data_get(toast_list));
80         }
81 }
82
83 int _post_toast_message(char *message)
84 {
85         Evas_Object *toast_window;
86         Evas *e;
87         Ecore_Evas *ee;
88         double scale = elm_config_scale_get();
89
90
91         toast_window = elm_win_add(NULL, "toast", ELM_WIN_BASIC);
92
93         elm_win_alpha_set(toast_window, EINA_TRUE);
94         elm_win_title_set(toast_window, "toast");
95
96         elm_win_indicator_mode_set(toast_window, ELM_WIN_INDICATOR_SHOW);
97         elm_win_indicator_type_set(toast_window,ELM_WIN_INDICATOR_TYPE_1);
98
99         //elm_win_autodel_set(toast_win, EINA_TRUE);
100         if (elm_win_wm_rotation_supported_get(toast_window)) {
101                 int rots[4] = { 0, 90, 180, 270 };
102                 elm_win_wm_rotation_available_rotations_set(toast_window, (const int*)(&rots), 4);
103         }
104
105         e = evas_object_evas_get(toast_window);
106         ee = ecore_evas_ecore_evas_get(e);
107         ecore_evas_name_class_set(ee, "TOAST_POPUP", "SYSTEM_POPUP");
108
109         evas_object_resize(toast_window, (480 * scale), (650 * scale));
110         ecore_x_window_shape_input_rectangle_set(elm_win_xwindow_get(toast_window), 0, 0, (480 * scale), (650 * scale));
111
112         toast_popup = elm_popup_add(toast_window);
113
114         elm_object_style_set(toast_popup, "toast");
115         evas_object_size_hint_weight_set(toast_popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
116
117         elm_object_text_set(toast_popup,message);
118
119         if (eina_list_count(toast_list) != 1) {
120                 elm_popup_timeout_set(toast_popup, 1.0);
121         }
122         else {
123                 elm_popup_timeout_set(toast_popup, 3.0);
124         }
125         evas_object_smart_callback_add(toast_popup, "timeout", popup_timeout_cb, (void *)toast_window);
126
127         elm_win_prop_focus_skip_set(toast_window, EINA_TRUE);
128
129         evas_object_show(toast_window);
130         evas_object_show(toast_popup);
131
132         return 0;
133 }
134
135 int notification_noti_post_toast_message(const char *message)
136 {
137         int let = 0;
138         char *msg = NULL;
139         int count = 0;
140
141         msg = (char *)calloc(strlen(message) + 1, sizeof(char));
142         strcpy(msg, message);
143
144         count = eina_list_count(toast_list);
145         if (count == 0) {
146                 toast_list = eina_list_append(toast_list, msg);
147                 let = _post_toast_message(msg);
148         }
149         else if (count == 1) {
150                 if (strcmp(msg, (char *)eina_list_nth(toast_list, count - 1)) == 0) {
151                         elm_popup_timeout_set(toast_popup, 3.0);
152                 }
153                 else {
154                         toast_list = eina_list_append(toast_list, msg);
155                         elm_popup_timeout_set(toast_popup, 1.0);
156                 }
157         }
158         else if (count >= 2) {
159                 if (strcmp(msg, (char *)eina_list_nth(toast_list, count - 1)) == 0) {
160                         free(msg);
161                         return 0;
162                 }
163                 else {
164                         toast_list = eina_list_append(toast_list, msg);
165                 }
166         }
167
168         return 0;
169 }
170
171 static void __notification_status_message_dbus_callback(void *data, DBusMessage *msg)
172 {
173         int ret = 0;
174         DBusError err;
175         char *message = NULL;
176
177         if(data==NULL||msg==NULL)
178         {
179                 NOTIFICATION_ERR("message is NULL");
180                 return;
181         }
182
183         dbus_error_init(&err);
184         ret = dbus_message_get_args(msg, &err,
185                         DBUS_TYPE_STRING, &message,
186                         DBUS_TYPE_INVALID);
187         if(ret == 0)
188         {
189                 NOTIFICATION_ERR("dbus_message_get_args error");
190                 return;
191         }
192
193         if (dbus_error_is_set(&err)) {
194                 NOTIFICATION_ERR("Dbus err: %s", err.message);
195                 dbus_error_free(&err);
196                 return;
197         }
198         /*if (!md.callback)
199                 return;
200
201         if (strlen(message) <= 0){
202                 NOTIFICATION_ERR("message has only NULL");
203                 return;
204         }
205
206         md.callback(message, md.data);*/
207
208         notification_noti_post_toast_message(message);
209 }
210
211 EXPORT_API
212 int notification_status_message_post(const char *message)
213 {
214         DBusConnection *connection = NULL;
215         DBusMessage *signal = NULL;
216         DBusError err;
217         dbus_bool_t ret;
218
219         if (!message) {
220                 NOTIFICATION_ERR("message is NULL");
221                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
222         }
223
224         if (strlen(message) <= 0) {
225                 NOTIFICATION_ERR("message has only NULL");
226                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
227         }
228
229         dbus_error_init(&err);
230         connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
231         if (!connection) {
232                 NOTIFICATION_ERR("Fail to dbus_bus_get");
233                 return NOTIFICATION_ERROR_FROM_DBUS;
234         }
235
236         signal =
237             dbus_message_new_signal(PATH_NAME, INTERFACE_NAME,
238                                     MEMBER_NAME);
239         if (!signal) {
240                 NOTIFICATION_ERR("Fail to dbus_message_new_signal");
241                 return NOTIFICATION_ERROR_FROM_DBUS;
242         }
243
244         ret = dbus_message_append_args(signal,
245                                            DBUS_TYPE_STRING, &message,
246                                            DBUS_TYPE_INVALID);
247         if (ret) {
248                 ret = dbus_connection_send(connection, signal, NULL);
249
250                 if (ret) {
251                         dbus_connection_flush(connection);
252                 }
253         }
254
255         dbus_message_unref(signal);
256         dbus_connection_unref(connection);
257
258         return NOTIFICATION_ERROR_NONE;
259 }
260
261 EXPORT_API
262 int notification_status_monitor_message_cb_set(notification_status_message_cb callback, void *user_data)
263 {
264         if (!callback)
265                 return NOTIFICATION_ERROR_INVALID_PARAMETER;
266         E_DBus_Connection *dbus_connection;
267         E_DBus_Signal_Handler *dbus_handler_size = NULL;
268
269         e_dbus_init();
270         dbus_connection = e_dbus_bus_get(DBUS_BUS_SYSTEM);
271         if (dbus_connection == NULL) {
272                 NOTIFICATION_ERR("noti register : failed to get dbus bus");
273                 return NOTIFICATION_ERROR_FROM_DBUS;
274         }
275         dbus_handler_size =
276                 e_dbus_signal_handler_add(dbus_connection, NULL,
277                         PATH_NAME,
278                         INTERFACE_NAME, MEMBER_NAME,
279                         __notification_status_message_dbus_callback,
280                         user_data);
281         if (dbus_handler_size == NULL)
282         {
283                 NOTIFICATION_ERR("fail to add size signal");
284                 return NOTIFICATION_ERROR_FROM_DBUS;
285         }
286
287
288         md.callback = callback;
289         md.data = user_data;
290         md.dbus_connection = dbus_connection;
291         md.dbus_hdlr = dbus_handler_size;
292
293         return NOTIFICATION_ERROR_NONE;
294 }
295
296 EXPORT_API
297 int notification_status_monitor_message_cb_unset(void)
298 {
299         if (md.dbus_hdlr != NULL) {
300                         e_dbus_signal_handler_del(md.dbus_connection,
301                                         md.dbus_hdlr);
302                         md.dbus_hdlr = NULL;
303         }
304         if (md.dbus_connection != NULL) {
305                 e_dbus_connection_close(md.dbus_connection);
306                 md.dbus_connection = NULL;
307                 e_dbus_shutdown();
308         }
309
310         md.callback = NULL;
311         md.data = NULL;
312
313         return NOTIFICATION_ERROR_NONE;
314 }