2 * Copyright (c) 2009-2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <Elementary.h>
19 //#include <Ecore_X.h>
21 #include <app_control.h>
22 #include <notification_internal.h>
24 #include <system_settings.h>
26 #include <sound_manager.h>
27 #include <metadata_extractor.h>
28 #include <notification.h>
29 #include <notification_text_domain.h>
30 #include <app_manager.h>
37 #include "indicator.h"
41 #define TICKERNOTI_DURATION 3
42 #define QP_TICKER_DETAIL_DURATION 6
43 #define QP_PLAY_DURATION_LIMIT 15
44 #define TICKER_MSG_LEN 1024
45 #define TICKER_PHONE_NUMBER_MAX_LEN 40
47 #define DEFAULT_ICON ICONDIR "/quickpanel_icon_default.png"
49 #define FORMAT_1LINE "<font_size=29><color=#F4F4F4FF>%s</color></font_size>"
50 #define FORMAT_2LINE "<font_size=26><color=#BABABAFF>%s</color></font_size><br/><font_size=29><color=#F4F4F4FF>%s</color></font_size>"
52 #define PRIVATE_DATA_KEY_APPDATA "pdka"
53 #define PRIVATE_DATA_KEY_DETAIL "pdkd"
54 #define PRIVATE_DATA_KEY_TICKERNOTI_EXECUTED "pdkte"
55 #define PRIVATE_DATA_KEY_ANI_ICON_TYPE "pdkait"
56 #define PRIVATE_DATA_KEY_ICON "pdki"
57 #define PRIVATE_DATA_KEY_BOX "pdkb"
58 #define PRIVATE_DATA_KEY_TICKER_INFO "pdkti"
59 #define PRIVATE_DATA_KEY_NOTI "pdkn"
61 #define PATH_DOWNLOAD "reserved://quickpanel/ani/downloading"
62 #define PATH_UPLOAD "reserved://quickpanel/ani/uploading"
63 #define PATH_INSTALL "reserved://quickpanel/ani/install"
65 static void _create_tickernoti(notification_h noti, struct appdata *ad, ticker_info_s *ticker_info);
66 static void _destroy_tickernoti(ticker_info_s *ticker_info);
68 static inline int _is_text_exist(const char *text)
71 if (strlen(text) > 0) {
72 if (strcmp(text, "") != 0) {
81 static int _is_security_lockscreen_launched(void)
84 int is_lock_launched = 0;
86 if ((ret = vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &is_lock_launched)) == 0) {
87 if (is_lock_launched == VCONFKEY_IDLE_LOCK && (ret = vconf_get_int(VCONFKEY_SETAPPL_SCREEN_LOCK_TYPE_INT, &is_lock_launched)) == 0) {
88 /* if (is_lock_launched != SETTING_SCREEN_LOCK_TYPE_NONE && is_lock_launched != SETTING_SCREEN_LOCK_TYPE_SWIPE) {
97 static int _check_is_noti_from_email(char *pkgname)
101 if (strcmp(pkgname, TIZEN_EMAIL_PACKAGE) == 0 || strcmp(pkgname, "/usr/bin/eas-engine") == 0) {
108 static int _check_is_noti_from_message(char *pkgname)
110 retv_if(!pkgname, 0);
112 if (strcmp(pkgname, TIZEN_MESSAGE_PACKAGE) == 0 || strcmp(pkgname, "/usr/bin/msg-server") == 0) {
119 static int _check_is_noti_from_im(char *pkgname)
121 retv_if(!pkgname, 0);
123 if (strcmp(pkgname, "xnq5eh9vop.ChatON") == 0) {
130 static notification_h _get_instant_latest_message_from_list(ticker_info_s *ticker_info)
133 notification_h noti = NULL;
135 count = eina_list_count(ticker_info->ticker_list);
137 noti = eina_list_nth(ticker_info->ticker_list, count-1);
139 eina_list_free(ticker_info->ticker_list);
140 ticker_info->ticker_list = NULL;
145 static int _ticker_check_ticker_off(notification_h noti)
147 char *pkgname = NULL;
149 notification_get_pkgname(noti, &pkgname);
151 if (pkgname == NULL) return 1; /* Ticker is not displaying. */
156 static int _ticker_check_displaying_contents_off(notification_h noti)
158 char *pkgname = NULL;
162 notification_get_pkgname(noti, &pkgname);
164 if (pkgname == NULL) return 0; /* Ticker is not displaying. */
166 /* FIXME : we have to confirm architecture for communiating with message or email */
167 if (_check_is_noti_from_message(pkgname) == 1) {
168 ret = vconf_get_bool(VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_MESSASGES, &boolval);
169 if (ret == 0 && boolval == 0) return 1;
171 } else if (_check_is_noti_from_email(pkgname) == 1) {
172 ret = vconf_get_bool(VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_EMAIL, &boolval);
173 if (ret == 0 && boolval == 0) return 1;
175 } else if (_check_is_noti_from_im(pkgname) == 1) {
176 ret = vconf_get_bool(VCONFKEY_TICKER_NOTI_DISPLAY_CONTENT_IM, &boolval);
177 if (ret == 0 && boolval == 0) return 1;
184 static inline void __ticker_only_noti_del(notification_h noti)
186 int applist = NOTIFICATION_DISPLAY_APP_ALL;
190 notification_get_display_applist(noti, &applist);
191 if ((applist & NOTIFICATION_DISPLAY_APP_TICKER) || (applist & NOTIFICATION_DISPLAY_APP_INDICATOR)) {
192 char *pkgname = NULL;
195 notification_get_pkgname(noti, &pkgname);
196 notification_get_id(noti, NULL, &priv_id);
197 notification_delete_by_priv_id(pkgname, NOTIFICATION_TYPE_NONE, priv_id);
201 static Eina_Bool _timeout_cb(void *data)
203 ticker_info_s *ticker_info = NULL;
209 retv_if(!data, EINA_FALSE);
211 _D("message is timeout");
215 /* If count is 1, self*/
216 if (ticker_info->ticker_list && eina_list_count(ticker_info->ticker_list) > 1) {
217 if (ticker_info->timer) {
218 ecore_timer_del(ticker_info->timer);
219 ticker_info->timer = NULL;
221 _destroy_tickernoti(ticker_info);
223 return ECORE_CALLBACK_CANCEL;
226 elm_scroller_last_page_get(ticker_info->scroller, &h_last_page, &v_last_page);
227 elm_scroller_current_page_get(ticker_info->scroller, &h_page, &v_page);
229 if (v_last_page > v_page) {
230 elm_scroller_page_bring_in(ticker_info->scroller, h_page, v_page + 1);
232 return ECORE_CALLBACK_RENEW;
235 if (ticker_info->timer) {
236 ecore_timer_del(ticker_info->timer);
237 ticker_info->timer = NULL;
239 _destroy_tickernoti(ticker_info);
241 return ECORE_CALLBACK_CANCEL;
244 static indicator_animated_icon_type _animated_type_get(const char *path)
246 retv_if(path == NULL, INDICATOR_ANIMATED_ICON_NONE);
248 if (strncasecmp(path, PATH_DOWNLOAD, MIN(strlen(PATH_DOWNLOAD), strlen(path))) == 0) {
249 return INDICATOR_ANIMATED_ICON_DOWNLOAD;
250 } else if (strncasecmp(path, PATH_UPLOAD, MIN(strlen(PATH_UPLOAD), strlen(path))) == 0) {
251 return INDICATOR_ANIMATED_ICON_UPLOAD;
252 } else if (strncasecmp(path, PATH_INSTALL, MIN(strlen(PATH_INSTALL), strlen(path))) == 0) {
253 return INDICATOR_ANIMATED_ICON_INSTALL;
256 return INDICATOR_ANIMATED_ICON_NONE;
259 #define DEFAULT_EDJ EDJDIR"/ticker_default.edj"
260 /* FIXME : evas_object_del(icon), we have to unset PRIVATE_DATA_KEY_ANI_ICON_TYPE) */
261 static Evas_Object *_animated_icon_get(Evas_Object *parent, const char *path)
263 indicator_animated_icon_type type = INDICATOR_ANIMATED_ICON_NONE;
265 const char *layout_icon = NULL;
266 Evas_Object *layout = NULL;
268 retv_if(!parent, NULL);
269 retv_if(!path, NULL);
271 type = _animated_type_get(path);
273 if (type == INDICATOR_ANIMATED_ICON_DOWNLOAD) {
274 layout_icon = "quickpanel/animated_icon_download";
275 } else if (type == INDICATOR_ANIMATED_ICON_UPLOAD) {
276 layout_icon = "quickpanel/animated_icon_upload";
277 } else if (type == INDICATOR_ANIMATED_ICON_INSTALL) {
278 layout_icon = "quickpanel/animated_icon_install";
283 layout = elm_layout_add(parent);
284 if (layout != NULL) {
285 elm_layout_file_set(layout, DEFAULT_EDJ, layout_icon);
286 evas_object_size_hint_weight_set(layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
287 evas_object_size_hint_align_set(layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
288 evas_object_data_set(layout, PRIVATE_DATA_KEY_ANI_ICON_TYPE, (void *)type);
289 evas_object_show(layout);
295 static char *_get_pkginfo_icon(const char *pkgid)
298 char *icon_path = NULL;
301 retif(pkgid == NULL, NULL, "invalid parameter");
303 ret = app_info_create(pkgid, &app_info);
304 if (ret != APP_MANAGER_ERROR_NONE) {
305 _E("app_info_create for %s failed %d", pkgid, ret);
309 ret = app_info_get_icon(app_info, &icon_path);
310 if (ret != APP_MANAGER_ERROR_NONE) {
311 app_info_destroy(app_info);
312 _E("app_info_get_icon failed %d", ret);
316 app_info_destroy(app_info);
321 static Evas_Object *_ticker_create_icon(Evas_Object *parent, notification_h noti)
323 char *pkgname = NULL;
324 char *icon_path = NULL;
325 char *icon_default = NULL;
326 Evas_Object *icon = NULL;
328 retif(noti == NULL || parent == NULL, NULL, "Invalid parameter!");
330 notification_get_pkgname(noti, &pkgname);
331 if (NOTIFICATION_ERROR_NONE != notification_get_image(noti, NOTIFICATION_IMAGE_TYPE_ICON, &icon_path)) {
332 _E("Cannot get image path");
336 icon = _animated_icon_get(parent, icon_path);
338 icon = elm_image_add(parent);
339 if (icon_path == NULL
340 || (elm_image_file_set(icon, icon_path, NULL) == EINA_FALSE)) {
341 icon_default = _get_pkginfo_icon(pkgname);
342 if (icon_default != NULL) {
343 elm_image_file_set(icon, icon_default, NULL);
344 elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
347 elm_image_file_set(icon, DEFAULT_ICON, NULL);
348 elm_image_resizable_set(icon, EINA_TRUE, EINA_TRUE);
357 static inline char *_get_text(notification_h noti, notification_text_type_e text_type)
361 notification_get_text(noti, text_type, &text);
363 return elm_entry_utf8_to_markup(text);
369 static inline void _strbuf_add(Eina_Strbuf *str_buf, char *text, const char *delimiter)
372 if (strlen(text) > 0) {
373 if (delimiter != NULL) {
374 eina_strbuf_append(str_buf, delimiter);
376 eina_strbuf_append(str_buf, text);
381 static int _is_phone_number(const char *address)
384 retif(address == NULL, 0, "address is NULL");
387 addr_len = strlen(address);
393 /* length check phone address should be longer than 2 and shorter than 40 */
394 if (addr_len > 2 && addr_len <= TICKER_PHONE_NUMBER_MAX_LEN) {
395 const char *pszOneChar = address;
397 while (*pszOneChar) {
398 if (isdigit(*pszOneChar)) {
405 pszOneChar = address;
407 if (*pszOneChar == '+') {
411 while (*pszOneChar) {
412 if (!isdigit(*pszOneChar)
413 && (*pszOneChar != '*') && (*pszOneChar != '#')
414 && (*pszOneChar != ' ')
415 && !((*pszOneChar == '-') && digit_count >= 7)) {
424 DBG("invalid address length [%d]", addr_len);
429 static void _char_set(char *dst, char s, int index, int size)
436 static void _make_phone_number_tts(char *dst, const char *src, int size)
438 retif(dst == NULL, , "invalid argument");
439 retif(src == NULL, , "invalid argument");
442 int i = 0, j = 0, text_len = 0;
444 text_len = strlen(src);
446 for (i = 0, j= 0; i < text_len; i++) {
448 _char_set(dst, *(src + i), j++, size);
450 if (isdigit(*(src + i))) {
451 if (i + 1 < text_len) {
452 if (*(src + i + 1) == '-' || *(src + i + 1) == _SPACE) {
453 _char_set(dst, *(src + i), j++, size);
455 _char_set(dst, *(src + i), j++, size);
456 _char_set(dst, _SPACE, j++, size);
459 _char_set(dst, *(src + i), j++, size);
460 _char_set(dst, _SPACE, j++, size);
462 } else if (*(src + i) == '-') {
464 _char_set(dst, *(src + i), j++, size);
466 _char_set(dst, *(src + i), j++, size);
472 static inline void _check_and_add_to_buffer(Eina_Strbuf *str_buf, char *text, int is_check_phonenumber)
474 char buf_number[TICKER_PHONE_NUMBER_MAX_LEN * 2] = { 0, };
477 if (strlen(text) > 0) {
478 if (_is_phone_number(text) && is_check_phonenumber) {
479 _make_phone_number_tts(buf_number, text,
480 (TICKER_PHONE_NUMBER_MAX_LEN * 2) - 1);
481 eina_strbuf_append(str_buf, buf_number);
483 eina_strbuf_append(str_buf, text);
485 eina_strbuf_append_char(str_buf, '\n');
490 static char *_ticker_get_label_layout_default(notification_h noti, int is_screenreader, char **str_line1, char **str_line2)
496 char *title_utf8 = NULL;
497 char *content_utf8 = NULL;
498 char *info1_utf8 = NULL;
499 char *info1_sub_utf8 = NULL;
500 char *info2_utf8 = NULL;
501 char *info2_sub_utf8 = NULL;
502 char *event_count_utf8 = NULL;
503 const char *tmp = NULL;
504 Eina_Strbuf *line1 = NULL;
505 Eina_Strbuf *line2 = NULL;
506 char buf[TICKER_MSG_LEN] = { 0, };
508 retif(noti == NULL, NULL, "Invalid parameter!");
510 notification_get_text_domain(noti, &domain, &dir);
511 if (domain != NULL && dir != NULL) {
512 bindtextdomain(domain, dir);
515 title_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE);
516 if (_ticker_check_displaying_contents_off(noti) == 1) {
517 content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF);
519 content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT);
521 info1_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_1);
522 info1_sub_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_1);
523 info2_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_2);
524 info2_sub_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_2);
526 if (is_screenreader == 0) {
527 line1 = eina_strbuf_new();
528 line2 = eina_strbuf_new();
530 if (line1 != NULL && line2 != NULL) {
531 if (_is_text_exist(title_utf8) && (_is_text_exist(content_utf8)
532 || _is_text_exist(event_count_utf8))) {
533 _strbuf_add(line1, title_utf8, NULL);
534 _strbuf_add(line2, content_utf8, NULL);
535 if (_is_text_exist(content_utf8)) {
536 _strbuf_add(line2, event_count_utf8, " ");
538 _strbuf_add(line2, event_count_utf8, "");
541 } else if (_is_text_exist(info1_utf8) && (_is_text_exist(content_utf8)
542 || _is_text_exist(event_count_utf8))) {
543 _strbuf_add(line1, content_utf8, NULL);
544 _strbuf_add(line1, event_count_utf8, " ");
545 _strbuf_add(line2, info1_utf8, NULL);
546 _strbuf_add(line2, info1_sub_utf8, " ");
548 } else if (_is_text_exist(info1_utf8) && _is_text_exist(info2_utf8)) {
549 _strbuf_add(line1, info1_utf8, NULL);
550 _strbuf_add(line1, info1_sub_utf8, " ");
551 _strbuf_add(line2, info2_utf8, NULL);
552 _strbuf_add(line2, info2_sub_utf8, " ");
554 } else if (_is_text_exist(title_utf8)) {
555 _strbuf_add(line1, title_utf8, NULL);
557 } else if (_is_text_exist(content_utf8)) {
558 _strbuf_add(line1, content_utf8, NULL);
563 tmp = eina_strbuf_string_get(line1);
564 if (str_line1 != NULL && tmp != NULL) {
565 *str_line1 = strdup(tmp);
568 tmp = eina_strbuf_string_get(line2);
569 if (str_line2 != NULL && tmp != NULL) {
570 *str_line2 = strdup(tmp);
573 tmp = eina_strbuf_string_get(line1);
574 if (str_line1 != NULL && tmp != NULL) {
575 *str_line1 = strdup(tmp);
579 eina_strbuf_free(line1);
580 eina_strbuf_free(line2);
582 _E("failed to allocate string buffer");
585 if (title_utf8 == NULL
586 && event_count_utf8 == NULL
587 && content_utf8 == NULL
588 && info1_utf8 == NULL
589 && info1_sub_utf8 == NULL
590 && info2_utf8 == NULL
591 && info2_sub_utf8 == NULL) {
594 Eina_Strbuf *strbuf = eina_strbuf_new();
595 if (strbuf != NULL) {
596 eina_strbuf_append(strbuf, _("IDS_QP_BUTTON_NOTIFICATION"));
597 eina_strbuf_append_char(strbuf, '\n');
598 _check_and_add_to_buffer(strbuf, title_utf8, 1);
599 _check_and_add_to_buffer(strbuf, event_count_utf8, 0);
600 _check_and_add_to_buffer(strbuf, content_utf8, 1);
601 _check_and_add_to_buffer(strbuf, info1_utf8, 1);
602 _check_and_add_to_buffer(strbuf, info1_sub_utf8, 1);
603 _check_and_add_to_buffer(strbuf, info2_utf8, 1);
604 _check_and_add_to_buffer(strbuf, info2_sub_utf8, 1);
606 if (eina_strbuf_length_get(strbuf) > 0) {
607 len = snprintf(buf, sizeof(buf) - 1, "%s", eina_strbuf_string_get(strbuf));
609 eina_strbuf_free(strbuf);
622 // if (event_count_utf8) {
623 // free(event_count_utf8);
629 if (info1_sub_utf8) {
630 free(info1_sub_utf8);
635 if (info2_sub_utf8) {
636 free(info2_sub_utf8);
644 static char *_ticker_get_label_layout_single(notification_h noti, int is_screenreader, char **str_line1, char **str_line2)
650 char *title_utf8 = NULL;
651 char *content_utf8 = NULL;
652 char *info1_utf8 = NULL;
653 char *info1_sub_utf8 = NULL;
654 char *info2_utf8 = NULL;
655 char *info2_sub_utf8 = NULL;
656 Eina_Strbuf *line1 = NULL;
657 Eina_Strbuf *line2 = NULL;
658 const char *tmp = NULL;
659 char buf[TICKER_MSG_LEN] = { 0, };
661 retif(noti == NULL, NULL, "Invalid parameter!");
663 notification_get_text_domain(noti, &domain, &dir);
664 if (domain != NULL && dir != NULL)
665 bindtextdomain(domain, dir);
667 title_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_TITLE);
668 if (_ticker_check_displaying_contents_off(noti) == 1) {
669 content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT_FOR_DISPLAY_OPTION_IS_OFF);
671 content_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_CONTENT);
673 info1_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_1);
674 info1_sub_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_1);
675 info2_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_2);
676 info2_sub_utf8 = _get_text(noti, NOTIFICATION_TEXT_TYPE_INFO_SUB_2);
678 if (is_screenreader == 0) {
679 line1 = eina_strbuf_new();
680 line2 = eina_strbuf_new();
682 if (line1 != NULL && line2 != NULL) {
683 if (_is_text_exist(info1_utf8) && _is_text_exist(content_utf8)) {
684 _strbuf_add(line1, content_utf8, NULL);
685 _strbuf_add(line2, info1_utf8, NULL);
686 _strbuf_add(line2, info1_sub_utf8, " ");
688 } else if (_is_text_exist(title_utf8) && _is_text_exist(content_utf8)) {
689 _strbuf_add(line1, title_utf8, NULL);
690 _strbuf_add(line2, content_utf8, NULL);
692 } else if (_is_text_exist(title_utf8)) {
693 _strbuf_add(line1, title_utf8, NULL);
695 } else if (_is_text_exist(content_utf8)) {
696 _strbuf_add(line1, content_utf8, NULL);
701 tmp = eina_strbuf_string_get(line1);
702 if (str_line1 != NULL && tmp != NULL) {
703 *str_line1 = strdup(tmp);
706 tmp = eina_strbuf_string_get(line2);
707 if (str_line2 != NULL && tmp != NULL) {
708 *str_line2 = strdup(tmp);
711 tmp = eina_strbuf_string_get(line1);
712 if (str_line1 != NULL && tmp != NULL) {
713 *str_line1 = strdup(tmp);
717 eina_strbuf_free(line1);
718 eina_strbuf_free(line2);
720 _E("failed to allocate string buffer");
723 if (title_utf8 == NULL
724 && content_utf8 == NULL
725 && info1_utf8 == NULL
726 && info1_sub_utf8 == NULL) {
729 Eina_Strbuf *strbuf = eina_strbuf_new();
730 if (strbuf != NULL) {
731 eina_strbuf_append(strbuf, _("IDS_QP_BUTTON_NOTIFICATION"));
732 eina_strbuf_append_char(strbuf, '\n');
733 if (info1_utf8 == NULL) {
734 _check_and_add_to_buffer(strbuf, title_utf8, 1);
735 _check_and_add_to_buffer(strbuf, content_utf8, 1);
737 if (content_utf8 == NULL) {
738 _check_and_add_to_buffer(strbuf, title_utf8, 1);
740 _check_and_add_to_buffer(strbuf, content_utf8, 1);
741 _check_and_add_to_buffer(strbuf, info1_utf8, 1);
742 _check_and_add_to_buffer(strbuf, info1_sub_utf8, 1);
745 if (eina_strbuf_length_get(strbuf) > 0) {
746 len = snprintf(buf, sizeof(buf) - 1, "%s", eina_strbuf_string_get(strbuf));
748 eina_strbuf_free(strbuf);
762 if (info1_sub_utf8) {
763 free(info1_sub_utf8);
768 if (info2_sub_utf8) {
769 free(info2_sub_utf8);
777 static char *_ticker_get_text(notification_h noti, int is_screenreader, char **line1, char **line2)
780 notification_ly_type_e layout;
782 retif(noti == NULL, NULL, "Invalid parameter!");
784 notification_get_layout(noti, &layout);
786 if (_ticker_check_displaying_contents_off(noti) == 1) {
787 result = _ticker_get_label_layout_default(noti, is_screenreader, line1, line2);
788 } else if (layout == NOTIFICATION_LY_NOTI_EVENT_SINGLE) {
789 result = _ticker_get_label_layout_single(noti, is_screenreader, line1, line2);
791 result = _ticker_get_label_layout_default(noti, is_screenreader, line1, line2);
797 static void _noti_hide_cb(void *data, Evas_Object *obj, const char *emission, const char *source)
799 ticker_info_s *ticker_info = NULL;
805 if (ticker_info->timer) {
806 ecore_timer_del(ticker_info->timer);
807 ticker_info->timer = NULL;
810 _destroy_tickernoti(ticker_info);
813 static void _mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
815 _noti_hide_cb(data, NULL, NULL, NULL);
818 #define TICKER_EDJ EDJDIR"/ticker.edj"
819 static void _create_tickernoti(notification_h noti, struct appdata *ad, ticker_info_s *ticker_info)
821 Eina_Bool ret = EINA_FALSE;
822 Evas_Object *detail = NULL;
823 Evas_Object *base = NULL;
824 Evas_Object *icon = NULL;
825 Evas_Object *box = NULL;
826 Evas_Object *textblock = NULL;
830 int *is_ticker_executed = NULL;
833 ret_if(!ticker_info);
835 if (ticker_info->win != NULL) {
836 _E("ticker notification exists");
840 _D("create ticker notification");
843 ticker_info->win = noti_win_add(NULL, ad);
844 ret_if(!ticker_info->win);
845 evas_object_data_set(ticker_info->win, PRIVATE_DATA_KEY_APPDATA, ad);
846 evas_object_data_set(ticker_info->win, PRIVATE_DATA_KEY_NOTI, noti);
849 detail = elm_layout_add(ticker_info->win);
850 goto_if(!detail, ERROR);
852 ret = elm_layout_file_set(detail, TICKER_EDJ, "quickpanel/tickernoti/normal");
853 goto_if(ret == EINA_FALSE, ERROR);
855 elm_object_signal_callback_add(detail, "request,hide", "", _noti_hide_cb, ticker_info);
856 evas_object_event_callback_add(detail, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down_cb, ticker_info);
857 evas_object_size_hint_min_set(detail, 1, noti_height);
858 noti_win_content_set(ticker_info->win, detail);
859 evas_object_data_set(ticker_info->win, PRIVATE_DATA_KEY_DETAIL, detail);
861 /* create base rectangle */
862 base = evas_object_rectangle_add(evas_object_evas_get(detail));
863 goto_if(!base, ERROR);
865 evas_object_color_set(base, 0, 0, 0, 0);
866 evas_object_resize(base, ad->win.w, ad->win.h);
867 evas_object_size_hint_min_set(base, ad->win.w, ad->win.h);
868 evas_object_show(base);
869 elm_object_part_content_set(detail, "base", base);
870 evas_object_data_set(ticker_info->win, DATA_KEY_BASE_RECT, base);
873 icon = _ticker_create_icon(detail, noti);
874 if (icon) elm_object_part_content_set(detail, "icon", icon);
875 evas_object_data_set(ticker_info->win, PRIVATE_DATA_KEY_ICON, icon);
877 /* create scroller */
878 ticker_info->scroller = elm_scroller_add(detail);
879 goto_if(!ticker_info->scroller, ERROR);
881 elm_scroller_policy_set(ticker_info->scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_OFF);
882 elm_scroller_page_size_set(ticker_info->scroller, 434, INDICATOR_HEIGHT - 5);
883 elm_scroller_movement_block_set(ticker_info->scroller, ELM_SCROLLER_MOVEMENT_BLOCK_VERTICAL|ELM_SCROLLER_MOVEMENT_BLOCK_HORIZONTAL);
884 elm_object_part_content_set(detail, "text_rect", ticker_info->scroller);
887 box = elm_box_add(ticker_info->scroller);
888 goto_if(!box, ERROR);
890 elm_object_content_set(ticker_info->scroller, box);
891 evas_object_show(box);
892 evas_object_data_set(ticker_info->win, PRIVATE_DATA_KEY_BOX, box);
894 /* create textblock */
895 textblock = elm_layout_add(box);
896 goto_if(!textblock, ERROR);
898 ret = elm_layout_file_set(textblock, TICKER_EDJ, "quickpanel/tickernoti/text");
899 goto_if(ret == EINA_FALSE, ERROR);
901 evas_object_show(textblock);
903 elm_box_pack_end(box, textblock);
906 _ticker_get_text(noti, 0, &line1, &line2);
910 elm_object_part_text_set(textblock, "elm.text", line2);
913 } else if (line2 == NULL) {
914 elm_object_part_text_set(textblock, "elm.text", line1);
917 Eina_Strbuf *buffer = eina_strbuf_new();
919 eina_strbuf_append(buffer, line1);
920 eina_strbuf_append(buffer, "<br/>");
921 eina_strbuf_append(buffer, line2);
923 elm_object_part_text_set(textblock, "elm.text", eina_strbuf_string_get(buffer));
927 eina_strbuf_free(buffer);
929 evas_object_data_set(ticker_info->win, DATA_KEY_TICKER_TEXT, textblock);
931 is_ticker_executed = (int *)malloc(sizeof(int));
932 if (is_ticker_executed != NULL) {
933 *is_ticker_executed = 0;
934 evas_object_data_set(detail, PRIVATE_DATA_KEY_TICKERNOTI_EXECUTED, is_ticker_executed);
937 /* When ticker noti is displayed, indicator window has to be hidden. */
938 if (ad) util_signal_emit_by_win(&ad->win, "message.show.noeffect", "indicator.prog");
940 ticker_info->timer = ecore_timer_add(TICKERNOTI_DURATION, _timeout_cb, ticker_info);
942 evas_object_data_set(ad->win.win, PRIVATE_DATA_KEY_TICKER_INFO, ticker_info);
947 if (ticker_info->win) _destroy_tickernoti(ticker_info);
952 static void _destroy_tickernoti(ticker_info_s *ticker_info)
954 struct appdata *ad = NULL;
955 Evas_Object *textblock = NULL;
956 Evas_Object *box = NULL;
957 Evas_Object *icon = NULL;
958 Evas_Object *detail = NULL;
959 Evas_Object *base = NULL;
960 int *is_ticker_executed = NULL;
963 ret_if(!ticker_info);
964 ret_if(!ticker_info->win);
966 _D("destroy ticker notification");
968 ad = evas_object_data_del(ticker_info->win, PRIVATE_DATA_KEY_APPDATA);
969 /* When ticker noti is hidden, indicator window has to be displayed. */
970 if (ad) util_signal_emit_by_win(&ad->win, "message.hide", "indicator.prog");
972 if (ticker_info->timer) {
973 ecore_timer_del(ticker_info->timer);
974 ticker_info->timer = NULL;
977 textblock = evas_object_data_del(ticker_info->win, DATA_KEY_TICKER_TEXT);
978 if (textblock) evas_object_del(textblock);
980 box = evas_object_data_del(ticker_info->win, PRIVATE_DATA_KEY_BOX);
981 if (box) evas_object_del(box);
983 if (ticker_info->scroller) ticker_info->scroller = NULL;
985 icon = evas_object_data_del(ticker_info->win, PRIVATE_DATA_KEY_ICON);
986 if (icon) evas_object_del(icon);
988 base = evas_object_data_del(ticker_info->win, DATA_KEY_BASE_RECT);
989 if (base) evas_object_del(base);
991 detail = evas_object_data_del(ticker_info->win, PRIVATE_DATA_KEY_DETAIL);
993 is_ticker_executed = evas_object_data_del(detail, PRIVATE_DATA_KEY_TICKERNOTI_EXECUTED);
994 if (is_ticker_executed != NULL) {
995 free(is_ticker_executed);
997 evas_object_del(detail);
1000 evas_object_del(ticker_info->win);
1001 ticker_info->win = NULL;
1003 noti = evas_object_data_del(ticker_info->win, PRIVATE_DATA_KEY_NOTI);
1005 __ticker_only_noti_del(noti);
1006 notification_free(noti);
1009 if (ticker_info->ticker_list) {
1010 noti = _get_instant_latest_message_from_list(ticker_info);
1012 _create_tickernoti(noti, ad, ticker_info);
1017 static void _ticker_noti_detailed_changed_cb(void *data, notification_type_e type, notification_op *op_list, int num_op)
1019 notification_h noti = NULL;
1020 notification_h noti_from_master = NULL;
1021 ticker_info_s *ticker_info = NULL;
1023 int applist = NOTIFICATION_DISPLAY_APP_ALL;
1030 _D("_ticker_noti_changed_cb");
1032 ticker_info = calloc(1, sizeof(ticker_info_s));
1033 ret_if(!ticker_info);
1036 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_TYPE, &op_type);
1037 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_PRIV_ID, &priv_id);
1038 notification_op_get_data(op_list, NOTIFICATION_OP_DATA_NOTI, ¬i_from_master);
1039 DBG("op_type:%d", op_type);
1040 DBG("op_priv_id:%d", priv_id);
1041 DBG("noti:%p", noti_from_master);
1043 if (op_type != NOTIFICATION_OP_INSERT &&
1044 op_type != NOTIFICATION_OP_UPDATE) {
1047 if (noti_from_master == NULL) {
1048 _E("failed to get a notification from master");
1051 if (notification_clone(noti_from_master, ¬i) != NOTIFICATION_ERROR_NONE) {
1052 _E("failed to create a cloned notification");
1055 #ifdef QP_EMERGENCY_MODE_ENABLE
1056 if (quickpanel_emergency_mode_is_on()) {
1057 if (quickpanel_emergency_mode_notification_filter(noti, 1)) {
1058 DBG("notification filtered");
1059 notification_free(noti);
1068 notification_get_display_applist(noti, &applist);
1069 if (!(applist & NOTIFICATION_DISPLAY_APP_TICKER
1070 || applist & NOTIFICATION_DISPLAY_APP_INDICATOR)) {
1071 DBG("displaying ticker option is off");
1072 notification_free(noti);
1076 /* Check setting's event notification */
1077 ret = _ticker_check_ticker_off(noti);
1079 DBG("Disabled tickernoti ret : %d", ret);
1080 /* delete temporary here only ticker noti display item */
1081 __ticker_only_noti_del(noti);
1082 notification_free(noti);
1087 /* Skip if previous ticker is still shown */
1089 if (ticker_info->win != NULL) {
1090 DBG("delete ticker noti");
1091 _destroy_tickernoti();
1092 ticker_info->win = NULL;
1096 /* Check tickernoti flag */
1097 notification_get_property(noti, &flags);
1099 if (flags & NOTIFICATION_PROP_DISABLE_TICKERNOTI) {
1100 DBG("NOTIFICATION_PROP_DISABLE_TICKERNOTI");
1101 __ticker_only_noti_del(noti);
1102 notification_free(noti);
1103 } else if (applist & NOTIFICATION_DISPLAY_APP_TICKER
1104 || applist & NOTIFICATION_DISPLAY_APP_INDICATOR) {
1105 if (_is_security_lockscreen_launched()) {
1106 _E("lockscreen or sview launched, creating a ticker canceled");
1107 notification_free(noti);
1111 ticker_info->ticker_list = eina_list_append(ticker_info->ticker_list, noti);
1112 /* wait when win is not NULL */
1113 if (ticker_info->win == NULL) {
1114 _create_tickernoti(noti, data, ticker_info);
1116 if (ticker_info->win == NULL) {
1117 _E("Fail to create tickernoti");
1118 __ticker_only_noti_del(noti);
1119 notification_free(noti);
1125 static Eina_Bool _tickernoti_callback_register_idler_cb(void *data)
1127 retv_if(!data, EINA_FALSE);
1129 notification_register_detailed_changed_cb(_ticker_noti_detailed_changed_cb, data);
1134 int ticker_init(void *data)
1137 /* Register notification changed cb */
1138 ecore_idler_add(_tickernoti_callback_register_idler_cb, data);
1140 return INDICATOR_ERROR_NONE;
1143 int ticker_fini(void *data)
1145 struct appdata *ad = NULL;
1146 ticker_info_s *ticker_info = NULL;
1152 ticker_info = evas_object_data_del(ad->win.win, PRIVATE_DATA_KEY_TICKER_INFO);
1153 retv_if(!ticker_info, 0);
1155 if (ticker_info->timer) {
1156 ecore_timer_del(ticker_info->timer);
1157 ticker_info->timer = NULL;
1160 return INDICATOR_ERROR_NONE;