c873185c9339e3caf6e948408b651a389d250c6c
[apps/home/quickpanel.git] / daemon / notifications / ticker.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (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 <Elementary.h>
18 #include <Ecore_X.h>
19 #include <appcore-common.h>
20 #include <vconf.h>
21 #include <appsvc.h>
22 #include <app_service.h>
23 #include <notification.h>
24 #include <feedback.h>
25
26 #include "quickpanel-ui.h"
27 #include "common.h"
28 #include "noti.h"
29 #include "noti_win.h"
30 #include "noti_util.h"
31
32 #define QP_TICKER_DURATION      5
33 #define QP_TICKER_DETAIL_DURATION 6
34
35 #define TICKER_MSG_LEN                          1024
36 #define DEFAULT_ICON ICONDIR            "/quickpanel_icon_default.png"
37
38 #define E_DATA_IS_TICKERNOTI_CONTENT "E_DATA_TN_CONTENT"
39 #define E_DATA_IS_TICKERNOTI_EXECUTED "E_DATA_TN_EXECUTED"
40
41 #define FORMAT_1LINE "<font_size=29><color=#BABABA>%s</color></font>"
42 #define FORMAT_2LINE "<font_size=26><color=#BABABA>%s</color></font><br><font_size=29><color=#F4F4F4>%s</color></font>"
43 #define FORMAT_2LINE_SINGLE "<font_size=26><color=#BABABA>%s</color></font><br><font_size=29><color=#F4F4F4>%s %s</color></font>"
44 #define FORMAT_2LINE_MULTI "<font_size=26><color=#BABABA>%s</color></font><br><font_size=29><color=#F4F4F4>%s %s</color></font>"
45
46 static Evas_Object *g_window;
47 static Evas_Object *g_ticker;
48 static Ecore_Timer *g_timer;
49 static int g_noti_height;
50
51 static int quickpanel_ticker_init(void *data);
52 static int quickpanel_ticker_fini(void *data);
53 static int quickpanel_ticker_enter_hib(void *data);
54 static int quickpanel_ticker_leave_hib(void *data);
55 static void quickpanel_ticker_reflesh(void *data);
56 static void _quickpanel_ticker_destroy_tickernoti(Evas_Object *tickernoti);
57
58 QP_Module ticker = {
59         .name = "ticker",
60         .init = quickpanel_ticker_init,
61         .fini = quickpanel_ticker_fini,
62         .hib_enter = quickpanel_ticker_enter_hib,
63         .hib_leave = quickpanel_ticker_leave_hib,
64         .lang_changed = NULL,
65         .refresh = quickpanel_ticker_reflesh
66 };
67
68 static int _is_lockscreen_launched(void) {
69         int ret = 0;
70         int is_lock_launched = VCONFKEY_IDLE_UNLOCK;
71
72         if ((ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &is_lock_launched)) == 0) {
73                 if (ret == 0 && is_lock_launched == VCONFKEY_IDLE_LOCK) {
74                         return 1;
75                 }
76         }
77
78         return 0;
79 }
80
81 /*****************************************************************************
82  *
83  * (Static) Util functions
84  *
85  *****************************************************************************/
86 static void _quickpanel_ticker_clicked_cb(void *data, Evas_Object *obj,
87                         const char *emission, const char *source) {
88         int ret = -1;
89         char *pkgname = NULL;
90         char *caller_pkgname = NULL;
91         bundle *args = NULL;
92         bundle *group_args = NULL;
93         bundle *single_service_handle = NULL;
94         bundle *multi_service_handle = NULL;
95         int flags = 0, group_id = 0, priv_id = 0, count = 0, flag_launch = 0,
96                         flag_delete = 0;
97         notification_type_e type = NOTIFICATION_TYPE_NONE;
98         notification_h noti = NULL;
99         int *is_ticker_executed = NULL;
100
101         noti = data;
102         retif(noti == NULL, , "Invalid parameter!");
103
104         quickpanel_play_feedback();
105
106         if (_is_lockscreen_launched()) {
107                 return ;
108         }
109
110         notification_get_pkgname(noti, &caller_pkgname);
111         notification_get_application(noti, &pkgname);
112         if (pkgname == NULL)
113                 pkgname = caller_pkgname;
114
115         notification_get_id(noti, &group_id, &priv_id);
116         notification_get_property(noti, &flags);
117         notification_get_type(noti, &type);
118
119         if (flags & NOTIFICATION_PROP_DISABLE_APP_LAUNCH) {
120                 flag_launch = 0;
121         } else {
122                 is_ticker_executed = evas_object_data_get(obj, E_DATA_IS_TICKERNOTI_EXECUTED);
123                 if (is_ticker_executed != NULL) {
124                         if (*is_ticker_executed == 0) {
125                                 flag_launch = 1;
126                                 *is_ticker_executed = 1;
127                         } else {
128                                 flag_launch = 0;
129                         }
130                 } else {
131                         flag_launch = 0;
132                 }
133         }
134
135         if (flags & NOTIFICATION_PROP_DISABLE_AUTO_DELETE)
136                 flag_delete = 0;
137         else
138                 flag_delete = 1;
139
140         notification_get_execute_option(noti,
141                                 NOTIFICATION_EXECUTE_TYPE_SINGLE_LAUNCH,
142                                 NULL, &single_service_handle);
143         notification_get_execute_option(noti,
144                                 NOTIFICATION_EXECUTE_TYPE_MULTI_LAUNCH,
145                                 NULL, &multi_service_handle);
146
147         if (flag_launch == 1) {
148                 /* Hide quickpanel */
149                 quickpanel_close_quickpanel(true);
150
151                 char *text_count = NULL;
152                 notification_get_text(noti, NOTIFICATION_TEXT_TYPE_EVENT_COUNT, &text_count);
153
154                 if (text_count != NULL) {
155                         count = atoi(text_count);
156                 } else {
157                         count = 1;
158                 }
159
160                 if (single_service_handle != NULL && multi_service_handle == NULL) {
161                         ret = quickpanel_launch_app(NULL, single_service_handle);
162                         quickpanel_launch_app_inform_result(pkgname, ret);
163                 }
164                 if (single_service_handle == NULL && multi_service_handle != NULL) {
165                         ret = quickpanel_launch_app(NULL, multi_service_handle);
166                         quickpanel_launch_app_inform_result(pkgname, ret);
167                 }
168                 if (single_service_handle != NULL && multi_service_handle != NULL) {
169                         if (count <= 1) {
170                                 ret = quickpanel_launch_app(NULL, single_service_handle);
171                                 quickpanel_launch_app_inform_result(pkgname, ret);
172                         } else {
173                                 ret = quickpanel_launch_app(NULL, multi_service_handle);
174                                 quickpanel_launch_app_inform_result(pkgname, ret);
175                         }
176                 }
177                 if (single_service_handle == NULL && multi_service_handle == NULL) {
178                         notification_get_args(noti, &args, &group_args);
179
180                         if (count > 1 && group_args != NULL) {
181                                 ret = quickpanel_launch_app(pkgname, group_args);
182                                 quickpanel_launch_app_inform_result(pkgname, ret);
183                         } else {
184                                 ret = quickpanel_launch_app(pkgname, args);
185                                 quickpanel_launch_app_inform_result(pkgname, ret);
186                         }
187                 }
188         }
189
190         if (flag_delete == 1 && type == NOTIFICATION_TYPE_NOTI) {
191                 notification_delete_by_priv_id(caller_pkgname,
192                                 NOTIFICATION_TYPE_NOTI,
193                                 priv_id);
194         }
195 }
196
197 static inline void __ticker_only_noti_del(notification_h noti)
198 {
199         int applist = NOTIFICATION_DISPLAY_APP_ALL;
200
201         retif(noti == NULL, ,"noti is null");
202
203         notification_get_display_applist(noti, &applist);
204         if (applist & NOTIFICATION_DISPLAY_APP_TICKER) {
205                 if (!(applist & NOTIFICATION_DISPLAY_APP_NOTIFICATION_TRAY)) {
206                         char *pkgname = NULL;
207                         int priv_id = 0;
208
209                         notification_get_pkgname(noti, &pkgname);
210                         notification_get_id(noti, NULL, &priv_id);
211                         notification_delete_by_priv_id(pkgname,
212                                                 NOTIFICATION_TYPE_NONE,
213                                                 priv_id);
214                 }
215         }
216 }
217
218 static void _quickpanel_ticker_hide(void *data)
219 {
220         if (g_ticker) {
221                 evas_object_hide(g_ticker);
222                 _quickpanel_ticker_destroy_tickernoti(g_ticker);
223                 g_ticker = NULL;
224         }
225 }
226
227 static Eina_Bool _quickpanel_ticker_timeout_cb(void *data)
228 {
229         INFO("ticker dismissed by timeout callback");
230
231         g_timer = NULL;
232
233         _quickpanel_ticker_hide(data);
234
235         return ECORE_CALLBACK_CANCEL;
236 }
237
238 static void _quickpanel_ticker_detail_hide_cb(void *data, Evas *e,
239                                         Evas_Object *obj,
240                                         void *event_info)
241 {
242         INFO("ticker dismissed by touching a hide button");
243
244         notification_h noti = (notification_h) data;
245
246         if (g_timer) {
247                 ecore_timer_del(g_timer);
248                 g_timer = NULL;
249         }
250
251         retif(noti == NULL, , "Invalid parameter!");
252
253         __ticker_only_noti_del(noti);
254         notification_free(noti);
255 }
256
257 static void _quickpanel_ticker_detail_show_cb(void *data, Evas *e,
258                                         Evas_Object *obj,
259                                         void *event_info)
260 {
261         DBG("");
262 }
263
264 static void _quickpanel_ticker_button_clicked_cb(void *data, Evas_Object *obj,
265                                         void *event_info)
266 {
267         if (g_timer) {
268                 ecore_timer_del(g_timer);
269                 g_timer = NULL;
270         }
271
272         _quickpanel_ticker_hide(data);
273 }
274
275 static Evas_Object *_quickpanel_ticker_create_button(Evas_Object *parent,
276                                                 notification_h noti)
277 {
278         Evas_Object *button = NULL;
279
280         retif(noti == NULL || parent == NULL, NULL, "Invalid parameter!");
281
282         if (_is_lockscreen_launched()) {
283                 return NULL;
284         }
285
286         button = elm_button_add(parent);
287         elm_object_style_set(button, "tickernoti");
288         elm_object_text_set(button, _S("IDS_COM_BODY_CLOSE"));
289         evas_object_smart_callback_add(button, "clicked",
290                                 _quickpanel_ticker_button_clicked_cb, noti);
291
292         return button;
293 }
294
295 static Evas_Object *_quickpanel_ticker_create_icon(Evas_Object *parent,
296                                                 notification_h noti)
297 {
298         char *icon_path = NULL;
299         Evas_Object *icon = NULL;
300
301         retif(noti == NULL || parent == NULL, NULL, "Invalid parameter!");
302
303         notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, &icon_path);
304         icon = elm_image_add(parent);
305
306         if (icon_path == NULL
307             || (elm_image_file_set(icon, icon_path, NULL) == EINA_FALSE)) {
308                 elm_image_file_set(icon, DEFAULT_ICON, NULL);
309                 elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
310         }
311
312         return icon;
313 }
314
315 static inline char *_get_text(notification_h noti, notification_text_type_e text_type) {
316         time_t time = 0;
317         char *text = NULL;
318         char buf[TICKER_MSG_LEN] = { 0, };
319
320         if (notification_get_time_from_text(noti, text_type, &time) == NOTIFICATION_ERROR_NONE) {
321                 if ((int)time > 0) {
322                         quickpanel_noti_get_time(time, buf, sizeof(buf));
323                         text = buf;
324                 }
325         } else {
326                 notification_get_text(noti, text_type, &text);
327         }
328
329         if (text != NULL)
330                 return elm_entry_utf8_to_markup(text);
331
332         return NULL;
333 }
334
335 static char *_quickpanel_ticker_get_label_layout_default(notification_h noti)
336 {
337         char buf[TICKER_MSG_LEN] = { 0, };
338         int len = 0;
339         char *domain = NULL;
340         char *dir = NULL;
341         char *title_utf8 = NULL;
342         char *content_utf8 = NULL;
343         char *event_count_utf8 = NULL;
344
345         retif(noti == NULL, NULL, "Invalid parameter!");
346
347         notification_get_text_domain(noti, &domain, &dir);
348         if (domain != NULL && dir != NULL)
349                 bindtextdomain(domain, dir);
350
351         title_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE);
352         content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT);
353
354         event_count_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_EVENT_COUNT);
355
356         if (event_count_utf8 == NULL) {
357                 if (title_utf8 && content_utf8) {
358                         len = snprintf(buf, sizeof(buf),FORMAT_2LINE, title_utf8, content_utf8);
359                 } else if (title_utf8) {
360                         len = snprintf(buf, sizeof(buf),FORMAT_1LINE, title_utf8);
361                 }
362         } else {
363                 if (title_utf8 && content_utf8) {
364                         len = snprintf(buf, sizeof(buf),FORMAT_2LINE_MULTI, title_utf8, event_count_utf8, content_utf8);
365                 } else if (title_utf8) {
366                         len = snprintf(buf, sizeof(buf),FORMAT_1LINE, title_utf8);
367                 }
368         }
369
370         if (title_utf8)
371                 free(title_utf8);
372
373         if (content_utf8)
374                 free(content_utf8);
375
376         if (event_count_utf8)
377                 free(event_count_utf8);
378
379         if (len > 0)
380                 return strdup(buf);
381
382         return NULL;
383 }
384
385 static char *_quickpanel_ticker_get_label_layout_single(notification_h noti)
386 {
387         char buf[TICKER_MSG_LEN] = { 0, };
388         int len = 0;
389         char *domain = NULL;
390         char *dir = NULL;
391         char *title_utf8 = NULL;
392         char *content_utf8 = NULL;
393         char *info_1_utf8 = NULL;
394         char *info_sub_1_utf8 = NULL;
395
396         retif(noti == NULL, NULL, "Invalid parameter!");
397
398         notification_get_text_domain(noti, &domain, &dir);
399         if (domain != NULL && dir != NULL)
400                 bindtextdomain(domain, dir);
401
402         title_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE);
403         content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT);
404
405         info_1_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_1);
406         info_sub_1_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_1);
407
408         if (info_1_utf8 == NULL) {
409                 if (title_utf8 && content_utf8) {
410                         len = snprintf(buf, sizeof(buf),FORMAT_2LINE, title_utf8, content_utf8);
411                 } else if (title_utf8) {
412                         len = snprintf(buf, sizeof(buf),FORMAT_1LINE, title_utf8);
413                 }
414         } else {
415                 if (info_sub_1_utf8) {
416                         if (content_utf8)
417                                 len = snprintf(buf, sizeof(buf), FORMAT_2LINE_SINGLE, content_utf8, info_1_utf8, info_sub_1_utf8);
418                         else if (title_utf8)
419                                 len = snprintf(buf, sizeof(buf), FORMAT_2LINE_SINGLE, title_utf8, info_1_utf8, info_sub_1_utf8);
420                 } else {
421                         if (content_utf8)
422                                 len = snprintf(buf, sizeof(buf), FORMAT_2LINE, content_utf8, info_1_utf8);
423                         else if (title_utf8)
424                                 len = snprintf(buf, sizeof(buf), FORMAT_2LINE, title_utf8, info_1_utf8);
425                 }
426         }
427
428         if (title_utf8)
429                 free(title_utf8);
430
431         if (content_utf8)
432                 free(content_utf8);
433
434         if (info_1_utf8)
435                 free(info_1_utf8);
436
437         if (info_sub_1_utf8)
438                 free(info_sub_1_utf8);
439
440         if (len > 0)
441                 return strdup(buf);
442
443         return NULL;
444 }
445
446 static char *_quickpanel_ticker_get_label(notification_h noti)
447 {
448         char *result = NULL;
449         notification_ly_type_e layout;
450
451         retif(noti == NULL, NULL, "Invalid parameter!");
452
453         notification_get_layout(noti, &layout);
454
455
456         if (layout == NOTIFICATION_LY_NOTI_EVENT_SINGLE) {
457                 result = _quickpanel_ticker_get_label_layout_single(noti);
458         } else {
459                 result = _quickpanel_ticker_get_label_layout_default(noti);
460         }
461
462         return result;
463 }
464
465 static void _noti_hide_cb(void *data, Evas_Object *obj,
466                         const char *emission, const char *source)
467 {
468         DBG("");
469
470         if (g_timer) {
471                 ecore_timer_del(g_timer);
472                 g_timer = NULL;
473         }
474
475         _quickpanel_ticker_hide(data);
476 }
477
478 static Evas_Object *_quickpanel_ticker_create_tickernoti(void *data)
479 {
480         notification_h noti = (notification_h) data;
481         Evas_Object *tickernoti = NULL;
482         Evas_Object *icon = NULL;
483         Evas_Object *detail = NULL;
484         Evas_Object *button = NULL;
485         char *buf = NULL;
486         const char *data_win_height = NULL;
487         int noti_height = 0;
488         int *is_ticker_executed = NULL;
489
490         retif(noti == NULL, NULL, "Invalid parameter!");
491
492         tickernoti = noti_win_add(NULL);
493         retif(tickernoti == NULL, NULL, "Failed to add elm tickernoti.");
494
495         detail = elm_layout_add(tickernoti);
496         if (!detail) {
497                 ERR("Failed to get detailview.");
498                 _quickpanel_ticker_destroy_tickernoti(tickernoti);
499                 return NULL;
500         }
501         elm_layout_theme_set(detail, "tickernoti", "base", "default");
502         elm_object_signal_callback_add(detail, "request,hide", "",
503                                 _noti_hide_cb, noti);
504         elm_object_signal_callback_add(detail, "clicked", "",
505                         _quickpanel_ticker_clicked_cb, noti);
506
507         data_win_height = (char *)elm_layout_data_get(detail, "height");
508         if (data_win_height != NULL && elm_config_scale_get() > 0.0)
509                 noti_height = (int)(elm_config_scale_get()
510                                         * atoi(data_win_height));
511         evas_object_size_hint_min_set(detail, 1, noti_height);
512         g_noti_height = noti_height;
513
514         noti_win_content_set(tickernoti, detail);
515
516         icon = _quickpanel_ticker_create_icon(detail, noti);
517         if (icon != NULL)
518                 elm_object_part_content_set(detail, "icon", icon);
519
520         button = _quickpanel_ticker_create_button(detail, noti);
521         if (button != NULL)
522                 elm_object_part_content_set(detail, "button", button);
523
524         buf = _quickpanel_ticker_get_label(noti);
525         if (buf != NULL) {
526                 elm_object_part_text_set(detail, "elm.text", buf);
527                 free(buf);
528         }
529
530         /* Use style "default" for detailview mode and
531          * "info" for text only mode
532          */
533         elm_object_style_set(tickernoti, "default");
534         evas_object_data_set(tickernoti, E_DATA_IS_TICKERNOTI_CONTENT, detail);
535         is_ticker_executed = (int *)malloc(sizeof(int));
536         if (is_ticker_executed != NULL) {
537                 *is_ticker_executed = 0;
538                 evas_object_data_set(detail, E_DATA_IS_TICKERNOTI_EXECUTED, is_ticker_executed);
539         }
540
541         return tickernoti;
542 }
543
544 static void _quickpanel_ticker_destroy_tickernoti(Evas_Object *tickernoti)
545 {
546         int *is_ticker_executed = NULL;
547         Evas_Object *detail = NULL;
548
549         retif(tickernoti == NULL, , "Invalid parameter!");
550
551         detail = evas_object_data_get(tickernoti, E_DATA_IS_TICKERNOTI_CONTENT);
552
553         if (detail != NULL) {
554                 is_ticker_executed = evas_object_data_get(detail, E_DATA_IS_TICKERNOTI_EXECUTED);
555                 if (is_ticker_executed != NULL) {
556                         evas_object_data_del(detail, E_DATA_IS_TICKERNOTI_EXECUTED);
557                         free(is_ticker_executed);
558                 }
559                 evas_object_data_del(detail, E_DATA_IS_TICKERNOTI_CONTENT);
560         }
561
562         evas_object_del(tickernoti);
563 }
564
565 static int _quickpanel_ticker_get_angle(void *data)
566 {
567         struct appdata *ad = (struct appdata *)data;
568         Ecore_X_Window xwin, root;
569         int ret = 0, angle = 0, count = 0;
570         unsigned char *prop_data = NULL;
571
572         xwin = elm_win_xwindow_get(ad->win);
573         root = ecore_x_window_root_get(xwin);
574
575         ret = ecore_x_window_prop_property_get(root,
576                                 ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE,
577                                 ECORE_X_ATOM_CARDINAL, 32,
578                                 &prop_data, &count);
579
580         if (ret && prop_data) {
581                 memcpy(&angle, prop_data, sizeof(int));
582
583                 if (prop_data)
584                         free(prop_data);
585
586                 return angle;
587         } else {
588                 ERR("Fail to get angle");
589                 if (prop_data)
590                         free(prop_data);
591
592                 return -1;
593         }
594 }
595
596 static void _quickpanel_ticker_update_geometry_on_rotation(void *data, int *x, int *y, int *w, int *h) {
597         int angle = 0;
598
599         if (!data)
600                 return;
601         angle = _quickpanel_ticker_get_angle(data);
602         Evas_Coord root_w, root_h;
603
604         /*
605          * manually calculate win_tickernoti_indi window position & size
606          *  - win_indi is not full size window
607          */
608         ecore_x_window_size_get(ecore_x_window_root_first_get(), &root_w, &root_h);
609
610         // rotate win
611         switch(angle)
612         {
613                 case 90:
614                         *w = g_noti_height;
615                         *h = root_h;
616                         break;
617                 case 270:
618                         *w = g_noti_height;
619                         *h = root_h;
620                         *x = root_w - g_noti_height;
621                         break;
622                 case 180:
623                         *w = root_w;
624                         *h = g_noti_height;
625                         *y = root_h - g_noti_height;
626                         break;
627                 case 0:
628                 default:
629                         *w = root_w;
630                         *h = g_noti_height;
631                         break;
632         }
633         elm_win_rotation_set(g_ticker, angle);
634 }
635
636 static void _quickpanel_ticker_win_rotated(void *data) {
637         retif(data == NULL, ,"data is NULL");
638         struct appdata *ad = data;
639         int x = 0, y = 0, w = 0, h = 0;
640
641         _quickpanel_ticker_update_geometry_on_rotation(ad, &x, &y, &w, &h);
642
643         if (g_ticker != NULL) {
644                 evas_object_move(g_ticker, x, y);
645                 evas_object_resize(g_ticker, w, h);
646         }
647 }
648
649 static void _quickpanel_noti_media_feedback(notification_h noti) {
650
651         retif(noti == NULL, ,"op_list is NULL");
652
653         if (quickpanel_is_sound_enabled() == 1) {
654                 notification_sound_type_e nsound_type = NOTIFICATION_SOUND_TYPE_NONE;
655                 const char *nsound_path = NULL;
656 #ifdef VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR
657                 char *default_msg_tone = NULL;
658 #endif
659
660                 notification_get_sound(noti, &nsound_type, &nsound_path);
661                 DBG("notification sound: %d, %s", nsound_type, nsound_path);
662
663                 switch (nsound_type) {
664                         case NOTIFICATION_SOUND_TYPE_USER_DATA:
665                                 quickpanel_player_play(SOUND_TYPE_NOTIFICATION, nsound_path);
666                                 break;
667                         case NOTIFICATION_SOUND_TYPE_DEFAULT:
668 #ifdef VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR
669                                 default_msg_tone = vconf_get_str(VCONFKEY_SETAPPL_NOTI_MSG_RINGTONE_PATH_STR);
670
671                                 if (default_msg_tone != NULL) {
672                                         quickpanel_player_play(SOUND_TYPE_NOTIFICATION, default_msg_tone);
673                                         free(default_msg_tone);
674                                 } else {
675                                         feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
676                                 }
677 #else
678                                 feedback_play_type(FEEDBACK_TYPE_SOUND, FEEDBACK_PATTERN_UNLOCK);
679 #endif
680                                 break;
681                         case NOTIFICATION_SOUND_TYPE_MAX:
682                         case NOTIFICATION_SOUND_TYPE_NONE:
683                                 break;
684                 }
685         }
686
687         /* Play Vibration */
688         notification_vibration_type_e nvibration_type =
689                 NOTIFICATION_VIBRATION_TYPE_NONE;
690         const char *nvibration_path = NULL;
691
692         notification_get_vibration(noti, &nvibration_type, &nvibration_path);
693         DBG("notification vibration: %d, %s", nvibration_type, nvibration_path);
694         switch (nvibration_type) {
695                 case NOTIFICATION_VIBRATION_TYPE_USER_DATA:
696                 case    NOTIFICATION_VIBRATION_TYPE_DEFAULT:
697                         feedback_play_type(FEEDBACK_TYPE_VIBRATION, FEEDBACK_PATTERN_GENERAL);
698                         break;
699                 case NOTIFICATION_VIBRATION_TYPE_MAX:
700                 case NOTIFICATION_VIBRATION_TYPE_NONE:
701                         break;
702         }
703 }
704
705 static void _quickpanel_ticker_noti_detailed_changed_cb(void *data, notification_type_e type, notification_op *op_list, int num_op)
706 {
707         notification_h noti = NULL;
708         int flags = 0;
709         int applist = NOTIFICATION_DISPLAY_APP_ALL;
710         int op_type = 0;
711         int priv_id = 0;
712
713         INFO("_quickpanel_ticker_noti_changed_cb");
714
715         retif(op_list == NULL, ,"op_list is NULL");
716
717         if (_is_lockscreen_launched()) {
718                 ERR("lockscreen launched, creating a ticker canceled");
719                 return;
720         }
721
722         if (num_op == 1) {
723                 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_TYPE, &op_type);
724                 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_PRIV_ID, &priv_id);
725                 DBG("op_type:%d", op_type);
726                 DBG("op_priv_id:%d", priv_id);
727
728                 if (op_type == NOTIFICATION_OP_INSERT) {
729                         noti = notification_load(NULL, priv_id);
730                 } else if (op_type == NOTIFICATION_OP_UPDATE) {
731                         noti = notification_load(NULL, priv_id);
732                 } else {
733                         return ;
734                 }
735         } else {
736                 return ;
737         }
738
739         retif(noti == NULL, ,"noti is NULL");
740
741         if (op_type == NOTIFICATION_OP_INSERT || op_type == NOTIFICATION_OP_UPDATE) {
742                 INFO("playing notification sound");
743                 _quickpanel_noti_media_feedback(noti);
744         }
745
746         notification_get_display_applist(noti, &applist);
747         if (!(applist & NOTIFICATION_DISPLAY_APP_TICKER)) {
748                 INFO("displaying ticker option is off");
749                 notification_free(noti);
750                 return ;
751         }
752
753         /* Skip if previous ticker is still shown */
754         if (g_ticker != NULL) {
755                 _quickpanel_ticker_hide(NULL);
756         }
757
758         /* Check tickernoti flag */
759         notification_get_property(noti, &flags);
760
761         if (flags & NOTIFICATION_PROP_DISABLE_TICKERNOTI) {
762                 INFO("NOTIFICATION_PROP_DISABLE_TICKERNOTI");
763                 __ticker_only_noti_del(noti);
764                 notification_free(noti);
765         } else if (applist & NOTIFICATION_DISPLAY_APP_TICKER) {
766                 /* Display ticker */
767                 if (g_timer)
768                         ecore_timer_del(g_timer);
769
770                 g_ticker = _quickpanel_ticker_create_tickernoti(noti);
771                 if (g_ticker == NULL) {
772                         ERR("Fail to create tickernoti");
773                         __ticker_only_noti_del(noti);
774                         notification_free(noti);
775                         return;
776                 }
777
778                 g_timer = ecore_timer_add(QP_TICKER_DURATION,
779                                 _quickpanel_ticker_timeout_cb, noti);
780
781                 _quickpanel_ticker_win_rotated(data);
782                 evas_object_show(g_ticker);
783
784                 evas_object_event_callback_add(g_ticker, EVAS_CALLBACK_SHOW,
785                                         _quickpanel_ticker_detail_show_cb,
786                                         g_ticker);
787                 evas_object_event_callback_add(g_ticker, EVAS_CALLBACK_HIDE,
788                                         _quickpanel_ticker_detail_hide_cb,
789                                         noti);
790         }
791 }
792
793 /*****************************************************************************
794  *
795  * Util functions
796  *
797  *****************************************************************************/
798 static int quickpanel_ticker_init(void *data)
799 {
800         struct appdata *ad = (struct appdata *)data;
801
802         g_window = ad->win;
803
804         notification_register_detailed_changed_cb(_quickpanel_ticker_noti_detailed_changed_cb,
805                                         data);
806
807         return QP_OK;
808 }
809
810 static int quickpanel_ticker_fini(void *data)
811 {
812         _quickpanel_ticker_hide(NULL);
813
814         return QP_OK;
815 }
816
817 static int quickpanel_ticker_enter_hib(void *data)
818 {
819         return QP_OK;
820 }
821
822 static int quickpanel_ticker_leave_hib(void *data)
823 {
824         return QP_OK;
825 }
826
827 static void quickpanel_ticker_reflesh(void *data)
828 {
829         retif(data == NULL, , "Invalid parameter!");
830
831         if (g_ticker != NULL) {
832                 _quickpanel_ticker_win_rotated(data);
833         }
834 }