sync with private git. updated the license and the boilerplates
[apps/core/preloaded/quickpanel.git] / daemon / notifications / noti.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *  http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <appsvc.h>
18
19 #include <time.h>
20 #include <vconf.h>
21 #include <appcore-common.h>
22 #include <app_service.h>
23 #include <Ecore_X.h>
24 #include <notification.h>
25
26 #include "quickpanel-ui.h"
27 #include "quickpanel_def.h"
28 #include "common.h"
29 #include "noti_node.h"
30 #include "noti_gridbox.h"
31 #include "noti_box.h"
32 #include "noti_listbox.h"
33 #include "noti_list_item.h"
34 #include "noti_section.h"
35 #include "noti.h"
36 #include "list_util.h"
37 #ifdef QP_SERVICE_NOTI_LED_ENABLE
38 #include "noti_led.h"
39 #endif
40
41 #ifndef VCONFKEY_QUICKPANEL_STARTED
42 #define VCONFKEY_QUICKPANEL_STARTED "memory/private/"PACKAGE_NAME"/started"
43 #endif /* VCONFKEY_QUICKPANEL_STARTED */
44
45 #define QP_NOTI_ONGOING_DBUS_PATH       "/dbus/signal"
46 #define QP_NOTI_ONGOING_DBUS_INTERFACE  "notification.ongoing"
47
48 static noti_node *g_noti_node;
49 static Evas_Object *g_noti_section;
50 static Evas_Object *g_noti_listbox;
51 static Evas_Object *g_noti_gridbox;
52
53 static int quickpanel_noti_init(void *data);
54 static int quickpanel_noti_fini(void *data);
55 static int quickpanel_noti_suspend(void *data);
56 static int quickpanel_noti_resume(void *data);
57 static void quickpanel_noti_lang_changed(void *data);
58 static void quickpanel_noti_refresh(void *data);
59
60 QP_Module noti = {
61         .name = "noti",
62         .init = quickpanel_noti_init,
63         .fini = quickpanel_noti_fini,
64         .suspend = quickpanel_noti_suspend,
65         .resume = quickpanel_noti_resume,
66         .lang_changed = quickpanel_noti_lang_changed,
67         .hib_enter = NULL,
68         .hib_leave = NULL,
69         .refresh = quickpanel_noti_refresh,
70         .get_height = NULL,
71 };
72
73 static notification_h _quickpanel_noti_update_item_progress(const char *pkgname,
74                                                             int priv_id,
75                                                             double progress)
76 {
77         char *noti_pkgname = NULL;
78         int noti_priv_id = 0;
79
80         noti_node_item *node = noti_node_get(g_noti_node, priv_id);
81
82         if (node != NULL && node->noti != NULL) {
83                 notification_get_pkgname(node->noti, &noti_pkgname);
84                 notification_get_id(node->noti, NULL, &noti_priv_id);
85                 if (!strcmp(noti_pkgname, pkgname)
86                     && priv_id == noti_priv_id) {
87
88                         if (notification_set_progress(node->noti, progress) != NOTIFICATION_ERROR_NONE) {
89                                 ERR("fail to set progress");
90                         }
91                         return node->noti;
92                 }
93         }
94
95         return NULL;
96 }
97
98 static notification_h _quickpanel_noti_update_item_size(const char *pkgname,
99                                                         int priv_id,
100                                                         double size)
101 {
102         char *noti_pkgname = NULL;
103         int noti_priv_id = 0;
104
105         noti_node_item *node = noti_node_get(g_noti_node, priv_id);
106
107         if (node != NULL && node->noti != NULL) {
108                 notification_get_pkgname(node->noti, &noti_pkgname);
109                 notification_get_id(node->noti, NULL, &noti_priv_id);
110                 if (!strcmp(noti_pkgname, pkgname)
111                     && priv_id == noti_priv_id) {
112                         notification_set_size(node->noti, size);
113                         return node->noti;
114                 }
115         }
116
117         return NULL;
118 }
119
120 static notification_h _quickpanel_noti_update_item_content(const char *pkgname,
121                                                         int priv_id,
122                                                         char *content)
123 {
124         char *noti_pkgname = NULL;
125         int noti_priv_id = 0;
126
127         noti_node_item *node = noti_node_get(g_noti_node, priv_id);
128
129         if (node != NULL && node->noti != NULL) {
130                 notification_get_pkgname(node->noti, &noti_pkgname);
131                 notification_get_id(node->noti, NULL, &noti_priv_id);
132                 if (!strcmp(noti_pkgname, pkgname)
133                     && priv_id == noti_priv_id) {
134                         notification_set_text(node->noti,
135                                 NOTIFICATION_TEXT_TYPE_CONTENT,
136                                 content, NULL,
137                                 NOTIFICATION_VARIABLE_TYPE_NONE);
138                         return node->noti;
139                 }
140         }
141
142         return NULL;
143 }
144
145 static void _quickpanel_noti_update_progressbar(void *data,
146                                                 notification_h update_noti)
147 {
148         struct appdata *ad = NULL;
149         Elm_Object_Item *found = NULL;
150         noti_node_item *node = NULL;
151
152         retif(!data, , "data is NULL");
153         ad = data;
154
155         retif(!ad->list, , "ad->list is NULL");
156
157         int priv_id = 0;
158
159         if (notification_get_id(update_noti, NULL, &priv_id) == NOTIFICATION_ERROR_NONE) {
160                 node = noti_node_get(g_noti_node, priv_id);
161
162                 if (node != NULL) {
163                         found = node->view;
164                 }
165         }
166
167         retif(node == NULL, , "fail to find node of priv_id:%d", priv_id);
168         retif(node->view == NULL, , "fail to find %p", node->view);
169
170         listbox_update_item(g_noti_listbox, node->view);
171 }
172
173 static void _quickpanel_noti_item_progress_update_cb(void *data,
174                                                 DBusMessage *msg)
175 {
176         DBusError err;
177         char *pkgname = 0;
178         int priv_id = 0;
179         double progress = 0;
180         notification_h noti = NULL;
181
182         retif(data == NULL || msg == NULL, , "Invalid parameter!");
183
184         dbus_error_init(&err);
185         dbus_message_get_args(msg, &err,
186                         DBUS_TYPE_STRING, &pkgname,
187                         DBUS_TYPE_INT32, &priv_id,
188                         DBUS_TYPE_DOUBLE, &progress,
189                         DBUS_TYPE_INVALID);
190
191         if (dbus_error_is_set(&err)) {
192                 ERR("dbus err: %s", err.message);
193                 dbus_error_free(&err);
194                 return;
195         }
196
197         if (pkgname == NULL) {
198                 ERR("pkgname is null");
199                 return;
200         }
201
202         /* check item on the list */
203         noti = _quickpanel_noti_update_item_progress(pkgname,
204                                                 priv_id, progress);
205         retif(noti == NULL, , "Can not found noti data.");
206
207         DBG("pkgname[%s], priv_id[%d], progress[%lf]",
208                                 pkgname, priv_id, progress);
209         if (!quickpanel_is_suspended())
210                 _quickpanel_noti_update_progressbar(data, noti);
211 }
212
213 static void _quickpanel_noti_item_size_update_cb(void *data, DBusMessage * msg)
214 {
215         DBusError err;
216         char *pkgname = 0;
217         int priv_id = 0;
218         double size = 0;
219         notification_h noti = NULL;
220
221         retif(data == NULL || msg == NULL, , "Invalid parameter!");
222
223         dbus_error_init(&err);
224         dbus_message_get_args(msg, &err,
225                         DBUS_TYPE_STRING, &pkgname,
226                         DBUS_TYPE_INT32, &priv_id,
227                         DBUS_TYPE_DOUBLE, &size, DBUS_TYPE_INVALID);
228         if (dbus_error_is_set(&err)) {
229                 ERR("dbus err: %s", err.message);
230                 dbus_error_free(&err);
231                 return;
232         }
233
234         if (pkgname == NULL) {
235                 ERR("pkgname is null");
236                 return;
237         }
238
239         /* check item on the list */
240         noti = _quickpanel_noti_update_item_size(pkgname, priv_id, size);
241         retif(noti == NULL, , "Can not found noti data.");
242
243         DBG("pkgname[%s], priv_id[%d], progress[%lf]",
244                                 pkgname, priv_id, size);
245
246         if (!quickpanel_is_suspended())
247                 _quickpanel_noti_update_progressbar(data, noti);
248 }
249
250 static void _quickpanel_noti_item_content_update_cb(void *data,
251                                                 DBusMessage *msg)
252 {
253         DBusError err;
254         char *pkgname = NULL;
255         int priv_id = 0;
256         char *content = NULL;
257         notification_h noti = NULL;
258
259         retif(data == NULL || msg == NULL, , "Invalid parameter!");
260
261         dbus_error_init(&err);
262         dbus_message_get_args(msg, &err,
263                         DBUS_TYPE_STRING, &pkgname,
264                         DBUS_TYPE_INT32, &priv_id,
265                         DBUS_TYPE_STRING, &content, DBUS_TYPE_INVALID);
266
267         if (pkgname == NULL) {
268                 ERR("pkgname  is null");
269                 return;
270         }
271         if (content == NULL) {
272                 ERR("content is null");
273                 return;
274         }
275
276         if (dbus_error_is_set(&err)) {
277                 ERR("dbus err: %s", err.message);
278                 dbus_error_free(&err);
279                 return;
280         }
281
282         DBG("pkgname[%s], priv_id[%d], content[%s]",
283                                 pkgname, priv_id, content);
284
285         /* check item on the list */
286         noti = _quickpanel_noti_update_item_content(pkgname, priv_id, content);
287         retif(noti == NULL, , "Can not found noti data.");
288
289         if (!quickpanel_is_suspended())
290                 _quickpanel_noti_update_progressbar(data, noti);
291 }
292
293 static void _quickpanel_do_noti_delete(notification_h noti) {
294         char *pkgname = NULL;
295         char *caller_pkgname = NULL;
296         int flags = 0, priv_id = 0, flag_delete = 0;
297         notification_type_e type = NOTIFICATION_TYPE_NONE;
298
299         quickpanel_play_feedback();
300
301         retif(noti == NULL, , "Invalid parameter!");
302
303         notification_get_pkgname(noti, &caller_pkgname);
304         notification_get_application(noti, &pkgname);
305         if (pkgname == NULL)
306                 pkgname = caller_pkgname;
307
308         notification_get_id(noti, NULL, &priv_id);
309         notification_get_property(noti, &flags);
310         notification_get_type(noti, &type);
311
312         if (flags & NOTIFICATION_PROP_PERMANENT_DISPLAY)
313                 flag_delete = 0;
314         else
315                 flag_delete = 1;
316
317         if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI) {
318                 notification_delete_by_priv_id(caller_pkgname, NOTIFICATION_TYPE_NOTI,
319                                 priv_id);
320         }
321 }
322
323 static void _quickpanel_do_noti_press(notification_h noti, int pressed_area) {
324         int ret = -1;
325         char *pkgname = NULL;
326         char *caller_pkgname = NULL;
327         bundle *args = NULL;
328         bundle *group_args = NULL;
329         bundle *responding_service_handle = NULL;
330         bundle *single_service_handle = NULL;
331         bundle *multi_service_handle = NULL;
332         int flags = 0, group_id = 0, priv_id = 0, count = 0, flag_launch = 0,
333                         flag_delete = 0;
334         notification_type_e type = NOTIFICATION_TYPE_NONE;
335
336         quickpanel_play_feedback();
337
338         retif(noti == NULL, , "Invalid parameter!");
339
340         notification_get_pkgname(noti, &caller_pkgname);
341         notification_get_application(noti, &pkgname);
342         if (pkgname == NULL)
343                 pkgname = caller_pkgname;
344
345         notification_get_id(noti, &group_id, &priv_id);
346         notification_get_property(noti, &flags);
347         notification_get_type(noti, &type);
348
349         if (flags & NOTIFICATION_PROP_DISABLE_APP_LAUNCH)
350                 flag_launch = 0;
351         else
352                 flag_launch = 1;
353
354         if (flags & NOTIFICATION_PROP_DISABLE_AUTO_DELETE)
355                 flag_delete = 0;
356         else
357                 flag_delete = 1;
358
359         notification_get_execute_option(noti,
360                         NOTIFICATION_EXECUTE_TYPE_RESPONDING,
361                                 NULL, &responding_service_handle);
362         notification_get_execute_option(noti,
363                                 NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH,
364                                 NULL, &single_service_handle);
365         notification_get_execute_option(noti,
366                                 NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH,
367                                 NULL, &multi_service_handle);
368
369         if (pressed_area == NOTI_PRESS_BUTTON_1 && responding_service_handle != NULL) {
370                 DBG("");
371                 quickpanel_close_quickpanel(true);
372                 ret = quickpanel_launch_app(NULL, responding_service_handle);
373                 quickpanel_launch_app_inform_result(pkgname, ret);
374         } else if (flag_launch == 1) {
375                 /* Hide quickpanel */
376                 quickpanel_close_quickpanel(true);
377
378                 char *text_count = NULL;
379                 notification_get_text(noti, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, &text_count);
380
381                 if (text_count != NULL) {
382                         count = atoi(text_count);
383                 } else {
384                         count = 1;
385                 }
386
387                 if (single_service_handle != NULL && multi_service_handle == NULL) {
388                         DBG("");
389                         ret = quickpanel_launch_app(NULL, single_service_handle);
390                         quickpanel_launch_app_inform_result(pkgname, ret);
391                 }
392                 if (single_service_handle == NULL && multi_service_handle != NULL) {
393                         DBG("");
394                         ret = quickpanel_launch_app(NULL, multi_service_handle);
395                         quickpanel_launch_app_inform_result(pkgname, ret);
396                 }
397                 if (single_service_handle != NULL && multi_service_handle != NULL) {
398                         DBG("");
399                         if (count <= 1) {
400                                 ret = quickpanel_launch_app(NULL, single_service_handle);
401                                 quickpanel_launch_app_inform_result(pkgname, ret);
402                         } else {
403                                 ret = quickpanel_launch_app(NULL, multi_service_handle);
404                                 quickpanel_launch_app_inform_result(pkgname, ret);
405                         }
406                 }
407                 if (single_service_handle == NULL && multi_service_handle == NULL) {
408                         DBG("");
409                         notification_get_args(noti, &args, &group_args);
410
411                         if (count > 1 && group_args != NULL) {
412                                 ret = quickpanel_launch_app(pkgname, group_args);
413                                 quickpanel_launch_app_inform_result(pkgname, ret);
414                         } else {
415                                 ret = quickpanel_launch_app(pkgname, args);
416                                 quickpanel_launch_app_inform_result(pkgname, ret);
417                         }
418                 }
419         }
420
421         if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI) {
422                 notification_delete_by_priv_id(caller_pkgname,
423                                 NOTIFICATION_TYPE_NOTI,
424                                 priv_id);
425         }
426 }
427
428 static void quickpanel_notibox_delete_cb(void *data, Evas_Object * obj) {
429         DBG("");
430         noti_node_item *item = data;
431         retif(item == NULL, , "Invalid parameter!");
432
433         notification_h noti = item->noti;
434         retif(noti == NULL, , "Invalid parameter!");
435
436         _quickpanel_do_noti_delete(noti);
437
438 }
439
440 static void quickpanel_notibox_button_1_cb(void *data, Evas_Object * obj) {
441         DBG("");
442         noti_node_item *item = data;
443         retif(item == NULL, , "Invalid parameter!");
444
445         notification_h noti = item->noti;
446         retif(noti == NULL, , "Invalid parameter!");
447
448         _quickpanel_do_noti_press(noti, NOTI_PRESS_BUTTON_1);
449 }
450
451 static void quickpanel_notibox_select_cb(void *data, Evas_Object * obj) {
452         DBG("");
453         noti_node_item *item = data;
454         retif(item == NULL, , "Invalid parameter!");
455
456         notification_h noti = item->noti;
457         retif(noti == NULL, , "Invalid parameter!");
458
459         _quickpanel_do_noti_press(noti, NOTI_PRESS_BG);
460 }
461
462 static void quickpanel_noti_listitem_select_cb(void *data, Evas_Object * obj) {
463         DBG("");
464         noti_node_item *item = data;
465         retif(item == NULL, , "Invalid parameter!");
466
467         notification_h noti = item->noti;
468         retif(noti == NULL, , "Invalid parameter!");
469
470         _quickpanel_do_noti_press(noti, NOTI_PRESS_BG);
471 }
472
473 static inline void __ongoing_comp_n_copy(notification_h old, notification_h new)
474 {
475         int priv_id = 0;
476         int new_priv_id = 0;
477         char *pkgname = NULL;
478         char *new_pkgname = NULL;
479
480         if (!old)
481                 return;
482
483         if (!new)
484                 return;
485
486         notification_get_id(old, NULL, &priv_id);
487         notification_get_id(new, NULL, &new_priv_id);
488
489         notification_get_pkgname(old, &pkgname);
490         notification_get_pkgname(new, &new_pkgname);
491
492         if (!pkgname || !new_pkgname)
493                 return;
494
495         if (!strcmp(pkgname, new_pkgname) && priv_id == new_priv_id) {
496                 double percentage = 0.0;
497                 double size = 0.0;
498                 time_t insert_time = 0;
499                 time_t new_insert_time = 0;
500
501                 notification_get_progress(old, &percentage);
502                 notification_get_size(old, &size);
503                 if (notification_set_progress(new, percentage) != NOTIFICATION_ERROR_NONE) {
504                         ERR("fail to set progress");
505                 }
506                 if (notification_set_size(new, size) != NOTIFICATION_ERROR_NONE) {
507                         ERR("fail to set size");
508                 }
509                 notification_get_insert_time(old, &insert_time);
510                 notification_get_insert_time(new, &new_insert_time);
511
512                 if (insert_time == new_insert_time) {
513                         char *content = NULL;
514                         notification_get_text(old,
515                                 NOTIFICATION_TEXT_TYPE_CONTENT, &content);
516                         notification_set_text(new,
517                                 NOTIFICATION_TEXT_TYPE_CONTENT, content,
518                                 NULL, NOTIFICATION_VARIABLE_TYPE_NONE);
519                 }
520         }
521 }
522
523 static void _quickpanel_noti_clear_ongoinglist()
524 {
525         if (g_noti_listbox != NULL) {
526                 listbox_remove_all_item(g_noti_listbox, EINA_FALSE);
527         }
528 }
529
530 static void _quickpanel_noti_clear_notilist(void)
531 {
532         if (g_noti_gridbox != NULL) {
533                 gridbox_remove_all_item(g_noti_gridbox, EINA_FALSE);
534         }
535 }
536
537 static void _quickpanel_noti_clear_list_all(void)
538 {
539         _quickpanel_noti_clear_ongoinglist();
540         _quickpanel_noti_clear_notilist();
541 }
542
543 static void _quickpanel_noti_section_add(void)
544 {
545         struct appdata *ad = quickpanel_get_app_data();
546         retif(ad == NULL, , "Invalid parameter!");
547         retif(ad->list == NULL, , "Invalid parameter!");
548
549         if (g_noti_section == NULL) {
550                 g_noti_section = noti_section_create(ad->list);
551                 if (g_noti_section != NULL) {
552                         quickpanel_list_util_sort_insert(ad->list, g_noti_section);
553                         DBG("noti section[%p]", g_noti_section);
554                 }
555         }
556 }
557
558 static void _quickpanel_noti_section_remove(void)
559 {
560         struct appdata *ad = quickpanel_get_app_data();
561         retif(ad == NULL, , "Invalid parameter!");
562         retif(ad->list == NULL, , "Invalid parameter!");
563
564         if (g_noti_section != NULL) {
565                 quickpanel_list_util_item_unpack_by_type(ad->list, QP_ITEM_TYPE_NOTI_GROUP);
566                 noti_section_remove(g_noti_section);
567                 g_noti_section = NULL;
568         }
569 }
570
571 static void _quickpanel_noti_box_deleted_cb(void *data, Evas_Object *obj) {
572         int priv_id = -1;
573
574         retif(data == NULL, , "Invalid parameter!");
575         DBG("deleting:%p", data);
576
577         noti_node_item *item = data;
578         notification_h noti = item->noti;
579
580         if (noti != NULL) {
581                 notification_get_id(noti, NULL, &priv_id);
582                 noti_node_remove(g_noti_node, priv_id);
583         }
584 }
585
586 static void _quickpanel_list_box_deleted_cb(void *data, Evas_Object *obj) {
587         int priv_id = -1;
588
589         retif(data == NULL, , "Invalid parameter!");
590         DBG("deleting:%p", data);
591
592         noti_node_item *item = data;
593         notification_h noti = item->noti;
594
595         if (noti != NULL) {
596                 notification_get_id(noti, NULL, &priv_id);
597                 noti_node_remove(g_noti_node, priv_id);
598         }
599 }
600
601 static void _quickpanel_noti_ongoing_add(Evas_Object *list, void *data, int is_prepend)
602 {
603         Evas_Object *noti_list_item = NULL;
604         notification_ly_type_e layout = NOTIFICATION_LY_ONGOING_EVENT;
605
606         retif(list == NULL, , "Invalid parameter!");
607         notification_h noti = data;
608
609         if (noti != NULL) {
610                 notification_get_layout(noti, &layout);
611                 noti_list_item = noti_list_item_create(g_noti_listbox, layout);
612
613                 if (noti_list_item != NULL) {
614                         noti_node_item *item = noti_node_add(g_noti_node, (void*)data, (void*)noti_list_item);
615                         if (item != NULL) {
616                                 noti_list_item_node_set(noti_list_item, item);
617                                 noti_list_item_set_item_selected_cb(noti_list_item, quickpanel_noti_listitem_select_cb);
618                                 listbox_add_item(g_noti_listbox, noti_list_item, is_prepend);
619                         }
620                 } else
621                         ERR("fail to insert item to list : %p", data);
622         }
623
624         DBG("noti[%p] data[%p] added listbox[%p]",
625                         data, noti_list_item, g_noti_listbox);
626 }
627
628 static void _quickpanel_noti_noti_add(Evas_Object *list, void *data, int is_prepend)
629 {
630         notification_h noti = data;
631         notification_ly_type_e layout = NOTIFICATION_LY_NOTI_EVENT_SINGLE;
632         Evas_Object *noti_box = NULL;
633
634         retif(list == NULL, , "Invalid parameter!");
635
636         if (g_noti_section == NULL) {
637                 _quickpanel_noti_section_add();
638         }
639
640         if (noti != NULL) {
641                 notification_get_layout(noti, &layout);
642                 Evas_Object *noti_box = noti_box_create(g_noti_gridbox, layout);
643
644                 if (noti_box != NULL) {
645                         noti_node_item *item = noti_node_add(g_noti_node, (void*)data, (void*)noti_box);
646                         if (item != NULL) {
647                                 noti_box_node_set(noti_box, item);
648                                 noti_box_set_item_selected_cb(noti_box, quickpanel_notibox_select_cb);
649                                 noti_box_set_item_button_1_cb(noti_box, quickpanel_notibox_button_1_cb);
650                                 noti_box_set_item_deleted_cb(noti_box, quickpanel_notibox_delete_cb);
651                                 gridbox_add_item(g_noti_gridbox, noti_box, is_prepend);
652                         }
653                 } else
654                         ERR("fail to insert item to list : %p", data);
655         }
656
657         int noti_count =
658                         noti_node_get_item_count(g_noti_node, NOTIFICATION_TYPE_NOTI);
659
660         if (g_noti_section != NULL) {
661                 noti_section_update(g_noti_section, noti_count);
662         }
663
664         DBG("noti[%p] view[%p] added gridbox[%p]",
665                         data, noti_box, g_noti_gridbox);
666 }
667
668 static void _quickpanel_noti_update_notilist(struct appdata *ad)
669 {
670         Evas_Object *list = NULL;
671         notification_h noti = NULL;
672         notification_h noti_save = NULL;
673         notification_list_h get_list = NULL;
674         int applist = NOTIFICATION_DISPLAY_APP_ALL;
675
676         DBG("");
677
678         retif(ad == NULL, , "Invalid parameter!");
679
680         list = ad->list;
681         retif(list == NULL, , "Failed to get noti genlist.");
682
683         _quickpanel_noti_clear_list_all();
684
685         notification_get_list(NOTIFICATION_TYPE_ONGOING, -1, &get_list);
686         while (get_list != NULL) {
687                 noti = notification_list_get_data(get_list);
688                 notification_get_display_applist(noti, &applist);
689
690                 if (applist &
691                     NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
692                         notification_clone(noti, &noti_save);
693                         _quickpanel_noti_ongoing_add(list, noti_save, LISTBOX_APPEND);
694                 }
695                 get_list = notification_list_get_next(get_list);
696         }
697         notification_free_list(get_list);
698
699         notification_get_list(NOTIFICATION_TYPE_NOTI , -1, &get_list);
700         while (get_list != NULL) {
701                 noti = notification_list_get_data(get_list);
702                 notification_get_display_applist(noti, &applist);
703
704                 if (applist &
705                     NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
706                         notification_clone(noti, &noti_save);
707                         _quickpanel_noti_noti_add(list, noti_save, GRIDBOX_APPEND);
708                 }
709                 get_list = notification_list_get_next(get_list);
710         }
711         notification_free_list(get_list);
712
713         if (g_noti_gridbox != NULL) {
714                 elm_box_recalculate(g_noti_gridbox);
715         }
716 }
717
718 static void _quickpanel_noti_delete_volatil_data(void)
719 {
720         notification_list_h noti_list = NULL;
721         notification_list_h noti_list_head = NULL;
722         notification_h noti = NULL;
723         int property = 0;
724
725         notification_get_grouping_list(NOTIFICATION_TYPE_NONE, -1, &noti_list);
726
727         noti_list_head = noti_list;
728
729         while (noti_list != NULL) {
730                 noti = notification_list_get_data(noti_list);
731                 notification_get_property(noti, &property);
732
733                 if (property & NOTIFICATION_PROP_VOLATILE_DISPLAY) {
734                         notification_set_property(noti,
735                                 property |
736                                 NOTIFICATION_PROP_DISABLE_UPDATE_ON_DELETE);
737                         notification_delete(noti);
738                 }
739
740                 noti_list = notification_list_get_next(noti_list);
741         }
742
743         notification_free_list(noti_list_head);
744
745         notification_update(NULL);
746 }
747
748 inline static void _print_debuginfo_from_noti(notification_h noti) {
749         retif(noti == NULL, , "Invalid parameter!");
750
751         char *noti_pkgname = NULL;
752         char *noti_launch_pkgname = NULL;
753         notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
754
755         notification_get_pkgname(noti, &noti_pkgname);
756         notification_get_application(noti, &noti_launch_pkgname);
757         notification_get_type(noti, &noti_type);
758
759         if (noti_pkgname != NULL) {
760                 ERR("pkg:%s", noti_pkgname);
761         }
762         if (noti_launch_pkgname != NULL) {
763                 ERR("pkgl:%s", noti_launch_pkgname);
764         }
765
766         ERR("type:%d", noti_type);
767 }
768
769 static void _quickpanel_noti_detailed_changed_cb(void *data, notification_type_e type, notification_op *op_list, int num_op)
770 {
771         int i = 0;
772         int op_type = 0;
773         int priv_id = 0;
774         struct appdata *ad = NULL;
775         notification_h noti_new = NULL;
776         notification_h noti_from_master = NULL;
777         notification_type_e noti_type = NOTIFICATION_TYPE_NONE;
778         int noti_applist = NOTIFICATION_DISPLAY_APP_ALL;
779         notification_ly_type_e noti_layout = NOTIFICATION_LY_NONE;
780
781         retif(data == NULL, , "Invalid parameter!");
782         ad = data;
783
784         ERR("num_op:%d", num_op);
785
786         for (i = 0; i < num_op; i++) {
787                 notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_TYPE, &op_type);
788                 notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_PRIV_ID, &priv_id);
789                 notification_op_get_data(op_list + i, NOTIFICATION_OP_DATA_NOTI, &noti_from_master);
790
791                 ERR("noti operation:%d privid:%d", op_type, priv_id);
792
793                 if (op_type == NOTIFICATION_OP_INSERT) {
794
795                         if (noti_from_master == NULL) {
796                                 ERR("failed to get a notification from master");
797                                 continue;
798                         }
799                         if (notification_clone(noti_from_master, &noti_new) != NOTIFICATION_ERROR_NONE) {
800                                 ERR("failed to create a cloned notification");
801                                 continue;
802                         }
803
804                         _print_debuginfo_from_noti(noti_new);
805 #ifdef QP_SERVICE_NOTI_LED_ENABLE
806                         quickpanel_service_noti_led_on(noti_new);
807 #endif
808
809                         notification_get_type(noti_new, &noti_type);
810                         notification_get_display_applist(noti_new, &noti_applist);
811                         notification_get_layout(noti_new, &noti_layout);
812
813                         if (noti_applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
814                                 noti_node_item *node = noti_node_get(g_noti_node, priv_id);
815                                 if (node != NULL) {
816                                         if (noti_type == NOTIFICATION_TYPE_NOTI) {
817                                                 DBG("cb after inserted:%d", priv_id);
818                                         }
819                                         notification_free(noti_new);
820                                 } else {
821                                         if (noti_type == NOTIFICATION_TYPE_NOTI) {
822                                                 _quickpanel_noti_noti_add(ad->list, noti_new, GRIDBOX_PREPEND);
823                                         } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
824                                                 _quickpanel_noti_ongoing_add(ad->list, noti_new, LISTBOX_PREPEND);
825                                         }
826                                 }
827                         } else {
828                                 notification_free(noti_new);
829                         }
830                 } else if (op_type == NOTIFICATION_OP_DELETE) {
831                         noti_node_item *node = noti_node_get(g_noti_node, priv_id);
832
833                         if (node != NULL && node->noti != NULL) {
834                                 notification_h noti = node->noti;
835                                 notification_get_type(noti, &noti_type);
836
837 #ifdef QP_SERVICE_NOTI_LED_ENABLE
838                                 quickpanel_service_noti_led_off(noti);
839 #endif
840                                 _print_debuginfo_from_noti(noti);
841
842                                 if (noti_type == NOTIFICATION_TYPE_NOTI) {
843                                         gridbox_remove_item(g_noti_gridbox, node->view, 0);
844                                 } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
845                                         listbox_remove_item(g_noti_listbox, node->view, 0);
846                                 }
847                                 noti_node_remove(g_noti_node, priv_id);
848                         }
849                 } else if (op_type == NOTIFICATION_OP_UPDATE) {
850                         noti_node_item *node = noti_node_get(g_noti_node, priv_id);
851                         notification_h old_noti = NULL;
852
853                         if (noti_from_master == NULL) {
854                                 ERR("failed to get a notification from master");
855                                 continue;
856                         }
857                         if (notification_clone(noti_from_master, &noti_new) != NOTIFICATION_ERROR_NONE) {
858                                 ERR("failed to create a cloned notification");
859                                 continue;
860                         }
861
862 #ifdef QP_SERVICE_NOTI_LED_ENABLE
863                         quickpanel_service_noti_led_on(noti_new);
864 #endif
865                         _print_debuginfo_from_noti(noti_new);
866
867                         if (node != NULL && node->view != NULL && node->noti != NULL) {
868                                 notification_get_type(noti_new, &noti_type);
869
870                                 if (noti_type == NOTIFICATION_TYPE_NOTI) {
871                                         gridbox_remove_item(g_noti_gridbox, node->view, 0);
872                                         _quickpanel_noti_noti_add(ad->list, noti_new, GRIDBOX_PREPEND);
873 /*
874                                         gridbox_remove_and_add_item(g_noti_gridbox, node->view,
875                                                         _quickpanel_noti_noti_add
876                                                         ,ad->list, noti_new, GRIDBOX_PREPEND);
877 */
878                                 } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
879                                         old_noti = node->noti;
880                                         node->noti = noti_new;
881
882                                         listbox_update_item(g_noti_listbox, node->view);
883                                 }
884
885                                 if (old_noti != NULL) {
886                                         notification_free(old_noti);
887                                 }
888                         } else {
889                                 notification_get_display_applist(noti_new, &noti_applist);
890
891                                 if (noti_applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY) {
892                                         if (noti_type == NOTIFICATION_TYPE_NOTI) {
893                                                 _quickpanel_noti_noti_add(ad->list, noti_new, GRIDBOX_PREPEND);
894                                         } else if (noti_type == NOTIFICATION_TYPE_ONGOING) {
895                                                 _quickpanel_noti_ongoing_add(ad->list, noti_new, GRIDBOX_PREPEND);
896                                         }
897                                 } else {
898                                         notification_free(noti_new);
899                                 }
900                         }
901                 } else if (op_type == NOTIFICATION_OP_REFRESH) {
902                         _quickpanel_noti_update_notilist(ad);
903                 } else if (op_type == NOTIFICATION_OP_SERVICE_READY) {
904                         _quickpanel_noti_update_notilist(ad);
905
906 #ifdef QP_SERVICE_NOTI_LED_ENABLE
907                         quickpanel_service_noti_init(ad);
908                         quickpanel_service_noti_led_on(NULL);
909 #endif
910                 }
911         }
912
913         int noti_count = 0;
914
915         if ((noti_count = noti_node_get_item_count(g_noti_node, NOTIFICATION_TYPE_NOTI))
916                         <= 0) {
917                 _quickpanel_noti_clear_notilist();
918                 _quickpanel_noti_section_remove();
919         } else {
920                 if (g_noti_section != NULL) {
921                         noti_section_update(g_noti_section, noti_count);
922                 }
923         }
924
925         ERR("current noti count:%d", noti_count);
926 }
927
928 static void _quickpanel_noti_update_desktop_cb(keynode_t *node, void *data)
929 {
930         char *event = NULL;
931         char type[10] = {0,};
932         char package[1024] = {0,};
933
934         event = vconf_get_str(vconf_keynode_get_name(node));
935         retif(NULL == event, , "invalid event");
936
937         DBG("%s", event);
938
939         if (sscanf(event, "%10[^:]:%1023s", type, package) != 2) {
940                 DBG("Failed to parse the event format : [%s], [%s]", type, package);
941         }
942
943         if (strncasecmp(type, "delete", strlen(type)) == 0) {
944                 notification_delete_all_by_type(package, NOTIFICATION_TYPE_NONE);
945         }
946
947         if (event != NULL)
948                 free(event);
949 }
950
951 static void _quickpanel_noti_update_sim_status_cb(keynode_t *node, void *data)
952 {
953         struct appdata *ad = data;
954
955         if (ad != NULL && ad->list != NULL) {
956                 _quickpanel_noti_update_notilist(ad);
957         }
958 }
959
960 static int _quickpanel_noti_register_event_handler(struct appdata *ad)
961 {
962         int ret = 0;
963         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
964
965         /* Add dbus signal */
966         e_dbus_init();
967         ad->dbus_connection = e_dbus_bus_get(DBUS_BUS_SYSTEM);
968         if (ad->dbus_connection == NULL) {
969                 ERR("noti register : failed to get dbus bus");
970                 return -1;
971         }
972
973         ad->dbus_handler_size =
974                 e_dbus_signal_handler_add(ad->dbus_connection, NULL,
975                         QP_NOTI_ONGOING_DBUS_PATH,
976                         QP_NOTI_ONGOING_DBUS_INTERFACE, "update_progress",
977                         _quickpanel_noti_item_progress_update_cb,
978                         ad);
979         if (ad->dbus_handler_size == NULL)
980                 ERR("fail to add size signal");
981
982         ad->dbus_handler_progress =
983                 e_dbus_signal_handler_add(ad->dbus_connection, NULL,
984                         QP_NOTI_ONGOING_DBUS_PATH,
985                         QP_NOTI_ONGOING_DBUS_INTERFACE, "update_size",
986                         _quickpanel_noti_item_size_update_cb,
987                         ad);
988         if (ad->dbus_handler_progress == NULL)
989                 ERR("fail to add progress signal");
990
991         ad->dbus_handler_content =
992                 e_dbus_signal_handler_add(ad->dbus_connection, NULL,
993                         QP_NOTI_ONGOING_DBUS_PATH,
994                         QP_NOTI_ONGOING_DBUS_INTERFACE, "update_content",
995                         _quickpanel_noti_item_content_update_cb,
996                         ad);
997         if (ad->dbus_handler_content == NULL)
998                 ERR("fail to add content signal");
999
1000         /* Notify vconf key */
1001         ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SIM_SLOT,
1002                                        _quickpanel_noti_update_sim_status_cb,
1003                                        (void *)ad);
1004         if (ret != 0)
1005                 ERR("Failed to register SIM_SLOT change callback!");
1006
1007         /* Notify vconf key */
1008         ret = vconf_notify_key_changed(VCONFKEY_MENUSCREEN_DESKTOP,
1009                                        _quickpanel_noti_update_desktop_cb,
1010                                        (void *)ad);
1011         if (ret != 0)
1012                 ERR("Failed to register DESKTOP change callback!");
1013
1014         /* Register notification changed cb */
1015         notification_register_detailed_changed_cb(_quickpanel_noti_detailed_changed_cb, ad);
1016
1017         return ret;
1018 }
1019
1020 static int _quickpanel_noti_unregister_event_handler(struct appdata *ad)
1021 {
1022         int ret = 0;
1023
1024         /* Unregister notification changed cb */
1025         notification_unregister_detailed_changed_cb(_quickpanel_noti_detailed_changed_cb, (void *)ad);
1026
1027         /* Ignore vconf key */
1028         ret = vconf_ignore_key_changed(VCONFKEY_MENUSCREEN_DESKTOP,
1029                         _quickpanel_noti_update_desktop_cb);
1030         if (ret != 0)
1031                 ERR("Failed to ignore DESKTOP change callback!");
1032
1033         ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SIM_SLOT,
1034                                 _quickpanel_noti_update_sim_status_cb);
1035         if (ret != 0)
1036                 ERR("Failed to ignore SIM_SLOT change callback!");
1037
1038         /* Delete dbus signal */
1039         if (ad->dbus_handler_size != NULL) {
1040                 e_dbus_signal_handler_del(ad->dbus_connection,
1041                                 ad->dbus_handler_size);
1042                 ad->dbus_handler_size = NULL;
1043         }
1044         if (ad->dbus_handler_progress != NULL) {
1045                 e_dbus_signal_handler_del(ad->dbus_connection,
1046                                 ad->dbus_handler_progress);
1047                 ad->dbus_handler_progress = NULL;
1048         }
1049         if (ad->dbus_handler_content != NULL) {
1050                 e_dbus_signal_handler_del(ad->dbus_connection,
1051                                 ad->dbus_handler_content);
1052                 ad->dbus_handler_content = NULL;
1053         }
1054
1055         if (ad->dbus_connection != NULL) {
1056                 e_dbus_connection_close(ad->dbus_connection);
1057                 ad->dbus_connection = NULL;
1058         }
1059
1060         return QP_OK;
1061 }
1062
1063 static int _quickpanel_noti_check_first_start(void)
1064 {
1065         int status = 0;
1066         int ret = 0;
1067
1068         ret = vconf_get_bool(VCONFKEY_QUICKPANEL_STARTED, &status);
1069         if (ret == 0 && status == 0) {
1070                 /* reboot */
1071                 ret = vconf_set_bool(VCONFKEY_QUICKPANEL_STARTED, 1);
1072                 INFO("set : %s, result : %d", VCONFKEY_QUICKPANEL_STARTED, ret);
1073         }
1074
1075         if (status)
1076                 return 0;
1077
1078         return 1;
1079 }
1080
1081 static void _quickpanel_noti_init(void *data)
1082 {
1083         struct appdata *ad = NULL;
1084
1085         retif(data == NULL, , "Invalid parameter!");
1086         ad = data;
1087
1088         retif(ad->list == NULL, , "Invalid parameter!");
1089
1090         DBG("wr");
1091
1092         if (g_noti_listbox == NULL) {
1093                 g_noti_listbox = listbox_create(ad->list, quickpanel_get_app_data());
1094                 listbox_set_item_deleted_cb(g_noti_listbox, _quickpanel_list_box_deleted_cb);
1095                 quickpanel_list_util_sort_insert(ad->list, g_noti_listbox);
1096         }
1097
1098         if (g_noti_gridbox == NULL) {
1099                 g_noti_gridbox = gridbox_create(ad->list, quickpanel_get_app_data());
1100                 gridbox_set_item_deleted_cb(g_noti_gridbox, _quickpanel_noti_box_deleted_cb);
1101                 quickpanel_list_util_sort_insert(ad->list, g_noti_gridbox);
1102         }
1103 }
1104
1105 static void _quickpanel_noti_fini(void *data)
1106 {
1107         struct appdata *ad = NULL;
1108
1109         retif(data == NULL, , "Invalid parameter!");
1110         ad = data;
1111
1112         retif(ad->list == NULL, , "Invalid parameter!");
1113
1114         DBG("dr");
1115
1116         if (g_noti_listbox != NULL) {
1117                 quickpanel_list_util_item_unpack_by_object(ad->list
1118                                 , g_noti_listbox);
1119                 listbox_remove(g_noti_listbox);
1120                 g_noti_listbox = NULL;
1121         }
1122
1123         if (g_noti_gridbox != NULL) {
1124                 quickpanel_list_util_item_unpack_by_object(ad->list
1125                                 , g_noti_gridbox);
1126                 gridbox_remove(g_noti_gridbox);
1127                 g_noti_gridbox = NULL;
1128         }
1129 }
1130
1131 static void _quickpanel_noti_cleanup(void *data) {
1132         notifiation_clear(NOTIFICATION_TYPE_ONGOING);
1133         _quickpanel_noti_delete_volatil_data();
1134 }
1135
1136 static int quickpanel_noti_init(void *data)
1137 {
1138         struct appdata *ad = data;
1139         int is_first = 0;
1140
1141         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
1142
1143         noti_node_create(&g_noti_node);
1144
1145         is_first = _quickpanel_noti_check_first_start();
1146         if (is_first) {
1147                 if (notification_is_service_ready()) {
1148                         _quickpanel_noti_cleanup(ad);
1149                 } else {
1150                         notification_add_deffered_task(_quickpanel_noti_cleanup, ad);
1151                 }
1152         }
1153
1154         _quickpanel_noti_init(ad);
1155
1156         _quickpanel_noti_register_event_handler(ad);
1157
1158         return QP_OK;
1159 }
1160
1161 static int quickpanel_noti_fini(void *data)
1162 {
1163         struct appdata *ad = data;
1164         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
1165
1166 #ifdef QP_SERVICE_NOTI_LED_ENABLE
1167         quickpanel_service_noti_fini(ad);
1168         quickpanel_service_noti_led_off(NULL);
1169 #endif
1170
1171         /* Unregister event handler */
1172         _quickpanel_noti_unregister_event_handler(data);
1173
1174         _quickpanel_noti_clear_list_all();
1175
1176         _quickpanel_noti_fini(ad);
1177
1178         if (g_noti_node != NULL) {
1179                 noti_node_destroy(&g_noti_node);
1180         }
1181
1182         return QP_OK;
1183 }
1184
1185 static int quickpanel_noti_suspend(void *data)
1186 {
1187         struct appdata *ad = data;
1188         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
1189
1190         return QP_OK;
1191 }
1192
1193 static int quickpanel_noti_resume(void *data)
1194 {
1195         struct appdata *ad = data;
1196         retif(ad == NULL, QP_FAIL, "Invalid parameter!");
1197
1198         if (ad->list) {
1199                 listbox_update(g_noti_listbox);
1200         }
1201
1202         return QP_OK;
1203 }
1204
1205 static void quickpanel_noti_refresh(void *data) {
1206         struct appdata *ad = NULL;
1207
1208         retif(data == NULL, , "Invalid parameter!");
1209         ad = data;
1210
1211         if (g_noti_gridbox != NULL) {
1212                 gridbox_rotation(g_noti_gridbox, ad->angle);
1213         }
1214 }
1215
1216 static void quickpanel_noti_lang_changed(void *data)
1217 {
1218         struct appdata *ad = data;
1219
1220         retif(ad == NULL, , "Invalid parameter!");
1221
1222         _quickpanel_noti_update_notilist(ad);
1223 }