2 * Copyright (c) 2009-2014 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.
17 #include <appcore-common.h>
19 #include <unicode/utypes.h>
20 #include <unicode/putil.h>
21 #include <unicode/uiter.h>
22 #include <unicode/udat.h>
23 #include <unicode/udatpg.h>
24 #include <unicode/ustring.h>
26 #include "lockscreen.h"
28 #include "lock_time.h"
30 #include "default_lock.h"
32 #define TIME_LOCALE_FILE "/opt/etc/localtime"
33 #define TIME_ZONEINFO_PATH "/usr/share/zoneinfo/"
34 #define TIME_ZONEINFO_PATH_LEN (strlen(TIME_ZONEINFO_PATH))
36 static struct _s_info {
40 UDateFormat *formatter_date;
41 UDateFormat *formatter_time;
42 UDateFormat *formatter_ampm;
43 UDateTimePatternGenerator *generator;
45 char *timeregion_format;
47 Eina_Bool is_pre_meridiem;
54 .is_timer_enabled = 0,
55 .formatter_date = NULL,
56 .formatter_time = NULL,
57 .formatter_ampm = NULL,
59 .timeformat = APPCORE_TIME_FORMAT_24,
60 .timeregion_format = NULL,
62 .is_pre_meridiem = EINA_FALSE,
68 static void _timer_add(void);
70 static UDateFormat *__util_time_ampm_formatter_get(void *data, const char *timezone_id)
72 UErrorCode status = U_ZERO_ERROR;
74 UChar u_best_pattern[64] = {0,};
75 UDateFormat *formatter = NULL;
77 u_uastrcpy(u_best_pattern, "a");
79 UChar u_timezone_id[64] = {0,};
81 u_uastrncpy(u_timezone_id, s_info.timezone_id, sizeof(u_timezone_id));
82 formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, s_info.timeregion_format, u_timezone_id, -1,
83 u_best_pattern, -1, &status);
85 u_uastrncpy(u_timezone_id, timezone_id, sizeof(u_timezone_id));
86 formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, s_info.timeregion_format, u_timezone_id, -1,
87 u_best_pattern, -1, &status);
89 if (U_FAILURE(status)) {
90 _E("udat_open() failed");
94 char a_best_pattern[64] = {0,};
95 u_austrcpy(a_best_pattern, u_best_pattern);
100 static UDateFormat *__util_time_time_formatter_get(void *data, int time_format, const char *timezone_id)
103 UErrorCode status = U_ZERO_ERROR;
104 UChar u_pattern[64] = {0,};
105 UChar u_best_pattern[64] = {0,};
106 int32_t u_best_pattern_capacity;
107 char a_best_pattern[64] = {0,};
109 UDateFormat *formatter = NULL;
111 retv_if(!s_info.generator, NULL);
113 if (time_format == APPCORE_TIME_FORMAT_24) {
114 snprintf(buf, sizeof(buf)-1, "%s", "HH:mm");
116 /* set time format 12 */
117 snprintf(buf, sizeof(buf)-1, "%s", "h:mm");
120 if (!u_uastrncpy(u_pattern, buf, sizeof(u_pattern))) {
121 _E("u_uastrncpy() is failed.");
125 u_best_pattern_capacity =
126 (int32_t) (sizeof(u_best_pattern) / sizeof((u_best_pattern)[0]));
128 udatpg_getBestPattern(s_info.generator, u_pattern, u_strlen(u_pattern),
129 u_best_pattern, u_best_pattern_capacity, &status);
130 if (U_FAILURE(status)) {
131 _E("udatpg_getBestPattern() failed");
135 u_austrcpy(a_best_pattern, u_best_pattern);
137 if (a_best_pattern[0] == 'a') {
138 s_info.is_pre_meridiem = EINA_TRUE;
140 s_info.is_pre_meridiem = EINA_FALSE;
144 char *a_best_pattern_fixed = strtok_r(a_best_pattern, "a", &saveptr);
145 a_best_pattern_fixed = strtok_r(a_best_pattern_fixed, " ", &saveptr);
146 if (a_best_pattern_fixed) {
147 u_uastrcpy(u_best_pattern, a_best_pattern_fixed);
150 UChar u_timezone_id[64] = {0,};
152 u_uastrncpy(u_timezone_id, s_info.timezone_id, sizeof(u_timezone_id));
153 formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, s_info.timeregion_format, u_timezone_id, -1,
154 u_best_pattern, -1, &status);
156 u_uastrncpy(u_timezone_id, timezone_id, sizeof(u_timezone_id));
157 formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, s_info.timeregion_format, u_timezone_id, -1,
158 u_best_pattern, -1, &status);
160 if (U_FAILURE(status)) {
161 _E("udat_open() failed");
168 static UDateFormat *__util_time_date_formatter_get(void *data, const char *timezone_id, const char *skeleton)
170 UErrorCode status = U_ZERO_ERROR;
172 UChar u_skeleton[64] = {0,};
173 int skeleton_len = 0;
175 UChar u_best_pattern[64] = {0,};
176 int32_t u_best_pattern_capacity;
177 UDateFormat *formatter = NULL;
179 retv_if(!s_info.generator, NULL);
181 u_uastrncpy(u_skeleton, skeleton, strlen(skeleton));
182 skeleton_len = u_strlen(u_skeleton);
184 u_best_pattern_capacity =
185 (int32_t) (sizeof(u_best_pattern) / sizeof((u_best_pattern)[0]));
187 udatpg_getBestPattern(s_info.generator, u_skeleton, skeleton_len,
188 u_best_pattern, u_best_pattern_capacity, &status);
189 if (U_FAILURE(status)) {
190 _E("udatpg_getBestPattern() failed");
194 UChar u_timezone_id[64] = {0,};
196 u_uastrncpy(u_timezone_id, s_info.timezone_id, sizeof(u_timezone_id));
197 formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, s_info.timeregion_format, u_timezone_id, -1,
198 u_best_pattern, -1, &status);
200 u_uastrncpy(u_timezone_id, timezone_id, sizeof(u_timezone_id));
201 formatter = udat_open(UDAT_IGNORE, UDAT_IGNORE, s_info.timeregion_format, u_timezone_id, -1,
202 u_best_pattern, -1, &status);
204 if (U_FAILURE(status)) {
205 _E("udat_open() failed");
209 char a_best_pattern[64] = {0,};
210 u_austrcpy(a_best_pattern, u_best_pattern);
215 static int __util_time_formatted_time_get(UDateFormat *formatter, time_t tt, char *buf, int buf_len)
217 retv_if (!formatter, -1);
219 UDate u_time = (UDate)tt * 1000;
220 UChar u_formatted_str[64] = {0,};
221 int32_t u_formatted_str_capacity;
222 UErrorCode status = U_ZERO_ERROR;
224 u_formatted_str_capacity = (int32_t)(sizeof(u_formatted_str) / sizeof((u_formatted_str)[0]));
226 (void)udat_format(formatter, u_time, u_formatted_str, u_formatted_str_capacity, NULL, &status);
227 if (U_FAILURE(status)) {
228 _E("udat_format() failed");
232 u_austrncpy(buf, u_formatted_str, buf_len-1);
233 _D("time(%d) formatted(%s)", tt, buf);
235 return (int)u_strlen(u_formatted_str);
238 static void _util_time_get(int is_current_time, time_t tt_a, char *timezone, char *skeleton, char **str_date, char **str_time, char **str_meridiem)
242 char buf_date[512] = {0,};
243 char buf_time[512] = {0,};
244 char buf_ampm[512] = {0,};
246 if (is_current_time == 1) {
251 localtime_r(&tt, &st);
253 UDateFormat *formatter_date = NULL;
254 UDateFormat *formatter_time = NULL;
255 UDateFormat *formatter_ampm = NULL;
257 if (timezone != NULL) {
259 formatter_date = __util_time_date_formatter_get(NULL, timezone, "MMMMEd");
261 formatter_date = __util_time_date_formatter_get(NULL, timezone, skeleton);
263 formatter_time = __util_time_time_formatter_get(NULL, s_info.timeformat, timezone);
264 if (s_info.timeformat == APPCORE_TIME_FORMAT_12) {
265 formatter_ampm = __util_time_ampm_formatter_get(NULL, timezone);
269 formatter_date = s_info.formatter_date;
271 formatter_date = __util_time_date_formatter_get(NULL, timezone, skeleton);
273 formatter_time = s_info.formatter_time;
274 formatter_ampm = s_info.formatter_ampm;
277 if (!s_info.formatter_time) {
278 s_info.formatter_time = __util_time_time_formatter_get(NULL, s_info.timeformat, NULL);
281 __util_time_formatted_time_get(formatter_date, tt, buf_date, sizeof(buf_date));
284 if (s_info.timeformat == APPCORE_TIME_FORMAT_24) {
285 __util_time_formatted_time_get(formatter_time, tt, buf_time, sizeof(buf_time)-1);
287 __util_time_formatted_time_get(formatter_time, tt, buf_time, sizeof(buf_time)-1);
288 int ampm_len = __util_time_formatted_time_get(formatter_ampm, tt, buf_ampm, sizeof(buf_ampm)-1);
290 if (st.tm_hour >= 0 && st.tm_hour < 12) {
291 snprintf(buf_ampm, sizeof(buf_ampm)-1, "AM");
293 snprintf(buf_ampm, sizeof(buf_ampm)-1, "PM");
298 if (str_date != NULL) {
299 *str_date = strdup(buf_date);
302 if (str_time != NULL) {
303 *str_time = strdup(buf_time);
306 if (str_meridiem != NULL) {
307 *str_meridiem = strdup(buf_ampm);
310 if (timezone != NULL) {
311 if (formatter_date != NULL) udat_close(formatter_date);
312 if (formatter_time != NULL) udat_close(formatter_time);
313 if (formatter_ampm != NULL) udat_close(formatter_ampm);
317 static char *_get_locale(void)
319 return strdup("en_US.UTF-8");
322 static int _is_korea_locale()
325 char *locale = _get_locale();
327 if (strstr(locale,"ko_KR")) {
336 lock_error_e lock_time_update(void)
338 Evas_Object *swipe_layout = NULL;
341 time_t tt = time(NULL);
342 localtime_r(&tt, &st);
344 char *str_date = NULL;
345 char *str_time = NULL;
346 char *str_meridiem = NULL;
347 char time_buf[PATH_MAX] = {0,};
348 char date_buf[PATH_MAX] = {0,};
350 swipe_layout = lock_default_swipe_layout_get();
351 retv_if(!swipe_layout, LOCK_ERROR_FAIL);
353 _util_time_get(1, 0, NULL, "MMMMEd", &str_date, &str_time, &str_meridiem);
354 if (s_info.timeformat == APPCORE_TIME_FORMAT_12) {
355 if (_is_korea_locale()) {
356 snprintf(time_buf, sizeof(time_buf), "<%s>%s </>%s", "small_font", str_meridiem, str_time);
358 snprintf(time_buf, sizeof(time_buf), "%s<%s> %s</>", str_time, "small_font", str_meridiem);
361 if (_is_korea_locale()) {
362 snprintf(time_buf, sizeof(time_buf), "%s", str_time);
364 snprintf(time_buf, sizeof(time_buf), "%s", str_time);
368 snprintf(date_buf, sizeof(time_buf), "<%s>%s</>", "small_font", str_date);
370 elm_object_part_text_set(swipe_layout, "txt.time", time_buf);
371 elm_object_part_text_set(swipe_layout, "txt.date", str_date);
377 return LOCK_ERROR_OK;
380 static UDateTimePatternGenerator *__util_time_generator_get(void *data)
382 UErrorCode status = U_ZERO_ERROR;
383 UDateTimePatternGenerator *generator = NULL;
385 retv_if(!s_info.timeregion_format, NULL);
387 generator = udatpg_open(s_info.timeregion_format, &status);
388 if (U_FAILURE(status)) {
389 _E("udatpg_open() failed");
396 static void _util_time_formatters_create(void *data)
398 if (!s_info.generator) {
399 s_info.generator = __util_time_generator_get(NULL);
402 if (!s_info.formatter_date) {
403 s_info.formatter_date = __util_time_date_formatter_get(NULL, NULL, "MMMMEd");
406 if (s_info.timeformat == APPCORE_TIME_FORMAT_12) {
407 if (!s_info.formatter_ampm) {
408 s_info.formatter_ampm = __util_time_ampm_formatter_get(NULL, NULL);
412 if (!s_info.formatter_time) {
413 s_info.formatter_time = __util_time_time_formatter_get(NULL, s_info.timeformat, NULL);
417 static char *_util_time_timezone_id_get(void)
419 char tz[1024] = {0,};
420 char *timezone = NULL;
422 memcpy(tz, "Asia/Seoul",strlen("Asia/Seoul"));
423 timezone = strdup(tz);
425 _D("timezone is %s ", timezone);
429 static char *_util_time_regionformat_get(void)
431 return strdup("en_US");
434 static void _formatter_create(void)
436 bool timeformat_24_bool = false;
438 timeformat_24_bool = true;
440 if (timeformat_24_bool) {
441 _D("TIMEFORMAT : 24");
442 s_info.timeformat = APPCORE_TIME_FORMAT_24;
444 _D("TIMEFORMAT : 12");
445 s_info.timeformat = APPCORE_TIME_FORMAT_12;
448 if (!s_info.timeregion_format) {
449 s_info.timeregion_format = _util_time_regionformat_get();
452 if (!s_info.timezone_id) {
453 s_info.timezone_id = _util_time_timezone_id_get();
456 _util_time_formatters_create(NULL);
458 s_info.is_initialized = 1;
459 _D("%d %s %s", s_info.timeformat, s_info.timeregion_format, s_info.timezone_id);
462 static void _util_time_formatters_destroy(void)
464 if (s_info.generator) {
465 udat_close(s_info.generator);
466 s_info.generator = NULL;
468 if (s_info.formatter_date) {
469 udat_close(s_info.formatter_date);
470 s_info.formatter_date = NULL;
472 if (s_info.formatter_time) {
473 udat_close(s_info.formatter_time);
474 s_info.formatter_time = NULL;
476 if (s_info.formatter_ampm) {
477 udat_close(s_info.formatter_ampm);
478 s_info.formatter_ampm = NULL;
482 static void _formatter_destroy(void)
484 if (s_info.timeregion_format) {
485 free(s_info.timeregion_format);
486 s_info.timeregion_format = NULL;
488 if (s_info.timezone_id) {
489 free(s_info.timezone_id);
490 s_info.timezone_id = NULL;
493 _util_time_formatters_destroy();
495 s_info.is_initialized = 0;
498 static void _util_time_vconf_changed_cb(keynode_t *key, void *data)
500 int index = (int)data;
502 _formatter_destroy();
506 s_info.need_sync = 1;
510 static void _time_event_attach(void)
514 /* register vconf cbs */
515 ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_SVC_ROAM, _util_time_vconf_changed_cb, (void*)3);
517 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_TIMEZONE_INT, _util_time_vconf_changed_cb, (void*)4);
521 static void _time_event_deattach(void)
525 /* unregister vconf cbs */
526 ret = vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SVC_ROAM, _util_time_vconf_changed_cb);
528 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_TIMEZONE_INT, _util_time_vconf_changed_cb);
532 static Eina_Bool _timer_cb(void *data)
536 if (LOCK_ERROR_OK != lock_time_update()) {
537 _E("Failed to update time & date");
540 if (s_info.is_timer_enabled == 1) {
543 return ECORE_CALLBACK_CANCEL;
546 static void _timer_add(void)
552 localtime_r(&tt, &st);
554 s_info.timer = ecore_timer_add(60 - st.tm_sec, _timer_cb, NULL);
557 static void _timer_del(void)
559 if (s_info.timer != NULL) {
560 ecore_timer_del(s_info.timer);
565 void lock_time_timer_enable_set(int is_enable)
568 s_info.is_timer_enabled = is_enable;
570 if (is_enable == 1) {
575 static void _util_time_reset_view(void)
577 Evas_Object *swipe_layout = lock_default_swipe_layout_get();
578 ret_if(!swipe_layout);
580 elm_object_part_text_set(swipe_layout, "txt.time", "");
581 elm_object_part_text_set(swipe_layout, "txt.date", "");
584 char *lock_time_formatted_noti_time_get(time_t ts)
586 char *time_str = NULL;
587 char *curr_date = NULL;
588 char *noti_date = NULL;
590 _util_time_get(0, time(NULL), NULL, UDAT_YEAR_NUM_MONTH_DAY, &curr_date, NULL, NULL);
591 _util_time_get(0, ts, NULL, UDAT_YEAR_NUM_MONTH_DAY, ¬i_date, NULL, NULL);
593 if (curr_date != NULL && noti_date != NULL) {
594 if (strcmp(curr_date, noti_date)) {
596 _util_time_get(0, ts, NULL, UDAT_ABBR_MONTH_DAY, &date, NULL, NULL);
603 if (s_info.timeformat == APPCORE_TIME_FORMAT_24) {
604 _util_time_get(0, ts, NULL, UDAT_HOUR_MINUTE , NULL, &time_str, NULL);
610 localtime_r(&ts, &st);
611 _util_time_get(0, ts, NULL, UDAT_HOUR_MINUTE , NULL, &time_str, NULL);
613 char buf_ampm[512] = {0,};
614 int ampm_len = __util_time_formatted_time_get(s_info.formatter_ampm, ts, buf_ampm, sizeof(buf_ampm) - 1);
616 if (st.tm_hour >= 0 && st.tm_hour < 12) {
617 snprintf(buf_ampm, sizeof(buf_ampm)-1, "AM");
619 snprintf(buf_ampm, sizeof(buf_ampm)-1, "PM");
625 if (_is_korea_locale()) {
626 snprintf(time, sizeof(time), "%s %s", buf_ampm, time_str);
628 snprintf(time, sizeof(time), "%s %s", time_str, buf_ampm);
639 void lock_time_resume(void)
641 if (s_info.need_sync == 1) {
642 _formatter_destroy();
644 s_info.need_sync = 0;
647 if (LOCK_ERROR_OK != lock_time_update()) {
648 _E("Failed to update time & date");
651 lock_time_timer_enable_set(1);
654 void lock_time_pause(void)
656 _util_time_reset_view();
657 lock_time_timer_enable_set(0);
660 void lock_time_init(void)
663 _time_event_attach();
665 if (LOCK_ERROR_OK != lock_time_update()) {
666 _E("Failed to update time & date");
669 lock_time_timer_enable_set(1);
672 void lock_time_fini(void)
674 _formatter_destroy();
675 _time_event_deattach();
677 lock_time_timer_enable_set(0);