2 * Copyright 2012 Samsung Electronics Co., Ltd
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
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.
20 #include <runtime_info.h>
22 #include <unicode/udat.h>
23 #include <unicode/udatpg.h>
24 #include <unicode/ustring.h>
27 #include "indicator.h"
28 #include "indicator_ui.h"
29 #include "indicator_gui.h"
30 #include "indicator_icon_util.h"
31 #include "indicator_util.h"
34 #define SYSTEM_RESUME "system_wakeup"
36 #define TIME_FONT_SIZE_24 34
37 #define TIME_FONT_SIZE_12 30
38 #define TIME_FONT_SIZE_BATTERY 32
39 #define TIME_FONT_COLOR 243, 243, 243, 255
41 #define AMPM_FONT_SIZE 24
42 #define AMPM_FONT_COLOR 243, 243, 243, 255
43 #define LABEL_STRING "<font_size=%d>%s" \
46 #define BATTERY_TIMER_INTERVAL 3
47 #define BATTERY_TIMER_INTERVAL_CHARGING 30
49 #define CLOCK_STR_LEN 256
52 INDICATOR_CLOCK_MODE_12H = 0,
53 INDICATOR_CLOCK_MODE_24H,
54 INDICATOR_CLOCK_MODE_MAX
58 static int clock_mode = INDICATOR_CLOCK_MODE_12H;
59 static int apm_length = 0;
60 static int apm_position = 0;
61 static Ecore_Timer *timer = NULL;
62 static Ecore_Timer *battery_timer = NULL;
63 static Ecore_Timer *battery_charging_timer = NULL;
64 static int battery_charging = 0;
65 static int battery_charging_first = 0;
67 static int register_clock_module(void *data);
68 static int unregister_clock_module(void);
69 static int language_changed_cb(void *data);
70 static int region_changed_cb(void *data);
71 static int wake_up_cb(void *data);
73 #define ICON_PRIORITY INDICATOR_PRIORITY_FIXED6
74 #define MODULE_NAME "clock"
76 static void indicator_get_time_by_region(char* output, void* data);
77 static void ICU_set_timezone(const char *timezone);
78 static void indicator_clock_display_battery_percentage(void *data,int win_type );
80 Indicator_Icon_Object sysclock[INDICATOR_WIN_MAX] = {
82 .win_type = INDICATOR_WIN_PORT,
83 .type = INDICATOR_TXT_ICON,
85 .priority = ICON_PRIORITY,
86 .always_top = EINA_FALSE,
89 .obj_exist = EINA_FALSE,
90 .exist_in_view = EINA_FALSE,
91 .init = register_clock_module,
92 .fini = unregister_clock_module,
94 .region_changed = region_changed_cb,
95 .lang_changed = language_changed_cb,
99 .win_type = INDICATOR_WIN_LAND,
100 .type = INDICATOR_TXT_ICON,
102 .priority = ICON_PRIORITY,
103 .always_top = EINA_FALSE,
106 .obj_exist = EINA_FALSE,
107 .exist_in_view = EINA_FALSE,
108 .init = register_clock_module,
109 .fini = unregister_clock_module,
110 .lang_changed = NULL,
111 .region_changed = region_changed_cb,
112 .lang_changed = language_changed_cb,
113 .wake_up = wake_up_cb
117 static void set_app_state(void* data)
121 for (i=0 ; i<INDICATOR_WIN_MAX ; i++)
123 sysclock[i].ad = data;
127 static void indicator_clock_changed_cb(void *data)
130 char time_buf[128], ampm_buf[128];
131 char buf[CLOCK_STR_LEN];
132 char icu_apm[CLOCK_STR_LEN] = {0,};
134 struct tm *ts = NULL;
139 retif(data == NULL, , "Invalid parameter!");
141 if(indicator_util_get_update_flag()==0)
143 DBG("need to update");
147 if (battery_timer != NULL || battery_charging_timer != NULL)
149 DBG("battery is displaying. ignore clock callback");
154 ts = localtime(&ctime);
159 ecore_timer_del(timer);
163 memset(time_str, 0x00, sizeof(time_str));
164 memset(time_buf, 0x00, sizeof(time_buf));
165 memset(ampm_buf, 0x00, sizeof(ampm_buf));
166 memset(buf, 0x00, sizeof(buf));
169 ecore_timer_add(60 - ts->tm_sec, (void *)indicator_clock_changed_cb,
172 indicator_get_time_by_region(icu_apm,data);
174 if (clock_mode == INDICATOR_CLOCK_MODE_12H) {
175 char bf1[32] = { 0, };
178 if(apm_length>0 && apm_length<=4)
180 snprintf(ampm_buf, sizeof(ampm_buf),LABEL_STRING, AMPM_FONT_SIZE,icu_apm);
184 if (ts->tm_hour >= 0 && ts->tm_hour < 12)
185 snprintf(ampm_buf, sizeof(ampm_buf),
186 LABEL_STRING, AMPM_FONT_SIZE,
189 snprintf(ampm_buf, sizeof(ampm_buf),
190 LABEL_STRING, AMPM_FONT_SIZE,
194 strftime(bf1, sizeof(bf1), "%l", ts);
196 strftime(bf1, sizeof(bf1), ":%M", ts);
198 snprintf(time_str, sizeof(time_str), "%d%s", hour, bf1);
199 font_size = TIME_FONT_SIZE_12;
200 indicator_signal_emit(data,"indicator.clock.ampm","indicator.prog");
203 font_size = TIME_FONT_SIZE_24;
204 strftime(time_str, sizeof(time_str), "%H:%M", ts);
205 indicator_signal_emit(data,"indicator.clock.default","indicator.prog");
208 snprintf(time_buf, sizeof(time_buf), LABEL_STRING, font_size, time_str);
210 if(apm_position == 0)
211 len = snprintf(buf, sizeof(buf), "%s%s", ampm_buf, time_buf);
213 len = snprintf(buf, sizeof(buf), "%s%s", time_buf, ampm_buf);
216 ERR("Unexpected ERROR!");
220 INFO("[CLOCK MODULE] Timer Status : %d Time: %s", timer, buf);
222 indicator_part_text_emit(data,"elm.text.clock", buf);
227 static void indicator_clock_format_changed_cb(keynode_t *node, void *data)
229 retif(data == NULL, , "Invalid parameter!");
233 bool is_24hour_enabled = false;
235 INFO("[Enter] indicator_clock_format_changed_cb");
237 r = runtime_info_get_value_bool(
238 RUNTIME_INFO_KEY_24HOUR_CLOCK_FORMAT_ENABLED, &is_24hour_enabled);
240 if( r==RUNTIME_INFO_ERROR_NONE&&is_24hour_enabled==true)
242 clock_mode = INDICATOR_CLOCK_MODE_24H;
246 clock_mode = INDICATOR_CLOCK_MODE_12H;
249 char *timezone = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
250 ICU_set_timezone(timezone);
251 indicator_clock_changed_cb(data);
255 static void indicator_clock_pm_state_change_cb(keynode_t *node, void *data)
259 retif(data == NULL, , "Invalid parameter!");
261 vconf_get_int(VCONFKEY_PM_STATE, &status);
265 case VCONFKEY_PM_STATE_LCDOFF:
267 ecore_timer_del(timer);
271 if (battery_timer != NULL) {
272 ecore_timer_del(battery_timer);
273 battery_timer = NULL;
276 if (battery_charging_timer != NULL) {
277 ecore_timer_del(battery_charging_timer);
278 battery_charging_timer = NULL;
287 static void indicator_clock_battery_display_cb(void *data)
289 INFO("indicator_clock_battery_display_cb");
291 if (battery_timer != NULL) {
292 ecore_timer_del(battery_timer);
293 battery_timer = NULL;
296 indicator_clock_changed_cb(data);
299 static void indicator_clock_battery_disp_changed_cb(keynode_t *node, void *data)
303 vconf_get_int(VCONFKEY_BATTERY_DISP_STATE,&status);
305 DBG("indicator_clock_battery_disp_changed_cb(%d)",status);
307 if(battery_charging_timer!=NULL)
309 ERR("30s timer alive");
312 if (battery_timer != NULL) {
313 ecore_timer_del(battery_timer);
314 battery_timer = NULL;
317 battery_timer = ecore_timer_add(BATTERY_TIMER_INTERVAL, (void *)indicator_clock_battery_display_cb,data);
321 indicator_clock_display_battery_percentage(data,0);
322 indicator_clock_display_battery_percentage(data,1);
326 indicator_clock_display_battery_percentage(data,status);
330 static void indicator_clock_battery_charging_stop_cb(void *data)
333 INFO("indicator_clock_battery_charging_stop_cb");
335 if (battery_charging_timer != NULL) {
336 ecore_timer_del(battery_charging_timer);
337 battery_charging_timer = NULL;
340 indicator_clock_changed_cb(data);
343 static void indicator_clock_charging_now_cb(keynode_t *node, void *data)
348 retif(data == NULL, , "Invalid parameter!");
350 vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_state);
352 vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &status);
354 battery_charging = status;
356 DBG("indicator_clock_charging_now_cb(%d)",status);
358 if(lock_state==VCONFKEY_IDLE_LOCK)
360 DBG("indicator_clock_charging_now_cb:lock_state(%d)",lock_state);
366 if(battery_charging_first == 0)
368 battery_charging_first = 1;
369 if (battery_charging_timer != NULL)
371 ecore_timer_del(battery_charging_timer);
372 battery_charging_timer = NULL;
374 battery_charging_timer = ecore_timer_add(BATTERY_TIMER_INTERVAL_CHARGING, (void *)indicator_clock_battery_charging_stop_cb,data);
376 indicator_clock_display_battery_percentage(data,0);
381 battery_charging_first = 0;
382 indicator_clock_battery_charging_stop_cb(data);
387 static void indicator_clock_battery_capacity_cb(keynode_t *node, void *data)
389 retif(data == NULL, , "Invalid parameter!");
391 if(battery_charging_timer!=NULL||battery_timer!=NULL)
393 DBG("indicator_clock_battery_capacity_cb:battery_charging(%d)",battery_charging);
394 indicator_clock_display_battery_percentage(data,0);
399 static void indicator_clock_usb_cb(keynode_t *node, void *data)
403 retif(data == NULL, , "Invalid parameter!");
405 vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &status);
407 DBG("indicator_clock_usb_cb(%d)",status);
409 if(status==VCONFKEY_SYSMAN_USB_DISCONNECTED)
411 if (battery_charging_timer != NULL)
413 ecore_timer_del(battery_charging_timer);
414 battery_charging_timer = NULL;
416 indicator_clock_changed_cb(data);
420 static void indicator_clock_lock_state_cb(keynode_t *node, void *data)
424 retif(data == NULL, , "Invalid parameter!");
426 vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &status);
428 DBG("indicator_clock_lock_state_cb(%d)",status);
430 if(status==VCONFKEY_IDLE_UNLOCK && battery_charging==1)
432 if (battery_charging_timer != NULL)
434 ecore_timer_del(battery_charging_timer);
435 battery_charging_timer = NULL;
437 battery_charging_timer = ecore_timer_add(BATTERY_TIMER_INTERVAL_CHARGING, (void *)indicator_clock_battery_charging_stop_cb,data);
439 indicator_clock_display_battery_percentage(data,0);
443 static void indicator_clock_battery_precentage_setting_cb(keynode_t *node, void *data)
448 retif(data == NULL, , "Invalid parameter!");
450 ret = vconf_get_bool(VCONFKEY_SETAPPL_BATTERY_PERCENTAGE_BOOL, &status);
453 ERR("Fail to get [%s: %d]",VCONFKEY_SETAPPL_BATTERY_PERCENTAGE_BOOL, ret);
458 if (battery_charging_timer != NULL) {
459 ecore_timer_del(battery_charging_timer);
460 battery_charging_timer = NULL;
462 if (battery_timer != NULL) {
463 ecore_timer_del(battery_timer);
464 battery_timer = NULL;
466 indicator_clock_changed_cb(data);
470 static void indicator_clock_display_battery_percentage(void *data,int win_type )
474 int battery_capa = 0;
475 char buf[256] = {0,};
476 char temp[256] = {0,};
477 struct appdata *ad = (struct appdata *)data;
479 ret = vconf_get_bool(VCONFKEY_SETAPPL_BATTERY_PERCENTAGE_BOOL, &status);
481 ERR("Fail to get [%s: %d]",
482 VCONFKEY_SETAPPL_BATTERY_PERCENTAGE_BOOL, ret);
486 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &battery_capa);
489 ERR("Fail to get [VCONFKEY_SYSMAN_BATTERY_CAPACITY:%d]", ret);
492 if (battery_capa < 0)
494 INFO("Invalid Battery Capacity: %d", battery_capa);
498 INFO("Battery Capacity: %d", battery_capa);
500 if (battery_capa > 100)
503 snprintf(temp, sizeof(temp), "%d%%",battery_capa);
505 snprintf(buf, sizeof(buf), LABEL_STRING, TIME_FONT_SIZE_BATTERY, temp);
507 INFO("indicator_clock_display_battery_percentage %s", buf);
509 indicator_part_text_emit_by_win(&(ad->win[win_type]),"elm.text.clock", buf);
516 static int language_changed_cb(void *data)
518 DBG("language_changed_cb");
519 indicator_clock_changed_cb(data);
523 static int region_changed_cb(void *data)
525 DBG("region_changed_cb");
526 indicator_clock_format_changed_cb(NULL, data);
530 static int wake_up_cb(void *data)
535 INFO("CLOCK wake_up_cb");
537 retif(data == NULL, FAIL, "Invalid parameter!");
539 vconf_get_int(VCONFKEY_IDLE_LOCK_STATE, &lock_type);
541 vconf_get_bool(VCONFKEY_SETAPPL_BATTERY_PERCENTAGE_BOOL, &status);
543 DBG("wake_up_cb(%d,%d)",lock_type,status);
547 if(lock_type == VCONFKEY_IDLE_UNLOCK && battery_charging==1)
549 indicator_clock_display_battery_percentage(data,0);
554 indicator_clock_changed_cb(data);
559 static int register_clock_module(void *data)
563 retif(data == NULL, FAIL, "Invalid parameter!");
567 ret = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
568 indicator_clock_format_changed_cb, data);
570 ERR("Fail: register VCONFKEY_SYSTEM_TIME_CHANGED");
574 ret = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT_TIME1224,
575 indicator_clock_format_changed_cb, data);
577 ERR("Fail: register VCONFKEY_REGIONFORMAT_TIME1224");
581 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_TIMEZONE_INT,
582 indicator_clock_format_changed_cb, data);
584 ERR("Fail: register VCONFKEY_SETAPPL_TIMEZONE_INT");
588 ret = vconf_notify_key_changed(VCONFKEY_PM_STATE, indicator_clock_pm_state_change_cb, (void *)data);
591 ERR("Fail: register VCONFKEY_PM_STATE");
595 ret = vconf_notify_key_changed(VCONFKEY_BATTERY_DISP_STATE,
596 indicator_clock_battery_disp_changed_cb, data);
598 ERR("Fail: register VCONFKEY_SETAPPL_TIMEZONE_INT");
602 ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
603 indicator_clock_battery_capacity_cb, data);
605 ERR("Failed to register callback!");
609 ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
610 indicator_clock_charging_now_cb, data);
612 ERR("Failed to register callback!");
616 ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
617 indicator_clock_usb_cb, data);
619 ERR("Failed to register callback!");
624 ret = vconf_notify_key_changed(VCONFKEY_IDLE_LOCK_STATE,
625 indicator_clock_lock_state_cb, data);
627 ERR("Failed to register callback!");
631 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_BATTERY_PERCENTAGE_BOOL,
632 indicator_clock_battery_precentage_setting_cb, data);
634 ERR("Failed to register callback!");
638 indicator_clock_format_changed_cb(NULL, data);
643 static int unregister_clock_module(void)
647 ret = vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
648 indicator_clock_format_changed_cb);
650 ERR("Fail: unregister VCONFKEY_SYSTEM_TIME_CHANGED");
652 ret = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT_TIME1224,
653 indicator_clock_format_changed_cb);
655 ERR("Fail: unregister VCONFKEY_REGIONFORMAT_TIME1224");
657 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_TIMEZONE_INT,
658 indicator_clock_format_changed_cb);
660 ERR("Fail: unregister VCONFKEY_SETAPPL_TIMEZONE_INT");
662 ret = vconf_ignore_key_changed(VCONFKEY_PM_STATE,
663 indicator_clock_pm_state_change_cb);
665 ERR("Fail: unregister VCONFKEY_PM_STATE");
667 ret = vconf_ignore_key_changed(VCONFKEY_BATTERY_DISP_STATE,
668 indicator_clock_battery_disp_changed_cb);
670 ERR("Fail: unregister VCONFKEY_BATTERY_DISP_STATE");
672 ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
673 indicator_clock_battery_capacity_cb);
675 ERR("Fail: unregister VCONFKEY_SYSMAN_BATTERY_CAPACITY");
677 ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW,
678 indicator_clock_charging_now_cb);
680 ERR("Fail: unregister VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW");
682 ret = vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
683 indicator_clock_usb_cb);
685 ERR("Fail: unregister VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW");
688 ret = vconf_ignore_key_changed(VCONFKEY_IDLE_LOCK_STATE,
689 indicator_clock_lock_state_cb);
691 ERR("Fail: unregister VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW");
693 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_BATTERY_PERCENTAGE_BOOL,
694 indicator_clock_battery_precentage_setting_cb);
696 ERR("Fail: unregister VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW");
699 ecore_timer_del(timer);
703 if (battery_timer != NULL) {
704 ecore_timer_del(battery_timer);
705 battery_timer = NULL;
708 if (battery_charging_timer != NULL) {
709 ecore_timer_del(battery_charging_timer);
710 battery_charging_timer = NULL;
716 void indicator_get_time_by_region(char* output,void *data)
718 retif(data == NULL, , "Data parameter is NULL");
719 retif(output == NULL, , "output parameter is NULL");
722 UChar customSkeleton[CLOCK_STR_LEN] = { 0, };
723 UErrorCode status = U_ZERO_ERROR;
724 UDateFormat *formatter = NULL;
726 UChar bestPattern[CLOCK_STR_LEN] = { 0, };
727 UChar formatted[CLOCK_STR_LEN] = { 0, };
729 char bestPatternString[CLOCK_STR_LEN] = { 0, };
730 char formattedString[CLOCK_STR_LEN] = { 0, };
732 UDateTimePatternGenerator *pattern_generator = NULL;
734 char *time_skeleton = "hhmm";
736 char *locale = vconf_get_str(VCONFKEY_REGIONFORMAT);
737 if (locale == NULL) {
738 DBG("[Error] get value of VCONFKEY_REGIONFORMAT fail.");
741 u_uastrncpy(customSkeleton, time_skeleton, strlen(time_skeleton));
743 pattern_generator = udatpg_open(locale, &status);
745 int32_t bestPatternCapacity = (int32_t) (sizeof(bestPattern) / sizeof((bestPattern)[0]));
746 (void)udatpg_getBestPattern(pattern_generator, customSkeleton,
747 u_strlen(customSkeleton), bestPattern,
748 bestPatternCapacity, &status);
750 u_austrcpy(bestPatternString, bestPattern);
751 u_uastrcpy(bestPattern,"a");
753 if(bestPatternString[0] == 'a')
762 UDate date = ucal_getNow();
763 formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, NULL, -1, bestPattern, -1, &status);
764 int32_t formattedCapacity = (int32_t) (sizeof(formatted) / sizeof((formatted)[0]));
765 (void)udat_format(formatter, date, formatted, formattedCapacity, NULL, &status);
766 u_austrcpy(formattedString, formatted);
768 DBG("DATE & TIME is %s %s %d %s", locale, formattedString, u_strlen(formatted), bestPatternString);
770 apm_length = u_strlen(formatted);
772 udatpg_close(pattern_generator);
774 udat_close(formatter);
776 if(strlen(formattedString)<CLOCK_STR_LEN)
778 strncpy(output,formattedString,strlen(formattedString));
782 strncpy(output,formattedString,CLOCK_STR_LEN-1);
788 static UChar *uastrcpy(const char *chars)
793 str = (UChar *) malloc(sizeof(UChar) *(len + 1));
796 u_uastrcpy(str, chars);
800 static void ICU_set_timezone(const char *timezone)
804 ERR("TIMEZONE is NULL");
808 DBG("ICU_set_timezone = %s ", timezone);
809 UErrorCode ec = U_ZERO_ERROR;
810 UChar *str = uastrcpy(timezone);
812 ucal_setDefaultTimeZone(str, &ec);
814 DBG("ucal_setDefaultTimeZone() SUCCESS ");
816 DBG("ucal_setDefaultTimeZone() FAILED : %s ",