2 * Copyright 2012 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
21 #include <runtime_info.h>
23 #include <unicode/udat.h>
24 #include <unicode/udatpg.h>
25 #include <unicode/ustring.h>
28 #include "indicator.h"
29 #include "indicator_ui.h"
30 #include "indicator_gui.h"
31 #include "indicator_icon_util.h"
32 #include "indicator_util.h"
35 #define SYSTEM_RESUME "system_wakeup"
37 #define TIME_FONT_SIZE_24 34
38 #define TIME_FONT_SIZE_12 30
39 #define TIME_FONT_SIZE_BATTERY 32
40 #define TIME_FONT_COLOR 243, 243, 243, 255
42 #define AMPM_FONT_SIZE 24
43 #define AMPM_FONT_COLOR 243, 243, 243, 255
44 #define LABEL_STRING "<font_size=%d>%s" \
47 #define BATTERY_TIMER_INTERVAL 3
48 #define BATTERY_TIMER_INTERVAL_CHARGING 30
50 #define CLOCK_STR_LEN 256
53 INDICATOR_CLOCK_MODE_12H = 0,
54 INDICATOR_CLOCK_MODE_24H,
55 INDICATOR_CLOCK_MODE_MAX
59 static int clock_mode = INDICATOR_CLOCK_MODE_12H;
60 static int apm_length = 0;
61 static int apm_position = 0;
62 static Ecore_Timer *timer = NULL;
63 static Ecore_Timer *battery_timer = NULL;
64 static Ecore_Timer *battery_charging_timer = NULL;
65 static int battery_charging = 0;
66 static int battery_charging_first = 0;
68 static int register_clock_module(void *data);
69 static int unregister_clock_module(void);
70 static int hib_enter_clock_module(void);
71 static int hib_leave_clock_module(void *data);
72 static int language_changed_cb(void *data);
73 static int region_changed_cb(void *data);
74 static int wake_up_cb(void *data);
76 #define ICON_PRIORITY INDICATOR_PRIORITY_FIXED6
77 #define MODULE_NAME "clock"
79 static void indicator_get_time_by_region(char* output, void* data);
80 static void ICU_set_timezone(const char *timezone);
81 static void indicator_clock_display_battery_percentage(void *data,int win_type );
83 Indicator_Icon_Object sysclock[INDICATOR_WIN_MAX] = {
85 .win_type = INDICATOR_WIN_PORT,
86 .type = INDICATOR_TXT_ICON,
88 .priority = ICON_PRIORITY,
89 .always_top = EINA_FALSE,
92 .obj_exist = EINA_FALSE,
93 .exist_in_view = EINA_FALSE,
94 .init = register_clock_module,
95 .fini = unregister_clock_module,
96 .hib_enter = hib_enter_clock_module,
97 .hib_leave = hib_leave_clock_module,
99 .region_changed = region_changed_cb,
100 .lang_changed = language_changed_cb,
101 .wake_up = wake_up_cb
104 .win_type = INDICATOR_WIN_LAND,
105 .type = INDICATOR_TXT_ICON,
107 .priority = ICON_PRIORITY,
108 .always_top = EINA_FALSE,
111 .obj_exist = EINA_FALSE,
112 .exist_in_view = EINA_FALSE,
113 .init = register_clock_module,
114 .fini = unregister_clock_module,
115 .hib_enter = hib_enter_clock_module,
116 .hib_leave = hib_leave_clock_module,
117 .lang_changed = NULL,
118 .region_changed = region_changed_cb,
119 .lang_changed = language_changed_cb,
120 .wake_up = wake_up_cb
124 static void set_app_state(void* data)
128 for (i=0 ; i<INDICATOR_WIN_MAX ; i++)
130 sysclock[i].ad = data;
134 static void indicator_clock_changed_cb(void *data)
137 char time_buf[128], ampm_buf[128];
138 char buf[CLOCK_STR_LEN];
139 char icu_apm[CLOCK_STR_LEN] = {0,};
141 struct tm *ts = NULL;
146 retif(data == NULL, , "Invalid parameter!");
148 if(indicator_util_get_update_flag()==0)
150 DBG("need to update");
154 if (battery_timer != NULL || battery_charging_timer != NULL)
156 DBG("battery is displaying. ignore clock callback");
161 ts = localtime(&ctime);
166 ecore_timer_del(timer);
170 memset(time_str, 0x00, sizeof(time_str));
171 memset(time_buf, 0x00, sizeof(time_buf));
172 memset(ampm_buf, 0x00, sizeof(ampm_buf));
173 memset(buf, 0x00, sizeof(buf));
176 ecore_timer_add(60 - ts->tm_sec, (void *)indicator_clock_changed_cb,
179 indicator_get_time_by_region(icu_apm,data);
181 if (clock_mode == INDICATOR_CLOCK_MODE_12H) {
182 char bf1[32] = { 0, };
185 if(apm_length>0 && apm_length<=4)
187 snprintf(ampm_buf, sizeof(ampm_buf),LABEL_STRING, AMPM_FONT_SIZE,icu_apm);
191 if (ts->tm_hour >= 0 && ts->tm_hour < 12)
192 snprintf(ampm_buf, sizeof(ampm_buf),
193 LABEL_STRING, AMPM_FONT_SIZE,
196 snprintf(ampm_buf, sizeof(ampm_buf),
197 LABEL_STRING, AMPM_FONT_SIZE,
201 strftime(bf1, sizeof(bf1), "%l", ts);
203 strftime(bf1, sizeof(bf1), ":%M", ts);
205 snprintf(time_str, sizeof(time_str), "%d%s", hour, bf1);
206 font_size = TIME_FONT_SIZE_12;
207 indicator_signal_emit(data,"indicator.clock.ampm","indicator.prog");
210 font_size = TIME_FONT_SIZE_24;
211 strftime(time_str, sizeof(time_str), "%H:%M", ts);
212 indicator_signal_emit(data,"indicator.clock.default","indicator.prog");
215 snprintf(time_buf, sizeof(time_buf), LABEL_STRING, font_size, time_str);
217 if(apm_position == 0)
218 len = snprintf(buf, sizeof(buf), "%s%s", ampm_buf, time_buf);
220 len = snprintf(buf, sizeof(buf), "%s%s", time_buf, ampm_buf);
223 ERR("Unexpected ERROR!");
227 INFO("[CLOCK MODULE] Timer Status : %d Time: %s", timer, buf);
229 indicator_part_text_emit(data,"elm.text.clock", buf);
234 static void indicator_clock_format_changed_cb(keynode_t *node, void *data)
236 retif(data == NULL, , "Invalid parameter!");
240 bool is_24hour_enabled = false;
242 INFO("[Enter] indicator_clock_format_changed_cb");
244 r = runtime_info_get_value_bool(
245 RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED, &is_24hour_enabled);
247 if( r==RUNTIME_INFO_ERROR_NONE&&is_24hour_enabled==true)
249 clock_mode = INDICATOR_CLOCK_MODE_24H;
253 clock_mode = INDICATOR_CLOCK_MODE_12H;
256 char *timezone = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
257 ICU_set_timezone(timezone);
258 indicator_clock_changed_cb(data);
262 static void indicator_clock_pm_state_change_cb(keynode_t *node, void *data)
266 retif(data == NULL, , "Invalid parameter!");
268 vconf_get_int(VCONFKEY_PM_STATE, &status);
272 case VCONFKEY_PM_STATE_LCDOFF:
274 ecore_timer_del(timer);
278 if (battery_timer != NULL) {
279 ecore_timer_del(battery_timer);
280 battery_timer = NULL;
283 if (battery_charging_timer != NULL) {
284 ecore_timer_del(battery_charging_timer);
285 battery_charging_timer = NULL;
294 static void indicator_clock_battery_disp_changed_cb(keynode_t *node, void *data)
298 vconf_get_int(VCONFKEY_BATTERY_DISP_STATE,&status);
300 DBG("indicator_clock_battery_disp_changed_cb(%d)",status);
304 indicator_clock_display_battery_percentage(data,0);
305 indicator_clock_display_battery_percentage(data,1);
309 indicator_clock_display_battery_percentage(data,status);
313 static void indicator_clock_charging_now_cb(keynode_t *node, void *data)
318 retif(data == NULL, , "Invalid parameter!");
320 vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
322 vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &status);
324 battery_charging = status;
326 DBG("indicator_clock_charging_now_cb(%d)",status);
328 if(lock_state==VCONFKEY_IDLE_LOCK)
330 DBG("indicator_clock_charging_now_cb:lock_state(%d)",lock_state);
334 if(battery_charging_first == 1&&status==1)
336 DBG("indicator_clock_charging_now_cb : ignore(%d)",status);
341 battery_charging_first = 1;
342 indicator_clock_display_battery_percentage(data,0);
346 static void indicator_clock_battery_capacity_cb(keynode_t *node, void *data)
348 retif(data == NULL, , "Invalid parameter!");
350 if(battery_charging==1&&battery_charging_timer!=NULL)
352 DBG("indicator_clock_battery_capacity_cb:battery_charging(%d)",battery_charging);
353 indicator_clock_display_battery_percentage(data,0);
358 static void indicator_clock_usb_cb(keynode_t *node, void *data)
362 retif(data == NULL, , "Invalid parameter!");
364 vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &status);
366 DBG("indicator_clock_usb_cb(%d)",status);
368 if(status==VCONFKEY_SYSMAN_USB_DISCONNECTED)
370 battery_charging_first = 0;
371 if (battery_charging_timer != NULL)
373 ecore_timer_del(battery_charging_timer);
374 battery_charging_timer = NULL;
376 indicator_clock_changed_cb(data);
380 static void indicator_clock_battery_display_cb(void *data)
382 INFO("indicator_clock_battery_charging_stop_cb");
384 if (battery_timer != NULL) {
385 ecore_timer_del(battery_timer);
386 battery_timer = NULL;
389 indicator_clock_changed_cb(data);
392 static void indicator_clock_battery_charging_stop_cb(void *data)
395 INFO("indicator_clock_battery_charging_stop_cb");
397 if (battery_charging_timer != NULL) {
398 ecore_timer_del(battery_charging_timer);
399 battery_charging_timer = NULL;
402 indicator_clock_changed_cb(data);
405 static void indicator_clock_lock_state_cb(keynode_t *node, void *data)
409 retif(data == NULL, , "Invalid parameter!");
411 vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &status);
413 DBG("indicator_clock_lock_state_cb(%d)",status);
415 if(status==VCONFKEY_IDLE_UNLOCK && battery_charging==1)
417 battery_charging_first = 1;
418 indicator_clock_display_battery_percentage(data,0);
423 static void indicator_clock_display_battery_percentage(void *data,int win_type )
427 int battery_capa = 0;
428 char buf[256] = {0,};
429 char temp[256] = {0,};
430 struct appdata *ad = (struct appdata *)data;
433 if(battery_charging_timer!=NULL)
435 INFO("30sec timer alive");
439 ret = vconf_get_bool(VCONFKEY_SETAPPL_BATTERY_PERCENTAGE_BOOL, &status);
441 ERR("Fail to get [%s: %d]",
442 VCONFKEY_SETAPPL_BATTERY_PERCENTAGE_BOOL, ret);
446 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &battery_capa);
449 ERR("Fail to get [VCONFKEY_SYSMAN_BATTERY_CAPACITY:%d]", ret);
452 if (battery_capa < 0)
454 INFO("Invalid Battery Capacity: %d", battery_capa);
458 INFO("Battery Capacity: %d", battery_capa);
460 if (battery_capa > 100)
463 snprintf(temp, sizeof(temp), "%d%%",battery_capa);
465 snprintf(buf, sizeof(buf), LABEL_STRING, TIME_FONT_SIZE_BATTERY, temp);
467 INFO("indicator_clock_display_battery_percentage %s", buf);
469 indicator_part_text_emit_by_win(&(ad->win[win_type]),"elm.text.clock", buf);
471 if(battery_charging == 1)
474 battery_charging_timer = ecore_timer_add(BATTERY_TIMER_INTERVAL_CHARGING, (void *)indicator_clock_battery_charging_stop_cb,data);
478 if (battery_timer != NULL) {
479 ecore_timer_del(battery_timer);
480 battery_timer = NULL;
483 battery_timer = ecore_timer_add(BATTERY_TIMER_INTERVAL, (void *)indicator_clock_battery_display_cb,data);
490 static int language_changed_cb(void *data)
492 DBG("language_changed_cb");
493 indicator_clock_changed_cb(data);
497 static int region_changed_cb(void *data)
499 DBG("region_changed_cb");
500 indicator_clock_format_changed_cb(NULL, data);
504 static int wake_up_cb(void *data)
508 INFO("CLOCK wake_up_cb");
510 retif(data == NULL, FAIL, "Invalid parameter!");
512 vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &status);
514 DBG("wake_up_cb(%d)",status);
516 if(status==VCONFKEY_IDLE_UNLOCK && battery_charging==1)
518 indicator_clock_display_battery_percentage(data,0);
522 indicator_clock_changed_cb(data);
527 static int register_clock_module(void *data)
531 retif(data == NULL, FAIL, "Invalid parameter!");
535 notifd = heynoti_init();
538 ERR("heynoti_init is failed");
543 heynoti_subscribe(notifd, SYSTEM_RESUME, indicator_clock_changed_cb,
546 ERR("Fail: register SYSTEM_RESUME");
550 ret = heynoti_attach_handler(notifd);
552 ERR("Failed to attach heynoti handler!");
556 ret = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
557 indicator_clock_format_changed_cb, data);
559 ERR("Fail: register VCONFKEY_SYSTEM_TIME_CHANGED");
563 ret = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224,
564 indicator_clock_format_changed_cb, data);
566 ERR("Fail: register VCONFKEY_REGIONFORMAT_TIME1224");
570 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_TIMEZONE_INT,
571 indicator_clock_format_changed_cb, data);
573 ERR("Fail: register VCONFKEY_SETAPPL_TIMEZONE_INT");
577 ret = vconf_notify_key_changed(VCONFKEY_PM_STATE, indicator_clock_pm_state_change_cb, (void *)data);
580 ERR("Fail: register VCONFKEY_PM_STATE");
584 ret = vconf_notify_key_changed(VCONFKEY_BATTERY_DISP_STATE,
585 indicator_clock_battery_disp_changed_cb, data);
587 ERR("Fail: register VCONFKEY_SETAPPL_TIMEZONE_INT");
591 ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
592 indicator_clock_battery_capacity_cb, data);
594 ERR("Failed to register callback!");
598 ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
599 indicator_clock_charging_now_cb, data);
601 ERR("Failed to register callback!");
605 ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
606 indicator_clock_usb_cb, data);
608 ERR("Failed to register callback!");
613 ret = vconf_notify_key_changed(VCONFKEY_IDLE_LOCK_STATE,
614 indicator_clock_lock_state_cb, data);
616 ERR("Failed to register callback!");
621 indicator_clock_format_changed_cb(NULL, data);
626 static int unregister_clock_module(void)
630 heynoti_unsubscribe(notifd, SYSTEM_RESUME, indicator_clock_changed_cb);
632 heynoti_close(notifd);
635 ret = vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
636 indicator_clock_format_changed_cb);
638 ERR("Fail: unregister VCONFKEY_SYSTEM_TIME_CHANGED");
640 ret = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224,
641 indicator_clock_format_changed_cb);
643 ERR("Fail: unregister VCONFKEY_REGIONFORMAT_TIME1224");
645 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_TIMEZONE_INT,
646 indicator_clock_format_changed_cb);
648 ERR("Fail: unregister VCONFKEY_SETAPPL_TIMEZONE_INT");
650 ret = vconf_ignore_key_changed(VCONFKEY_PM_STATE,
651 indicator_clock_battery_disp_changed_cb);
653 ERR("Fail: unregister VCONFKEY_PM_STATE");
655 ret = vconf_ignore_key_changed(VCONFKEY_BATTERY_DISP_STATE,
656 indicator_clock_pm_state_change_cb);
658 ERR("Fail: unregister VCONFKEY_BATTERY_DISP_STATE");
660 ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
661 indicator_clock_battery_capacity_cb);
663 ERR("Fail: unregister VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW");
665 ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
666 indicator_clock_charging_now_cb);
668 ERR("Fail: unregister VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW");
670 ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
671 indicator_clock_usb_cb);
673 ERR("Fail: unregister VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW");
676 ret = vconf_ignore_key_changed(VCONFKEY_IDLE_LOCK_STATE,
677 indicator_clock_lock_state_cb);
679 ERR("Fail: unregister VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW");
682 ecore_timer_del(timer);
688 static int hib_enter_clock_module(void)
692 ret = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224,
693 indicator_clock_format_changed_cb);
695 ERR("Fail: unregister VCONFKEY_REGIONFORMAT_TIME1224");
698 ecore_timer_del(timer);
705 static int hib_leave_clock_module(void *data)
709 retif(data == NULL, FAIL, "Invalid parameter!");
711 ret = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224,
712 indicator_clock_format_changed_cb, data);
713 retif(ret != OK, FAIL, "Failed to register callback!");
715 indicator_clock_format_changed_cb(NULL, data);
719 void indicator_get_time_by_region(char* output,void *data)
721 retif(data == NULL, , "Data parameter is NULL");
722 retif(output == NULL, , "output parameter is NULL");
725 UChar customSkeleton[CLOCK_STR_LEN] = { 0, };
726 UErrorCode status = U_ZERO_ERROR;
727 UDateFormat *formatter = NULL;
729 UChar bestPattern[CLOCK_STR_LEN] = { 0, };
730 UChar formatted[CLOCK_STR_LEN] = { 0, };
732 char bestPatternString[CLOCK_STR_LEN] = { 0, };
733 char formattedString[CLOCK_STR_LEN] = { 0, };
735 UDateTimePatternGenerator *pattern_generator = NULL;
737 char *time_skeleton = "hhmm";
739 char *locale = vconf_get_str(VCONFKEY_REGIONFORMAT);
740 if (locale == NULL) {
741 DBG("[Error] get value of VCONFKEY_REGIONFORMAT fail.");
744 u_uastrncpy(customSkeleton, time_skeleton, strlen(time_skeleton));
746 pattern_generator = udatpg_open(locale, &status);
748 int32_t bestPatternCapacity = (int32_t) (sizeof(bestPattern) / sizeof((bestPattern)[0]));
749 (void)udatpg_getBestPattern(pattern_generator, customSkeleton,
750 u_strlen(customSkeleton), bestPattern,
751 bestPatternCapacity, &status);
753 u_austrcpy(bestPatternString, bestPattern);
754 u_uastrcpy(bestPattern,"a");
756 if(bestPatternString[0] == 'a')
765 UDate date = ucal_getNow();
766 formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, NULL, -1, bestPattern, -1, &status);
767 int32_t formattedCapacity = (int32_t) (sizeof(formatted) / sizeof((formatted)[0]));
768 (void)udat_format(formatter, date, formatted, formattedCapacity, NULL, &status);
769 u_austrcpy(formattedString, formatted);
771 DBG("DATE & TIME is %s %s %d %s", locale, formattedString, u_strlen(formatted), bestPatternString);
773 apm_length = u_strlen(formatted);
775 udatpg_close(pattern_generator);
777 udat_close(formatter);
779 if(strlen(formattedString)<CLOCK_STR_LEN)
781 strncpy(output,formattedString,strlen(formattedString));
785 strncpy(output,formattedString,CLOCK_STR_LEN-1);
791 static UChar *uastrcpy(const char *chars)
796 str = (UChar *) malloc(sizeof(UChar) *(len + 1));
799 u_uastrcpy(str, chars);
803 static void ICU_set_timezone(const char *timezone)
807 ERR("TIMEZONE is NULL");
811 DBG("ICU_set_timezone = %s ", timezone);
812 UErrorCode ec = U_ZERO_ERROR;
813 UChar *str = uastrcpy(timezone);
815 ucal_setDefaultTimeZone(str, &ec);
817 DBG("ucal_setDefaultTimeZone() SUCCESS ");
819 DBG("ucal_setDefaultTimeZone() FAILED : %s ",