4 * Copyright (c) 2012 - 2015 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_typedef.h"
30 #include "cal_internal.h"
32 #include "cal_inotify.h"
33 #include "cal_db_util.h"
35 #include "cal_db_query.h"
36 #include "cal_server_reminder.h"
38 #define CAL_SEARCH_LOOP_MAX 4
43 long long int alert_utime; /* to compare */
46 int type; /* utime, localtime */
48 int record; /* todo, event */
53 /* this api is necessary for repeat instance. */
54 static int _cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
56 char query[CAL_DB_SQL_MAX_LEN] = {0};
59 ret = cal_db_util_begin_trans();
60 if (CALENDAR_ERROR_NONE != ret)
62 ERR("cal_db_util_begin_trans() Fail");
63 return CALENDAR_ERROR_DB_FAILED;
66 DBG("alarm_id(%d)", alarm_id);
68 snprintf(query, sizeof(query), "UPDATE %s SET alarm_id = 0 WHERE alarm_id =%d ",
69 CAL_TABLE_ALARM, alarm_id);
70 ret = cal_db_util_query_exec(query);
71 if (CALENDAR_ERROR_NONE != ret) {
72 ERR("cal_db_util_query_exec() Fail(%d)", ret);
73 SECURE("[%s]", query);
74 cal_db_util_end_trans(false);
77 cal_db_util_end_trans(true);
78 return CALENDAR_ERROR_NONE;
81 static int _cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
85 DBG("remove alarm id(%d)", alarm_id);
86 _cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
87 ret = alarmmgr_remove_alarm(alarm_id);
88 if (ret != ALARMMGR_RESULT_SUCCESS)
90 ERR("alarmmgr_remove_alarm() Fail(ret:%d)", ret);
93 return CALENDAR_ERROR_NONE;
96 static int _cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
98 char query[CAL_DB_SQL_MAX_LEN] = {0};
101 ret = cal_db_util_begin_trans();
102 if (CALENDAR_ERROR_NONE != ret)
104 ERR("cal_db_util_begin_trans() Fail");
105 return CALENDAR_ERROR_DB_FAILED;
108 DBG("Update alarm_id(%d) in alarm table", alarm_id);
109 snprintf(query, sizeof(query), "UPDATE %s SET alarm_id =%d "
110 "WHERE event_id =%d AND remind_tick =%d AND remind_tick_unit =%d",
111 CAL_TABLE_ALARM, alarm_id, event_id, tick, unit);
112 ret = cal_db_util_query_exec(query);
113 if (CALENDAR_ERROR_NONE != ret) {
114 ERR("cal_db_util_query_exec() Fail(%d)", ret);
115 SECURE("[%s]", query);
116 cal_db_util_end_trans(false);
119 cal_db_util_end_trans(true);
120 return CALENDAR_ERROR_NONE;
123 static long long int _cal_server_alarm_get_alert_utime(const char *field, int event_id, time_t current)
126 char query[CAL_DB_SQL_MAX_LEN] = {0};
127 snprintf(query, sizeof(query), "SELECT %s FROM %s "
128 "WHERE event_id=%d AND %s>%ld ORDER BY %s LIMIT 1",
129 field, CAL_TABLE_NORMAL_INSTANCE, event_id, field, current, field);
131 sqlite3_stmt *stmt = NULL;
132 ret = cal_db_util_query_prepare(query, &stmt);
133 if (CALENDAR_ERROR_NONE != ret) {
134 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
135 SECURE("query[%s]", query);
139 long long int utime = 0;
140 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
141 utime = sqlite3_column_int(stmt, 0);
143 sqlite3_finalize(stmt);
147 static int _cal_server_alarm_get_alert_localtime(const char *field, int event_id, time_t current)
150 char query[CAL_DB_SQL_MAX_LEN] = {0};
153 localtime_r(¤t, &st);
154 time_t mod_current = timegm(&st);
155 snprintf(query, sizeof(query), "SELECT %s FROM %s "
156 "WHERE event_id=%d AND strftime('%%s', %s)>%ld ORDER BY %s LIMIT 1",
157 field, CAL_TABLE_ALLDAY_INSTANCE, event_id, field, mod_current, field);
159 sqlite3_stmt *stmt = NULL;
160 ret = cal_db_util_query_prepare(query, &stmt);
161 if (CALENDAR_ERROR_NONE != ret) {
162 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
163 SECURE("query[%s]", query);
167 const char *datetime = NULL;
168 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
169 datetime = (const char *)sqlite3_column_text(stmt, 0);
171 if (NULL == datetime || '\0' == *datetime) {
172 ERR("Invalid datetime [%s]", datetime);
173 sqlite3_finalize(stmt);
177 int y = 0, m = 0, d = 0;
178 int h = 0, n = 0, s = 0;
179 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
180 sqlite3_finalize(stmt);
182 st.tm_year = y - 1900;
189 return (long long int)mktime(&st);
193 * to get aler time, time(NULL) is not accurate. 1 secs diff could be occured.
194 * so, searching DB is neccessary to find alert time.
196 static int _cal_server_alarm_get_alert_time(int alarm_id, time_t *tt_alert)
199 RETV_IF(NULL == tt_alert, CALENDAR_ERROR_INVALID_PARAMETER);
201 char query[CAL_DB_SQL_MAX_LEN] = {0};
202 snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
203 "A.alarm_type, A.alarm_utime, A.alarm_datetime, B.system_type, "
204 "B.type, B.dtstart_type, B.dtend_type "
205 "FROM %s as A, %s as B ON A.event_id = B.id WHERE alarm_id =%d ",
206 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE, alarm_id);
208 sqlite3_stmt *stmt = NULL;
209 ret = cal_db_util_query_prepare(query, &stmt);
210 if (CALENDAR_ERROR_NONE != ret) {
211 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
212 SECURE("query[%s]", query);
220 long long int utime = 0;
221 const char *datetime = NULL;
224 int dtstart_type = 0;
228 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
230 event_id = sqlite3_column_int(stmt, index++);
231 unit = sqlite3_column_int(stmt, index++);
232 tick = sqlite3_column_int(stmt, index++);
233 type = sqlite3_column_int(stmt, index++);
234 utime = sqlite3_column_int64(stmt, index++);
235 datetime = (const char *)sqlite3_column_text(stmt, index++);
236 system_type = sqlite3_column_int(stmt, index++);
237 record_type = sqlite3_column_int(stmt, index++);
238 dtstart_type = sqlite3_column_int(stmt, index++);
239 dtend_type = sqlite3_column_int(stmt, index++);
242 if (NULL == tt_alert) {
243 ERR("Invalid parameter: tt_alert is NULL");
244 sqlite3_finalize(stmt);
245 return CALENDAR_ERROR_INVALID_PARAMETER;
248 if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
249 if (CALENDAR_TIME_UTIME == type) {
253 int y = 0, m = 0, d = 0;
254 int h = 0, n = 0, s = 0;
255 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
257 st.tm_year = y - 1900;
263 *tt_alert = (long long int)mktime(&st);
264 DBG("datetime[%s] to %02d:%02d:%02d (%lld)", datetime, h, n, s, *tt_alert);
266 sqlite3_finalize(stmt);
267 return CALENDAR_ERROR_NONE;
269 sqlite3_finalize(stmt);
271 time_t current = time(NULL);
272 current += (tick * unit);
273 current -= 2; /* in case time passed */
275 switch (record_type) {
276 case CALENDAR_BOOK_TYPE_EVENT:
277 switch (dtstart_type) {
278 case CALENDAR_TIME_UTIME:
279 utime = _cal_server_alarm_get_alert_utime("dtstart_utime", event_id, current);
282 case CALENDAR_TIME_LOCALTIME:
283 utime = _cal_server_alarm_get_alert_localtime("dtstart_datetime", event_id, current);
288 case CALENDAR_BOOK_TYPE_TODO:
289 switch (dtend_type) {
290 case CALENDAR_TIME_UTIME:
291 utime = _cal_server_alarm_get_alert_utime("dtend_utime", event_id, current);
294 case CALENDAR_TIME_LOCALTIME:
295 utime = _cal_server_alarm_get_alert_localtime("dtend_datetime", event_id, current);
300 DBG("alert_time(%lld) = utime(%lld) - (tick(%d) * unit(%d))", *tt_alert, utime, datetime, tick, unit);
302 *tt_alert = utime - (tick * unit);
303 return CALENDAR_ERROR_NONE;
306 static void _cal_server_alarm_get_upcoming_specific_utime(time_t utime, bool get_all, GList **l)
309 char query[CAL_DB_SQL_MAX_LEN] = {0};
310 snprintf(query, sizeof(query),
311 // alarm utime(normal event + todo)
312 "SELECT event_id, remind_tick_unit, remind_tick, alarm_type, alarm_utime, alarm_datetime "
314 "WHERE remind_tick_unit =%d AND alarm_type =%d AND alarm_utime %s %ld %s",
316 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
317 true == get_all ? "=" : ">",
319 true == get_all ? "" : "ORDER BY alarm_utime ASC LIMIT 1");
321 sqlite3_stmt *stmt = NULL;
322 ret = cal_db_util_query_prepare(query, &stmt);
323 if (CALENDAR_ERROR_NONE != ret) {
324 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
325 SECURE("query[%s]", query);
329 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
330 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
332 ERR("calloc() Fail");
333 sqlite3_finalize(stmt);
338 ad->event_id = sqlite3_column_int(stmt, index++);
339 ad->unit = sqlite3_column_int(stmt, index++);
340 ad->tick = sqlite3_column_int(stmt, index++);
341 ad->type = sqlite3_column_int(stmt, index++);
342 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
343 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
344 *l = g_list_append(*l, ad);
345 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
346 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
347 ad->alert_utime = ad->time;
348 if (false == get_all) break;
350 sqlite3_finalize(stmt);
353 static void _cal_server_alarm_get_upcoming_specific_localtime(const char *datetime, bool get_all, GList **l)
356 char query[CAL_DB_SQL_MAX_LEN] = {0};
357 snprintf(query, sizeof(query),
358 "SELECT event_id, remind_tick_unit, remind_tick, "
359 "alarm_type, alarm_utime, alarm_datetime "
361 "WHERE remind_tick_unit=%d AND alarm_type=%d AND alarm_datetime %s '%s' %s",
363 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
364 true == get_all ? "=" : ">",
366 true == get_all ? "" : "ORDER BY alarm_datetime ASC LIMIT 1");
368 sqlite3_stmt *stmt = NULL;
369 ret = cal_db_util_query_prepare(query, &stmt);
370 if (CALENDAR_ERROR_NONE != ret) {
371 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
372 SECURE("query[%s]", query);
376 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
377 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
379 ERR("calloc() Fail");
380 sqlite3_finalize(stmt);
385 ad->event_id = sqlite3_column_int(stmt, index++);
386 ad->unit = sqlite3_column_int(stmt, index++);
387 ad->tick = sqlite3_column_int(stmt, index++);
388 ad->type = sqlite3_column_int(stmt, index++);
389 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
390 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
391 *l = g_list_append(*l, ad);
392 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
393 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
395 int y = 0, m = 0, d = 0;
396 int h = 0, n = 0, s = 0;
397 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
400 st.tm_year = y - 1900;
406 ad->alert_utime = (long long int)mktime(&st);
407 if (false == get_all) break;
409 sqlite3_finalize(stmt);
412 static void _cal_server_alarm_get_upcoming_nonspecific_event_utime(time_t utime, bool get_all, GList **l)
415 char query[CAL_DB_SQL_MAX_LEN] = {0};
420 snprintf(query, sizeof(query),
421 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, B.dtstart_utime, A.alarm_datetime "
422 "FROM %s as A, %s as B ON A.event_id = B.event_id "
423 "WHERE A.remind_tick_unit >%d AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
424 CAL_TABLE_ALARM, CAL_TABLE_NORMAL_INSTANCE,
425 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
426 true == get_all ? "=" : ">",
428 true == get_all ? "" : "ORDER BY (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1");
430 sqlite3_stmt *stmt = NULL;
431 ret = cal_db_util_query_prepare(query, &stmt);
432 if (CALENDAR_ERROR_NONE != ret) {
433 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
434 SECURE("query[%s]", query);
438 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
439 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
441 ERR("calloc() Fail");
442 sqlite3_finalize(stmt);
447 ad->event_id = sqlite3_column_int(stmt, index++);
448 ad->unit = sqlite3_column_int(stmt, index++);
449 ad->tick = sqlite3_column_int(stmt, index++);
450 ad->type = sqlite3_column_int(stmt, index++);
451 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
452 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
453 *l = g_list_append(*l, ad);
454 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
455 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
457 ad->alert_utime = ad->time - (ad->tick * ad->unit);
458 if (false == get_all) break;
460 sqlite3_finalize(stmt);
463 static void _cal_server_alarm_get_upcoming_nonspecific_event_localtime(const char *datetime, bool get_all, GList **l)
466 char query[CAL_DB_SQL_MAX_LEN] = {0};
471 snprintf(query, sizeof(query),
472 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, A.alarm_utime, B.dtstart_datetime "
473 "FROM %s as A, %s as B ON A.event_id = B.event_id "
474 "WHERE A.remind_tick_unit >%d AND "
475 "(strftime('%%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
476 CAL_TABLE_ALARM, CAL_TABLE_ALLDAY_INSTANCE,
477 CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
479 true == get_all ? "=" : ">",
480 true == get_all ? "" : "ORDER BY (strftime('%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
481 sqlite3_stmt *stmt = NULL;
482 ret = cal_db_util_query_prepare(query, &stmt);
483 if (CALENDAR_ERROR_NONE != ret) {
484 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
485 SECURE("query[%s]", query);
489 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
490 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
492 ERR("calloc() Fail");
493 sqlite3_finalize(stmt);
498 ad->event_id = sqlite3_column_int(stmt, index++);
499 ad->unit = sqlite3_column_int(stmt, index++);
500 ad->tick = sqlite3_column_int(stmt, index++);
501 ad->type = sqlite3_column_int(stmt, index++);
502 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
503 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
504 *l = g_list_append(*l, ad);
505 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
506 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
508 int y = 0, m = 0, d = 0;
509 int h = 0, n = 0, s = 0;
510 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
513 st.tm_year = y - 1900;
519 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
520 if (false == get_all) break;
522 sqlite3_finalize(stmt);
525 static void _cal_server_alarm_get_upcoming_nonspecific_todo_utime(time_t utime, bool get_all, GList **l)
528 char query[CAL_DB_SQL_MAX_LEN] = {0};
533 snprintf(query, sizeof(query),
534 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, B.dtend_utime, A.alarm_datetime "
535 "FROM %s as A, %s as B ON A.event_id = B.id "
536 "WHERE A.remind_tick_unit >%d AND B.type =%d "
537 "AND (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
538 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
539 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
540 true == get_all ? "=" : ">",
542 true == get_all ? "" : "ORDER BY (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
544 sqlite3_stmt *stmt = NULL;
545 ret = cal_db_util_query_prepare(query, &stmt);
546 if (CALENDAR_ERROR_NONE != ret) {
547 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
548 SECURE("query[%s]", query);
552 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
553 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
555 ERR("calloc() Fail");
556 sqlite3_finalize(stmt);
561 ad->event_id = sqlite3_column_int(stmt, index++);
562 ad->unit = sqlite3_column_int(stmt, index++);
563 ad->tick = sqlite3_column_int(stmt, index++);
564 ad->type = sqlite3_column_int(stmt, index++);
565 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
566 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
567 *l = g_list_append(*l, ad);
568 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
569 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
571 ad->alert_utime = ad->time - (ad->tick * ad->unit);
572 if (false == get_all) break;
574 sqlite3_finalize(stmt);
577 static void _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(const char *datetime, bool get_all, GList **l)
580 char query[CAL_DB_SQL_MAX_LEN] = {0};
585 snprintf(query, sizeof(query),
586 "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, A.alarm_type, A.alarm_utime, B.dtend_datetime "
587 "FROM %s as A, %s as B ON A.event_id = B.id "
588 "WHERE A.remind_tick_unit >%d AND B.type =%d "
589 "AND (strftime('%%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
590 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
591 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
593 true == get_all ? "=" : ">",
594 true == get_all ? "" : "ORDER BY (strftime('%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
596 sqlite3_stmt *stmt = NULL;
597 ret = cal_db_util_query_prepare(query, &stmt);
598 if (CALENDAR_ERROR_NONE != ret) {
599 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
600 SECURE("query[%s]", query);
604 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
605 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
607 ERR("calloc() Fail");
608 sqlite3_finalize(stmt);
613 ad->event_id = sqlite3_column_int(stmt, index++);
614 ad->unit = sqlite3_column_int(stmt, index++);
615 ad->tick = sqlite3_column_int(stmt, index++);
616 ad->type = sqlite3_column_int(stmt, index++);
617 ad->time = (long long int)sqlite3_column_int64(stmt, index++);
618 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, index++));
619 *l = g_list_append(*l, ad);
620 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
621 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
623 int y = 0, m = 0, d = 0;
624 int h = 0, n = 0, s = 0;
625 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
628 st.tm_year = y - 1900;
634 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
635 if (false == get_all) break;
637 sqlite3_finalize(stmt);
640 static int _cal_server_alarm_get_alert_list(time_t utime, GList **list)
643 RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
646 struct tm st_local = {0};
647 localtime_r(&utime, &st_local);
648 char datetime[32] = {0};
649 snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
650 st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
651 st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
652 DBG("get alert to register with given time (%ld) datetime[%s]", utime, datetime);
656 _cal_server_alarm_get_upcoming_specific_utime(utime, true, &l);
657 _cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, true, &l);
658 _cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, true, &l);
660 _cal_server_alarm_get_upcoming_specific_localtime(datetime, true, &l);
661 _cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, true, &l);
662 _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, true, &l);
666 return CALENDAR_ERROR_NONE;
669 static gint _cal_server_alarm_sort_cb(gconstpointer a, gconstpointer b)
671 struct _alarm_data_s *p1 = (struct _alarm_data_s *)a;
672 struct _alarm_data_s *p2 = (struct _alarm_data_s *)b;
673 DBG("%lld) > (%lld)",p1->alert_utime, p2->alert_utime);
675 return p1->alert_utime < p2->alert_utime ? -1 : 1;
678 static GFunc _cal_server_alarm_print_cb(gpointer data, gpointer user_data)
680 struct _alarm_data_s *ad = (struct _alarm_data_s *)data;
681 DBG("id(%d) unit(%d) tick(%d) type(%d) time(%lld) datetime[%s]",
682 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
686 static int _cal_server_alarm_register(GList *alarm_list)
689 RETV_IF(NULL == alarm_list, CALENDAR_ERROR_INVALID_PARAMETER);
691 int ret = CALENDAR_ERROR_NONE;
692 GList *l = g_list_first(alarm_list);
693 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
694 RETVM_IF(NULL == ad, CALENDAR_ERROR_DB_FAILED, "No data");
696 /* clear all alarm which set by mine. */
697 ret = alarmmgr_enum_alarm_ids(_cal_server_alarm_clear_all_cb, NULL);
698 if (ret != ALARMMGR_RESULT_SUCCESS) {
699 ERR("alarmmgr_enum_alarm_ids() Fail");
703 time_t mod_time = (time_t)ad->alert_utime;
704 alarm_entry_t *alarm_info = NULL;
705 alarm_info = alarmmgr_create_alarm();
706 if (NULL == alarm_info)
708 ERR("Failed to create alarm");
709 return CALENDAR_ERROR_DB_FAILED;
712 struct tm st_alarm = {0};
714 switch (ad->system_type) {
715 case CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR:
716 gmtime_r(&mod_time, &st_alarm);
721 localtime_r(&mod_time, &st_alarm);
725 alarm_date_t date = {0};
726 date.year = st_alarm.tm_year + 1900;
727 date.month = st_alarm.tm_mon + 1;
728 date.day = st_alarm.tm_mday;
729 date.hour = st_alarm.tm_hour;
730 date.min = st_alarm.tm_min;
731 date.sec = st_alarm.tm_sec;
732 alarmmgr_set_time(alarm_info, date);
733 DBG(COLOR_CYAN" >>> registered record id (%d) at %04d/%02d/%02d %02d:%02d:%02d "COLOR_END" (utime(%lld), datetime[%s], tick(%d) unit(%d))",
734 ad->event_id, date.year, date.month, date.day, date.hour, date.min, date.sec,
735 ad->time, ad->datetime, ad->tick, ad->unit);
738 ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
740 ERR("alarmmgr_add_alarm_with_localtime Fail (%d)", ret);
741 alarmmgr_free_alarm(alarm_info);
744 DBG("alarmmgr id (%d)", alarm_id);
745 _cal_server_alarm_update_alarm_id(alarm_id, ad->event_id, ad->tick, ad->unit);
746 alarmmgr_free_alarm(alarm_info);
747 return CALENDAR_ERROR_NONE;
750 static bool __app_matched_cb(app_control_h app_control, const char *package, void *user_data)
753 struct alarm_ud *au = (struct alarm_ud *)user_data;
755 RETV_IF(NULL == user_data, true);
758 ret = app_control_get_mime(app_control, &mime);
759 RETVM_IF(APP_CONTROL_ERROR_NONE != ret, true, "app_control_get_mime() Fail(%d)", ret);
761 const char *reminder_mime = "application/x-tizen.calendar.reminder";
762 if (strncmp(mime, reminder_mime, strlen(reminder_mime))) { /* not same */
763 DBG("get mime[%s] is not [%s]", mime, reminder_mime);
769 GList *alarm_list = (GList *)user_data;
771 len = g_list_length(alarm_list);
773 DBG("len is 0, no alarm list");
777 app_control_h b = NULL;
778 app_control_create(&b);
779 app_control_set_operation(b, APP_CONTROL_OPERATION_DEFAULT);
780 app_control_set_app_id(b, package);
783 ids = calloc(len, sizeof(char *));
785 ERR("calloc() Fail");
786 app_control_destroy(b);
787 return CALENDAR_ERROR_DB_FAILED;
789 GList *l = g_list_first(alarm_list);
791 for (i = 0; i < len; i++) {
792 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
798 DBG("pkg[%s] time[%lld] tick[%d] unit[%d] record_type[%d]",
799 package, ad->time, ad->tick, ad->unit, ad->record);
801 char buf_event_id[128] = {0};
802 char buf_time[128] = {0};
803 char buf_tick[128] = {0};
804 char buf_unit[128] = {0};
805 char buf_record_type[128] = {0};
806 snprintf(buf_event_id, sizeof(buf_event_id), "%d", ad->event_id);
807 snprintf(buf_time, sizeof(buf_time), "%lld", ad->time);
808 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
809 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
810 snprintf(buf_record_type, sizeof(buf_record_type), "%d", ad->record);
813 cal_server_reminder_add_callback_data(&p, "id", buf_event_id);
814 cal_server_reminder_add_callback_data(&p, "time", buf_time);
815 cal_server_reminder_add_callback_data(&p, "tick", buf_tick);
816 cal_server_reminder_add_callback_data(&p, "unit", buf_unit);
817 cal_server_reminder_add_callback_data(&p, "type", buf_record_type);
819 app_control_add_extra_data(b, buf_event_id, p); // key: id, value: id=4&time=123123&..
824 ids[i] = strdup(buf_event_id);
828 app_control_add_extra_data_array(b, "ids", (const char **)ids, len);
829 app_control_send_launch_request (b, NULL, NULL);
830 app_control_destroy(b);
832 for (i = 0; i < len; i++) {
841 static void _cal_server_alarm_noti_with_control(GList *alarm_list)
843 RETM_IF(NULL == alarm_list, "No alarm list");
845 app_control_h app_control = NULL;
846 app_control_create(&app_control);
847 app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW);
848 app_control_set_mime(app_control, "application/x-tizen.calendar.reminder");
849 app_control_foreach_app_matched(app_control, __app_matched_cb, alarm_list);
850 app_control_destroy(app_control);
853 static void _cal_server_alarm_noti_with_callback(GList *alarm_list)
855 RETM_IF(NULL == alarm_list, "No alarm list");
857 GList *l = g_list_first(alarm_list);
859 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
865 DBG("callback time[%lld] tick[%d] unit[%d] record_type[%d]",
866 ad->time, ad->tick, ad->unit, ad->record);
868 char buf_event_id[128] = {0};
869 char buf_time[128] = {0};
870 char buf_tick[128] = {0};
871 char buf_unit[128] = {0};
872 char buf_record_type[128] = {0};
873 snprintf(buf_event_id, sizeof(buf_event_id), "%d", ad->event_id);
874 snprintf(buf_time, sizeof(buf_time), "%lld", ad->time);
875 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
876 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
877 snprintf(buf_record_type, sizeof(buf_record_type), "%d", ad->record);
880 cal_server_reminder_add_callback_data(&p, "id", buf_event_id);
881 cal_server_reminder_add_callback_data(&p, "time", buf_time);
882 cal_server_reminder_add_callback_data(&p, "tick", buf_tick);
883 cal_server_reminder_add_callback_data(&p, "unit", buf_unit);
884 cal_server_reminder_add_callback_data(&p, "type", buf_record_type);
885 cal_server_reminder_publish(p);
892 static int _cal_server_alarm_register_with_alarmmgr(time_t utime)
895 struct tm st_local = {0};
896 localtime_r(&utime, &st_local);
897 char datetime[32] = {0};
898 snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
899 st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
900 st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
901 DBG("search alarm to register with given time (%ld) datetime[%s]", utime, datetime);
905 _cal_server_alarm_get_upcoming_specific_utime(utime, false, &l);
906 _cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, false, &l);
907 _cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, false, &l);
909 _cal_server_alarm_get_upcoming_specific_localtime(datetime, false, &l);
910 _cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, false, &l);
911 _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, false, &l);
914 DBG("No alarm list");
915 return CALENDAR_ERROR_NONE;
918 l = g_list_sort(l, _cal_server_alarm_sort_cb);
919 g_list_foreach(l, (GFunc)_cal_server_alarm_print_cb, NULL);
920 _cal_server_alarm_register(l);
924 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
929 return CALENDAR_ERROR_NONE;
932 static int _alert_cb(alarm_id_t alarm_id, void *data)
937 DBG("alarm_id (%ld)", alarm_id);
939 _cal_server_alarm_get_alert_time(alarm_id, &tt_alert);
940 _cal_server_alarm_get_alert_list(tt_alert, &l);
941 _cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
942 _cal_server_alarm_noti_with_callback(l);
943 _cal_server_alarm_noti_with_control(l);
944 _cal_server_alarm_register_with_alarmmgr(tt_alert);
948 ////////////////////////////////////////////////////////////////////
949 static void _cal_server_alarm_timechange_cb(keynode_t *node, void *data)
955 t = vconf_keynode_get_int(node);
959 ret = vconf_get_int(VCONFKEY_SYSTEM_TIMECHANGE, &t);
960 WARN_IF(0 < ret, "vconf_get_int() Fail");
965 _cal_server_alarm_register_with_alarmmgr(time(NULL));
969 DBG("system changed time(%ld)", t);
970 _cal_server_alarm_register_with_alarmmgr((time_t)t);
974 void _cal_server_alarm_set_timechange(void)
976 vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
977 _cal_server_alarm_timechange_cb, NULL);
979 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT,
980 _cal_server_alarm_timechange_cb, NULL);
981 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT,
982 _cal_server_alarm_timechange_cb, NULL);
983 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE,
984 _cal_server_alarm_timechange_cb, NULL);
987 static void __changed_cb(const char* view_uri, void* data)
990 _cal_server_alarm_register_with_alarmmgr(time(NULL));
993 static int _cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
995 cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
996 cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
1000 int cal_server_alarm(void)
1005 _cal_server_alarm_set_timechange();
1006 _cal_server_alarm_set_inotify(__changed_cb);
1008 ret = alarmmgr_init("calendar-service");
1009 RETVM_IF(ret < 0, ret, "alarmmgr_init() Fail");
1011 ret = alarmmgr_set_cb(_alert_cb, NULL);
1012 RETVM_IF(ret < 0, ret, "alarmmgr_set_cb() Fail");
1014 _cal_server_alarm_register_with_alarmmgr(time(NULL));
1016 return CALENDAR_ERROR_NONE;