4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
29 #include "cal_internal.h"
32 #include "cal_typedef.h"
33 #include "cal_inotify.h"
35 #include "cal_db_util.h"
37 #include "cal_db_query.h"
38 #include "cal_server_reminder.h"
40 #define CAL_SEARCH_LOOP_MAX 4
42 #define COLOR_CYAN "\033[0;36m"
43 #define COLOR_END "\033[0;m"
48 long long int alert_utime; // to compare
51 int type; // utime, local
53 int record; // todo, event
58 // this api is necessary for repeat instance.
59 static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
61 int ret = CALENDAR_ERROR_NONE;
62 char query[CAL_DB_SQL_MAX_LEN] = {0};
63 cal_db_util_error_e dbret = CAL_DB_OK;
65 ret = _cal_db_util_begin_trans();
66 if (CALENDAR_ERROR_NONE != ret)
68 ERR("_cal_db_util_begin_trans() failed");
69 return CALENDAR_ERROR_DB_FAILED;
72 DBG("alarm_id(%d)", alarm_id);
74 snprintf(query, sizeof(query), "UPDATE %s SET alarm_id = 0 WHERE alarm_id =%d ",
75 CAL_TABLE_ALARM, alarm_id);
77 dbret = _cal_db_util_query_exec(query);
78 if (CAL_DB_OK != dbret)
80 ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
83 case CAL_DB_ERROR_NO_SPACE:
84 _cal_db_util_end_trans(false);
85 return CALENDAR_ERROR_FILE_NO_SPACE;
87 _cal_db_util_end_trans(false);
88 return CALENDAR_ERROR_DB_FAILED;
91 _cal_db_util_end_trans(true);
92 return CALENDAR_ERROR_NONE;
95 static int __cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
99 DBG("remove alarm id(%d)", alarm_id);
100 __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
101 ret = alarmmgr_remove_alarm(alarm_id);
102 if (ret != ALARMMGR_RESULT_SUCCESS)
104 ERR("alarmmgr_remove_alarm() failed(ret:%d)", ret);
107 return CALENDAR_ERROR_NONE;
110 static int __cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
112 int ret = CALENDAR_ERROR_NONE;
113 char query[CAL_DB_SQL_MAX_LEN] = {0};
114 cal_db_util_error_e dbret = CAL_DB_OK;
116 ret = _cal_db_util_begin_trans();
117 if (CALENDAR_ERROR_NONE != ret)
119 ERR("_cal_db_util_begin_trans() failed");
120 return CALENDAR_ERROR_DB_FAILED;
123 DBG("Update alarm_id(%d) in alarm table", alarm_id);
124 snprintf(query, sizeof(query), "UPDATE %s SET "
126 "WHERE event_id =%d AND remind_tick =%d AND remind_tick_unit =%d",
129 event_id, tick, unit);
131 dbret = _cal_db_util_query_exec(query);
132 if (CAL_DB_OK != dbret)
134 ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
137 case CAL_DB_ERROR_NO_SPACE:
138 _cal_db_util_end_trans(false);
139 return CALENDAR_ERROR_FILE_NO_SPACE;
141 _cal_db_util_end_trans(false);
142 return CALENDAR_ERROR_DB_FAILED;
145 _cal_db_util_end_trans(true);
146 return CALENDAR_ERROR_NONE;
149 static long long int __cal_server_alarm_get_alert_utime(const char *field, int event_id, time_t current)
151 char query[CAL_DB_SQL_MAX_LEN] = {0};
152 snprintf(query, sizeof(query), "SELECT %s FROM %s "
153 "WHERE event_id=%d AND %s>%ld ORDER BY %s LIMIT 1",
154 field, CAL_TABLE_NORMAL_INSTANCE, event_id, field, current, field);
156 sqlite3_stmt *stmt = NULL;
157 stmt = _cal_db_util_query_prepare(query);
159 long long int utime = 0;
160 if (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
161 utime = sqlite3_column_int(stmt, 0);
163 sqlite3_finalize(stmt);
167 static int __cal_server_alarm_get_alert_localtime(const char *field, int event_id, time_t current)
169 char query[CAL_DB_SQL_MAX_LEN] = {0};
172 localtime_r(¤t, &st);
173 time_t mod_current = timegm(&st);
174 snprintf(query, sizeof(query), "SELECT %s FROM %s "
175 "WHERE event_id=%d AND strftime('%%s', %s)>%ld ORDER BY %s LIMIT 1",
176 field, CAL_TABLE_ALLDAY_INSTANCE, event_id, field, mod_current, field);
178 sqlite3_stmt *stmt = NULL;
179 stmt = _cal_db_util_query_prepare(query);
181 const char *datetime = NULL;
182 if (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
183 datetime = (const char *)sqlite3_column_text(stmt, 0);
185 if (NULL == datetime || '\0' == *datetime) {
186 ERR("Invalid datetime [%s]", datetime);
187 sqlite3_finalize(stmt);
191 int y = 0, m = 0, d = 0;
192 int h = 0, n = 0, s = 0;
193 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
194 sqlite3_finalize(stmt);
196 st.tm_year = y - 1900;
203 return (long long int)mktime(&st);
207 * to get aler time, time(NULL) is not accurate. 1 secs diff could be occured.
208 * so, searching DB is neccessary to find alert time.
210 static int __cal_server_alarm_get_alert_time(int alarm_id, time_t *tt_alert)
212 retvm_if(NULL == tt_alert, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter: tt_alert is NULL");
214 char query[CAL_DB_SQL_MAX_LEN] = {0};
215 snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
216 "A.alarm_type, A.alarm_utime, A.alarm_datetime, B.system_type, "
217 "B.type, B.dtstart_type, B.dtend_type "
218 "FROM %s as A, %s as B ON A.event_id = B.id WHERE alarm_id =%d ",
219 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE, alarm_id);
221 sqlite3_stmt *stmt = NULL;
222 stmt = _cal_db_util_query_prepare(query);
223 retvm_if (NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
229 long long int utime = 0;
230 const char *datetime = NULL;
233 int dtstart_type = 0;
237 if (CAL_DB_ROW == _cal_db_util_stmt_step(stmt)) {
239 event_id = sqlite3_column_int(stmt, index++);
240 unit = sqlite3_column_int(stmt, index++);
241 tick = sqlite3_column_int(stmt, index++);
242 type = sqlite3_column_int(stmt, index++);
243 utime = sqlite3_column_int64(stmt, index++);
244 datetime = (const char *)sqlite3_column_text(stmt, index++);
245 system_type = sqlite3_column_int(stmt, index++);
246 record_type = sqlite3_column_int(stmt, index++);
247 dtstart_type = sqlite3_column_int(stmt, index++);
248 dtend_type = sqlite3_column_int(stmt, index++);
251 if (NULL == tt_alert) {
252 ERR("Invalid parameter: tt_alert is NULL");
253 sqlite3_finalize(stmt);
254 return CALENDAR_ERROR_INVALID_PARAMETER;
257 if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
258 if (CALENDAR_TIME_UTIME == type) {
262 int y = 0, m = 0, d = 0;
263 int h = 0, n = 0, s = 0;
264 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
266 st.tm_year = y - 1900;
272 *tt_alert = (long long int)mktime(&st);
273 DBG("datetime[%s] to %02d:%02d:%02d (%lld)", datetime, h, n, s, *tt_alert);
275 sqlite3_finalize(stmt);
276 return CALENDAR_ERROR_NONE;
278 sqlite3_finalize(stmt);
282 time_t current = time(NULL);
283 current += (tick * unit);
284 current -= 2; // in case time passed
288 case CALENDAR_BOOK_TYPE_EVENT:
289 switch (dtstart_type)
291 case CALENDAR_TIME_UTIME:
292 utime = __cal_server_alarm_get_alert_utime("dtstart_utime", event_id, current);
295 case CALENDAR_TIME_LOCALTIME:
296 utime = __cal_server_alarm_get_alert_localtime("dtstart_datetime", event_id, current);
301 case CALENDAR_BOOK_TYPE_TODO:
304 case CALENDAR_TIME_UTIME:
305 utime = __cal_server_alarm_get_alert_utime("dtend_utime", event_id, current);
308 case CALENDAR_TIME_LOCALTIME:
309 utime = __cal_server_alarm_get_alert_localtime("dtend_datetime", event_id, current);
314 DBG("alert_time(%lld) = utime(%lld) - (tick(%d) * unit(%d))", *tt_alert, utime, datetime, tick, unit);
316 *tt_alert = utime - (tick * unit);
317 return CALENDAR_ERROR_NONE;
320 static void __cal_server_alarm_get_upcoming_specific_utime(time_t utime, bool get_all, GList **l) // case 1
322 char query_specific_utime[CAL_DB_SQL_MAX_LEN] = {0};
323 snprintf(query_specific_utime, sizeof(query_specific_utime),
324 // alarm utime(normal event + todo)
325 "SELECT event_id, remind_tick_unit, remind_tick, alarm_type, alarm_utime, alarm_datetime "
327 "WHERE remind_tick_unit =%d AND alarm_type =%d AND alarm_utime %s %ld %s",
329 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
330 true == get_all ? "=" : ">",
332 true == get_all ? "" : "ORDER BY alarm_utime ASC LIMIT 1");
334 sqlite3_stmt *stmt = NULL;
335 stmt = _cal_db_util_query_prepare(query_specific_utime);
337 ERR("_cal_db_util_query_prepare() Failed");
338 ERR("[%s]", query_specific_utime);
342 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt)) {
343 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
346 ad->event_id = sqlite3_column_int(stmt, index++);
347 ad->unit = sqlite3_column_int(stmt, index++);
348 ad->tick = sqlite3_column_int(stmt, index++);
349 ad->type = sqlite3_column_int(stmt, index++);
350 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
351 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
352 *l = g_list_append(*l, ad);
353 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
354 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
355 ad->alert_utime = ad->time;
356 if (false == get_all) break;
358 sqlite3_finalize(stmt);
361 static void __cal_server_alarm_get_upcoming_specific_localtime(const char *datetime, bool get_all, GList **l)
363 char query_specific_localtime[CAL_DB_SQL_MAX_LEN] = {0};
364 snprintf(query_specific_localtime, sizeof(query_specific_localtime),
365 "SELECT event_id, remind_tick_unit, remind_tick, "
366 "alarm_type, alarm_utime, alarm_datetime "
368 "WHERE remind_tick_unit=%d AND alarm_type=%d AND alarm_datetime %s '%s' %s",
370 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
371 true == get_all ? "=" : ">",
373 true == get_all ? "" : "ORDER BY alarm_datetime ASC LIMIT 1");
375 sqlite3_stmt *stmt = NULL;
376 stmt = _cal_db_util_query_prepare(query_specific_localtime);
378 ERR("_cal_db_util_query_prepare() Failed");
379 ERR("[%s]", query_specific_localtime);
383 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt)) {
384 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
387 ad->event_id = sqlite3_column_int(stmt, index++);
388 ad->unit = sqlite3_column_int(stmt, index++);
389 ad->tick = sqlite3_column_int(stmt, index++);
390 ad->type = sqlite3_column_int(stmt, index++);
391 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
392 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
393 *l = g_list_append(*l, ad);
394 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
395 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
397 int y = 0, m = 0, d = 0;
398 int h = 0, n = 0, s = 0;
399 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
402 st.tm_year = y - 1900;
408 ad->alert_utime = (long long int)mktime(&st);
409 if (false == get_all) break;
411 sqlite3_finalize(stmt);
414 static void __cal_server_alarm_get_upcoming_nonspecific_event_utime(time_t utime, bool get_all, GList **l)
416 char query_nonspecific_event_utime[CAL_DB_SQL_MAX_LEN] = {0};
417 snprintf(query_nonspecific_event_utime, sizeof(query_nonspecific_event_utime),
418 // A:alarm B:normal instance
419 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, B.dtstart_utime, A.alarm_datetime "
420 "FROM %s as A, %s as B ON A.event_id = B.event_id "
421 "WHERE A.remind_tick_unit >%d AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
422 CAL_TABLE_ALARM, CAL_TABLE_NORMAL_INSTANCE,
423 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
424 true == get_all ? "=" : ">",
426 true == get_all ? "" : "ORDER BY (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1");
428 sqlite3_stmt *stmt = NULL;
429 stmt = _cal_db_util_query_prepare(query_nonspecific_event_utime);
431 ERR("_cal_db_util_query_prepare() Failed");
432 ERR("[%s]", query_nonspecific_event_utime);
436 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt)) {
437 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
440 ad->event_id = sqlite3_column_int(stmt, index++);
441 ad->unit = sqlite3_column_int(stmt, index++);
442 ad->tick = sqlite3_column_int(stmt, index++);
443 ad->type = sqlite3_column_int(stmt, index++);
444 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
445 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
446 *l = g_list_append(*l, ad);
447 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
448 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
450 ad->alert_utime = ad->time - (ad->tick * ad->unit);
451 if (false == get_all) break;
453 sqlite3_finalize(stmt);
456 static void __cal_server_alarm_get_upcoming_nonspecific_event_localtime(const char *datetime, bool get_all, GList **l)
458 char query_nonspecific_event_localtime[CAL_DB_SQL_MAX_LEN] = {0};
459 snprintf(query_nonspecific_event_localtime, sizeof(query_nonspecific_event_localtime),
461 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, A.alarm_utime, B.dtstart_datetime "
462 "FROM %s as A, %s as B ON A.event_id = B.event_id "
463 "WHERE A.remind_tick_unit >%d AND "
464 "(strftime('%%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
465 CAL_TABLE_ALARM, CAL_TABLE_ALLDAY_INSTANCE,
466 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
468 true == get_all ? "=" : ">",
469 true == get_all ? "" : "ORDER BY (strftime('%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
470 sqlite3_stmt *stmt = NULL;
471 stmt = _cal_db_util_query_prepare(query_nonspecific_event_localtime);
473 ERR("_cal_db_util_query_prepare() Failed");
474 ERR("[%s]", query_nonspecific_event_localtime);
478 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt)) {
479 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
482 ad->event_id = sqlite3_column_int(stmt, index++);
483 ad->unit = sqlite3_column_int(stmt, index++);
484 ad->tick = sqlite3_column_int(stmt, index++);
485 ad->type = sqlite3_column_int(stmt, index++);
486 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
487 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
488 *l = g_list_append(*l, ad);
489 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
490 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
492 int y = 0, m = 0, d = 0;
493 int h = 0, n = 0, s = 0;
494 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
497 st.tm_year = y - 1900;
503 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
504 if (false == get_all) break;
506 sqlite3_finalize(stmt);
509 static void __cal_server_alarm_get_upcoming_nonspecific_todo_utime(time_t utime, bool get_all, GList **l)
511 char query_nonspecific_todo_utime[CAL_DB_SQL_MAX_LEN] = {0};
512 snprintf(query_nonspecific_todo_utime, sizeof(query_nonspecific_todo_utime),
513 // A:alarm B:todo(normal)
514 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, B.dtend_utime, A.alarm_datetime "
515 "FROM %s as A, %s as B ON A.event_id = B.id "
516 "WHERE A.remind_tick_unit >%d AND B.type =%d "
517 "AND (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
518 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
519 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
520 true == get_all ? "=" : ">",
522 true == get_all ? "" : "ORDER BY (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
524 sqlite3_stmt *stmt = NULL;
525 stmt = _cal_db_util_query_prepare(query_nonspecific_todo_utime);
527 ERR("_cal_db_util_query_prepare() Failed");
528 ERR("[%s]", query_nonspecific_todo_utime);
532 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt)) {
533 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
536 ad->event_id = sqlite3_column_int(stmt, index++);
537 ad->unit = sqlite3_column_int(stmt, index++);
538 ad->tick = sqlite3_column_int(stmt, index++);
539 ad->type = sqlite3_column_int(stmt, index++);
540 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
541 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
542 *l = g_list_append(*l, ad);
543 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
544 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
546 ad->alert_utime = ad->time - (ad->tick * ad->unit);
547 if (false == get_all) break;
549 sqlite3_finalize(stmt);
552 static void __cal_server_alarm_get_upcoming_nonspecific_todo_localtime(const char *datetime, bool get_all, GList **l)
554 char query_nonspecific_todo_localtime[CAL_DB_SQL_MAX_LEN] = {0};
555 snprintf(query_nonspecific_todo_localtime, sizeof(query_nonspecific_todo_localtime),
556 // A:alarm B:todo(allday)
557 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, A.alarm_utime, B.dtend_datetime "
558 "FROM %s as A, %s as B ON A.event_id = B.id "
559 "WHERE A.remind_tick_unit >%d AND B.type =%d "
560 "AND (strftime('%%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
561 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
562 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
564 true == get_all ? "=" : ">",
565 true == get_all ? "" : "ORDER BY (strftime('%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
567 sqlite3_stmt *stmt = NULL;
568 stmt = _cal_db_util_query_prepare(query_nonspecific_todo_localtime);
570 ERR("_cal_db_util_query_prepare() Failed");
571 ERR("[%s]", query_nonspecific_todo_localtime);
575 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt)) {
576 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
579 ad->event_id = sqlite3_column_int(stmt, index++);
580 ad->unit = sqlite3_column_int(stmt, index++);
581 ad->tick = sqlite3_column_int(stmt, index++);
582 ad->type = sqlite3_column_int(stmt, index++);
583 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
584 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
585 *l = g_list_append(*l, ad);
586 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
587 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
589 int y = 0, m = 0, d = 0;
590 int h = 0, n = 0, s = 0;
591 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
594 st.tm_year = y - 1900;
600 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
601 if (false == get_all) break;
603 sqlite3_finalize(stmt);
606 static int __cal_server_alarm_get_alert_list(time_t utime, GList **list)
609 retvm_if (NULL == list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter: list is NULL");
612 struct tm st_local = {0};
613 localtime_r(&utime, &st_local);
614 char datetime[32] = {0};
615 snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
616 st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
617 st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
618 DBG("get alert to register with given time (%ld) datetime[%s]", utime, datetime);
622 __cal_server_alarm_get_upcoming_specific_utime(utime, true, &l);
623 __cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, true, &l);
624 __cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, true, &l);
626 __cal_server_alarm_get_upcoming_specific_localtime(datetime, true, &l);
627 __cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, true, &l);
628 __cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, true, &l);
632 return CALENDAR_ERROR_NONE;
635 static gint __cal_server_alarm_sort_cb(gconstpointer a, gconstpointer b)
637 struct _alarm_data_s *p1 = (struct _alarm_data_s *)a;
638 struct _alarm_data_s *p2 = (struct _alarm_data_s *)b;
639 DBG("%lld) > (%lld)",p1->alert_utime, p2->alert_utime);
641 return p1->alert_utime > p2->alert_utime ? 1 : -1;
644 static GFunc __cal_server_alarm_print_cb(gpointer data, gpointer user_data)
646 struct _alarm_data_s *ad = (struct _alarm_data_s *)data;
647 DBG("id(%d) unit(%d) tick(%d) type(%d) time(%lld) datetime[%s]",
648 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
652 static int __cal_server_alarm_register(GList *alarm_list)
655 retvm_if (NULL == alarm_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter: alarm list is NULL");
657 int ret = CALENDAR_ERROR_NONE;
658 GList *l = g_list_first(alarm_list);
659 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
660 retvm_if (NULL == ad, CALENDAR_ERROR_DB_FAILED, "No data");
662 // clear all alarm which set by mine.
663 ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
664 if (ret != ALARMMGR_RESULT_SUCCESS)
666 ERR("alarmmgr_enum_alarm_ids() failed");
670 time_t mod_time = (time_t)ad->alert_utime;
671 alarm_entry_t *alarm_info = NULL;
672 alarm_info = alarmmgr_create_alarm();
673 if (NULL == alarm_info)
675 ERR("Failed to create alarm");
676 return CALENDAR_ERROR_DB_FAILED;
679 struct tm st_alarm = {0};
681 switch (ad->system_type)
683 case CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR:
684 gmtime_r(&mod_time, &st_alarm);
689 localtime_r(&mod_time, &st_alarm);
693 alarm_date_t date = {0};
694 date.year = st_alarm.tm_year + 1900;
695 date.month = st_alarm.tm_mon + 1;
696 date.day = st_alarm.tm_mday;
697 date.hour = st_alarm.tm_hour;
698 date.min = st_alarm.tm_min;
699 date.sec = st_alarm.tm_sec;
700 alarmmgr_set_time(alarm_info, date);
701 DBG(COLOR_CYAN" >>> registered record id (%d) at %04d/%02d/%02d %02d:%02d:%02d "COLOR_END" (utime(%lld), datetime[%s], tick(%d) unit(%d))",
702 ad->event_id, date.year, date.month, date.day, date.hour, date.min, date.sec,
703 ad->time, ad->datetime, ad->tick, ad->unit);
706 ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
709 ERR("alarmmgr_add_alarm_with_localtime failed (%d)", ret);
710 alarmmgr_free_alarm(alarm_info);
713 DBG("alarmmgr id (%d)", alarm_id);
714 __cal_server_alarm_update_alarm_id(alarm_id, ad->event_id, ad->tick, ad->unit);
715 alarmmgr_free_alarm(alarm_info);
716 return CALENDAR_ERROR_NONE;
719 static bool __app_matched_cb(app_control_h app_control, const char *package, void *user_data)
721 retvm_if (NULL == user_data, true, "Invalid parameter: user_data is NULL");
725 ret = app_control_get_mime(app_control, &mime);
726 retvm_if(APP_CONTROL_ERROR_NONE != ret, true, "app_control_get_mime() is failed(%d)", ret);
728 const char *reminder_mime = "application/x-tizen.calendar.reminder";
729 if (strncmp(mime, reminder_mime, strlen(reminder_mime))) { // not same
730 DBG("get mime[%s] is not [%s]", mime, reminder_mime);
736 GList *alarm_list = (GList *)user_data;
738 len = g_list_length(alarm_list);
740 DBG("len is 0, no alarm list");
744 app_control_h b = NULL;
745 app_control_create(&b);
746 app_control_set_operation(b, APP_CONTROL_OPERATION_DEFAULT);
747 app_control_set_app_id(b, package);
751 ids = calloc(len, sizeof(char *));
753 ERR("calloc() is failed");
754 app_control_destroy(b);
755 return CALENDAR_ERROR_DB_FAILED;
757 GList *l = g_list_first(alarm_list);
759 for (i = 0; i < len; i++) {
760 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
766 DBG("pkg[%s] time[%lld] tick[%d] unit[%d] record_type[%d]",
767 package, ad->time, ad->tick, ad->unit, ad->record);
769 char buf_event_id[128] = {0};
770 char buf_time[128] = {0};
771 char buf_tick[128] = {0};
772 char buf_unit[128] = {0};
773 char buf_record_type[128] = {0};
774 snprintf(buf_event_id, sizeof(buf_event_id), "%d", ad->event_id);
775 snprintf(buf_time, sizeof(buf_time), "%lld", ad->time);
776 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
777 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
778 snprintf(buf_record_type, sizeof(buf_record_type), "%d", ad->record);
781 _cal_server_reminder_add_callback_data(&p, "id", buf_event_id);
782 _cal_server_reminder_add_callback_data(&p, "time", buf_time);
783 _cal_server_reminder_add_callback_data(&p, "tick", buf_tick);
784 _cal_server_reminder_add_callback_data(&p, "unit", buf_unit);
785 _cal_server_reminder_add_callback_data(&p, "type", buf_record_type);
787 app_control_add_extra_data(b, buf_event_id, p); // key: id, value: id=4&time=123123&..
792 ids[i] = strdup(buf_event_id);
796 app_control_add_extra_data_array(b, "ids", (const char **)ids, len);
797 app_control_send_launch_request (b, NULL, NULL);
798 app_control_destroy(b);
801 for (i = 0; i < len; i++) {
810 static void __cal_server_alarm_noti_with_control(GList *alarm_list)
812 retm_if(NULL == alarm_list, "No alarm list");
814 app_control_h app_control = NULL;
815 app_control_create(&app_control);
816 app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW);
817 app_control_set_mime(app_control, "application/x-tizen.calendar.reminder");
818 app_control_foreach_app_matched(app_control, __app_matched_cb, alarm_list);
819 app_control_destroy(app_control);
822 static void __cal_server_alarm_noti_with_callback(GList *alarm_list)
824 retm_if(NULL == alarm_list, "No alarm list");
826 GList *l = g_list_first(alarm_list);
828 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
834 DBG("callback time[%lld] tick[%d] unit[%d] record_type[%d]",
835 ad->time, ad->tick, ad->unit, ad->record);
837 char buf_event_id[128] = {0};
838 char buf_time[128] = {0};
839 char buf_tick[128] = {0};
840 char buf_unit[128] = {0};
841 char buf_record_type[128] = {0};
842 snprintf(buf_event_id, sizeof(buf_event_id), "%d", ad->event_id);
843 snprintf(buf_time, sizeof(buf_time), "%lld", ad->time);
844 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
845 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
846 snprintf(buf_record_type, sizeof(buf_record_type), "%d", ad->record);
849 _cal_server_reminder_add_callback_data(&p, "id", buf_event_id);
850 _cal_server_reminder_add_callback_data(&p, "time", buf_time);
851 _cal_server_reminder_add_callback_data(&p, "tick", buf_tick);
852 _cal_server_reminder_add_callback_data(&p, "unit", buf_unit);
853 _cal_server_reminder_add_callback_data(&p, "type", buf_record_type);
854 _cal_server_reminder_publish(p);
861 static int __cal_server_alarm_register_with_alarmmgr(time_t utime)
864 struct tm st_local = {0};
865 localtime_r(&utime, &st_local);
866 char datetime[32] = {0};
867 snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
868 st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
869 st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
870 DBG("search alarm to register with given time (%ld) datetime[%s]", utime, datetime);
874 __cal_server_alarm_get_upcoming_specific_utime(utime, false, &l);
875 __cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, false, &l);
876 __cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, false, &l);
878 __cal_server_alarm_get_upcoming_specific_localtime(datetime, false, &l);
879 __cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, false, &l);
880 __cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, false, &l);
883 DBG("No alarm list");
884 return CALENDAR_ERROR_NONE;
887 l = g_list_sort(l, __cal_server_alarm_sort_cb);
888 g_list_foreach(l, (GFunc)__cal_server_alarm_print_cb, NULL);
889 __cal_server_alarm_register(l);
894 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
899 return CALENDAR_ERROR_NONE;
902 static int _alert_cb(alarm_id_t alarm_id, void *data)
907 DBG("alarm_id (%ld)", alarm_id);
909 __cal_server_alarm_get_alert_time(alarm_id, &tt_alert);
910 __cal_server_alarm_get_alert_list(tt_alert, &l);
911 __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
912 __cal_server_alarm_noti_with_callback(l);
913 __cal_server_alarm_noti_with_control(l);
914 __cal_server_alarm_register_with_alarmmgr(tt_alert);
919 ////////////////////////////////////////////////////////////////////
920 static void __cal_server_alarm_timechange_cb(keynode_t *node, void *data)
927 t = vconf_keynode_get_int(node);
931 ret = vconf_get_int(VCONFKEY_SYSTEM_TIMECHANGE, &t);
932 warn_if(0 < ret, "vconf_get_int() Failed");
937 __cal_server_alarm_register_with_alarmmgr(time(NULL));
941 DBG("system changed time(%ld)", t);
942 __cal_server_alarm_register_with_alarmmgr((time_t)t);
946 void __cal_server_alarm_set_timechange(void)
948 vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
949 __cal_server_alarm_timechange_cb, NULL);
951 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT,
952 __cal_server_alarm_timechange_cb, NULL);
953 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT,
954 __cal_server_alarm_timechange_cb, NULL);
955 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE,
956 __cal_server_alarm_timechange_cb, NULL);
959 static void __changed_cb(const char* view_uri, void* data)
962 __cal_server_alarm_register_with_alarmmgr(time(NULL));
965 static int __cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
967 _cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
968 _cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
972 int _cal_server_alarm(void)
977 __cal_server_alarm_set_timechange();
978 __cal_server_alarm_set_inotify(__changed_cb);
980 ret = alarmmgr_init("calendar-service");
981 retvm_if(ret < 0, ret, "alarmmgr_init() failed");
983 ret = alarmmgr_set_cb(_alert_cb, NULL);
984 retvm_if(ret < 0, ret, "alarmmgr_set_cb() failed");
986 __cal_server_alarm_register_with_alarmmgr(time(NULL));
988 return CALENDAR_ERROR_NONE;