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 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.type,B.dtstart_type,B.dtend_type "
204 "FROM %s as A, %s as B ON A.event_id = B.id WHERE alarm_id =%d ",
205 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE, alarm_id);
207 sqlite3_stmt *stmt = NULL;
208 ret = cal_db_util_query_prepare(query, &stmt);
209 if (CALENDAR_ERROR_NONE != ret) {
210 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
211 SECURE("query[%s]", query);
219 long long int utime = 0;
220 const char *datetime = NULL;
222 int dtstart_type = 0;
226 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
227 event_id = sqlite3_column_int(stmt, 0);
228 unit = sqlite3_column_int(stmt, 1);
229 tick = sqlite3_column_int(stmt, 2);
230 type = sqlite3_column_int(stmt, 3);
231 utime = sqlite3_column_int64(stmt, 4);
232 datetime = (const char *)sqlite3_column_text(stmt, 5);
233 record_type = sqlite3_column_int(stmt, 6);
234 dtstart_type = sqlite3_column_int(stmt, 7);
235 dtend_type = sqlite3_column_int(stmt, 8);
238 if (NULL == tt_alert) {
239 ERR("Invalid parameter: tt_alert is NULL");
240 sqlite3_finalize(stmt);
241 return CALENDAR_ERROR_INVALID_PARAMETER;
244 if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
245 if (CALENDAR_TIME_UTIME == type) {
249 int y = 0, m = 0, d = 0;
250 int h = 0, n = 0, s = 0;
251 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
253 st.tm_year = y - 1900;
259 *tt_alert = (long long int)mktime(&st);
260 DBG("datetime[%s] to %02d:%02d:%02d (%lld)", datetime, h, n, s, *tt_alert);
262 sqlite3_finalize(stmt);
263 return CALENDAR_ERROR_NONE;
265 sqlite3_finalize(stmt);
267 time_t current = time(NULL);
268 current += (tick * unit);
269 current -= 2; /* in case time passed */
271 switch (record_type) {
272 case CALENDAR_BOOK_TYPE_EVENT:
273 switch (dtstart_type) {
274 case CALENDAR_TIME_UTIME:
275 utime = _cal_server_alarm_get_alert_utime("dtstart_utime", event_id, current);
278 case CALENDAR_TIME_LOCALTIME:
279 utime = _cal_server_alarm_get_alert_localtime("dtstart_datetime", event_id, current);
284 case CALENDAR_BOOK_TYPE_TODO:
285 switch (dtend_type) {
286 case CALENDAR_TIME_UTIME:
287 utime = _cal_server_alarm_get_alert_utime("dtend_utime", event_id, current);
290 case CALENDAR_TIME_LOCALTIME:
291 utime = _cal_server_alarm_get_alert_localtime("dtend_datetime", event_id, current);
296 DBG("alert_time(%lld) = utime(%lld) - (tick(%d) * unit(%d))", *tt_alert, utime, datetime, tick, unit);
298 *tt_alert = utime - (tick * unit);
299 return CALENDAR_ERROR_NONE;
304 * true : to get all alarms including same time event.
305 * (ig. if 3 diffrent alarms exist at 06:30, list has 3 data)
306 * false : to get only one alarm to register in alarm-manager.
307 * (ig. if 3 diffrent alarms exist at 06:30, list has only one)
309 static void _cal_server_alarm_get_upcoming_specific_utime(time_t utime, bool get_all, GList **l)
312 char query[CAL_DB_SQL_MAX_LEN] = {0};
313 snprintf(query, sizeof(query), "SELECT event_id,remind_tick_unit,remind_tick,"
314 "alarm_type,alarm_utime,alarm_datetime "
315 "FROM %s WHERE remind_tick_unit =%d AND alarm_type =%d AND alarm_utime %s %ld %s",
316 CAL_TABLE_ALARM, CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
317 true == get_all ? "=" : ">", utime,
318 true == get_all ? "" : "ORDER BY alarm_utime ASC LIMIT 1");
320 sqlite3_stmt *stmt = NULL;
321 ret = cal_db_util_query_prepare(query, &stmt);
322 if (CALENDAR_ERROR_NONE != ret) {
323 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
324 SECURE("query[%s]", query);
328 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
329 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
331 ERR("calloc() Fail");
332 sqlite3_finalize(stmt);
336 ad->event_id = sqlite3_column_int(stmt,0);
337 ad->unit = sqlite3_column_int(stmt, 1);
338 ad->tick = sqlite3_column_int(stmt, 2);
339 ad->type = sqlite3_column_int(stmt, 3);
340 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
341 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
342 *l = g_list_append(*l, ad);
343 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
344 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
345 ad->alert_utime = ad->time;
346 if (false == get_all) break;
348 sqlite3_finalize(stmt);
351 static void _cal_server_alarm_get_upcoming_specific_localtime(const char *datetime, bool get_all, GList **l)
354 char query[CAL_DB_SQL_MAX_LEN] = {0};
355 snprintf(query, sizeof(query), "SELECT event_id,remind_tick_unit,remind_tick,"
356 "alarm_type,alarm_utime,alarm_datetime "
357 "FROM %s WHERE remind_tick_unit=%d AND alarm_type=%d AND alarm_datetime %s '%s' %s",
358 CAL_TABLE_ALARM, CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
359 true == get_all ? "=" : ">", datetime,
360 true == get_all ? "" : "ORDER BY alarm_datetime ASC LIMIT 1");
362 sqlite3_stmt *stmt = NULL;
363 ret = cal_db_util_query_prepare(query, &stmt);
364 if (CALENDAR_ERROR_NONE != ret) {
365 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
366 SECURE("query[%s]", query);
370 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
371 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
373 ERR("calloc() Fail");
374 sqlite3_finalize(stmt);
378 ad->event_id = sqlite3_column_int(stmt, 0);
379 ad->unit = sqlite3_column_int(stmt, 1);
380 ad->tick = sqlite3_column_int(stmt, 2);
381 ad->type = sqlite3_column_int(stmt, 3);
382 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
383 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
384 *l = g_list_append(*l, ad);
385 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
386 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
388 int y = 0, m = 0, d = 0;
389 int h = 0, n = 0, s = 0;
390 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
393 st.tm_year = y - 1900;
399 ad->alert_utime = (long long int)mktime(&st);
400 if (false == get_all) break;
402 sqlite3_finalize(stmt);
405 static void _cal_server_alarm_get_upcoming_nonspecific_event_utime(time_t utime, bool get_all, GList **l)
412 char query[CAL_DB_SQL_MAX_LEN] = {0};
413 snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
414 "A.alarm_type,B.dtstart_utime,A.alarm_datetime "
415 "FROM %s as A, %s as B ON A.event_id = B.event_id "
416 "WHERE A.remind_tick_unit >%d AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
417 CAL_TABLE_ALARM, CAL_TABLE_NORMAL_INSTANCE, CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
418 true == get_all ? "=" : ">", utime,
419 true == get_all ? "" : "ORDER BY (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1");
421 sqlite3_stmt *stmt = NULL;
422 ret = cal_db_util_query_prepare(query, &stmt);
423 if (CALENDAR_ERROR_NONE != ret) {
424 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
425 SECURE("query[%s]", query);
429 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
430 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
432 ERR("calloc() Fail");
433 sqlite3_finalize(stmt);
437 ad->event_id = sqlite3_column_int(stmt, 0);
438 ad->unit = sqlite3_column_int(stmt, 1);
439 ad->tick = sqlite3_column_int(stmt, 2);
440 ad->type = sqlite3_column_int(stmt, 3);
441 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
442 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
443 *l = g_list_append(*l, ad);
444 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
445 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
447 ad->alert_utime = ad->time - (ad->tick * ad->unit);
448 if (false == get_all) break;
450 sqlite3_finalize(stmt);
453 static void _cal_server_alarm_get_upcoming_nonspecific_event_localtime(const char *datetime, bool get_all, GList **l)
460 char query[CAL_DB_SQL_MAX_LEN] = {0};
461 snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
462 "A.alarm_type,A.alarm_utime,B.dtstart_datetime "
463 "FROM %s as A, %s as B ON A.event_id = B.event_id "
464 "WHERE A.remind_tick_unit >%d AND "
465 "(strftime('%%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
466 CAL_TABLE_ALARM, CAL_TABLE_ALLDAY_INSTANCE, CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
467 datetime, true == get_all ? "=" : ">",
468 true == get_all ? "" : "ORDER BY (strftime('%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
469 sqlite3_stmt *stmt = NULL;
470 ret = cal_db_util_query_prepare(query, &stmt);
471 if (CALENDAR_ERROR_NONE != ret) {
472 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
473 SECURE("query[%s]", query);
477 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
478 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
480 ERR("calloc() Fail");
481 sqlite3_finalize(stmt);
485 ad->event_id = sqlite3_column_int(stmt, 0);
486 ad->unit = sqlite3_column_int(stmt, 1);
487 ad->tick = sqlite3_column_int(stmt, 2);
488 ad->type = sqlite3_column_int(stmt, 3);
489 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
490 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
491 *l = g_list_append(*l, ad);
492 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
493 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
495 int y = 0, m = 0, d = 0;
496 int h = 0, n = 0, s = 0;
497 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
500 st.tm_year = y - 1900;
506 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
507 if (false == get_all) break;
509 sqlite3_finalize(stmt);
512 static void _cal_server_alarm_get_upcoming_nonspecific_todo_utime(time_t utime, bool get_all, GList **l)
519 char query[CAL_DB_SQL_MAX_LEN] = {0};
520 snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
521 "A.alarm_type,B.dtend_utime,A.alarm_datetime "
522 "FROM %s as A, %s as B ON A.event_id = B.id "
523 "WHERE A.remind_tick_unit >%d AND B.type =%d "
524 "AND (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
525 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
526 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
527 true == get_all ? "=" : ">", utime,
528 true == get_all ? "" : "ORDER BY (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
530 sqlite3_stmt *stmt = NULL;
531 ret = cal_db_util_query_prepare(query, &stmt);
532 if (CALENDAR_ERROR_NONE != ret) {
533 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
534 SECURE("query[%s]", query);
538 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
539 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
541 ERR("calloc() Fail");
542 sqlite3_finalize(stmt);
546 ad->event_id = sqlite3_column_int(stmt, 0);
547 ad->unit = sqlite3_column_int(stmt, 1);
548 ad->tick = sqlite3_column_int(stmt, 2);
549 ad->type = sqlite3_column_int(stmt, 3);
550 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
551 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
552 *l = g_list_append(*l, ad);
553 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
554 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
556 ad->alert_utime = ad->time - (ad->tick * ad->unit);
557 if (false == get_all) break;
559 sqlite3_finalize(stmt);
562 static void _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(const char *datetime, bool get_all, GList **l)
569 char query[CAL_DB_SQL_MAX_LEN] = {0};
570 snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
571 "A.alarm_type,A.alarm_utime,B.dtend_datetime "
572 "FROM %s as A, %s as B ON A.event_id = B.id "
573 "WHERE A.remind_tick_unit >%d AND B.type =%d "
574 "AND (strftime('%%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
575 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
576 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
577 datetime, true == get_all ? "=" : ">",
578 true == get_all ? "" : "ORDER BY (strftime('%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
580 sqlite3_stmt *stmt = NULL;
581 ret = cal_db_util_query_prepare(query, &stmt);
582 if (CALENDAR_ERROR_NONE != ret) {
583 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
584 SECURE("query[%s]", query);
588 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
589 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
591 ERR("calloc() Fail");
592 sqlite3_finalize(stmt);
596 ad->event_id = sqlite3_column_int(stmt, 0);
597 ad->unit = sqlite3_column_int(stmt, 1);
598 ad->tick = sqlite3_column_int(stmt, 2);
599 ad->type = sqlite3_column_int(stmt, 3);
600 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
601 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
602 *l = g_list_append(*l, ad);
603 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
604 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
606 int y = 0, m = 0, d = 0;
607 int h = 0, n = 0, s = 0;
608 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
611 st.tm_year = y - 1900;
617 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
618 if (false == get_all) break;
620 sqlite3_finalize(stmt);
623 static void _cal_server_alarm_get_latest(time_t utime, bool get_all, GList **out_l)
626 RET_IF(NULL == out_l);
629 struct tm st_local = {0};
630 localtime_r(&utime, &st_local);
632 char datetime[32] = {0};
633 snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
634 st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
635 st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
636 DBG("get alert to register with given time (%ld) datetime[%s]", utime, datetime);
640 _cal_server_alarm_get_upcoming_specific_utime(utime, get_all, &l);
641 _cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, get_all, &l);
642 _cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, get_all, &l);
644 _cal_server_alarm_get_upcoming_specific_localtime(datetime, get_all, &l);
645 _cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, get_all, &l);
646 _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, get_all, &l);
651 static gint _cal_server_alarm_sort_cb(gconstpointer a, gconstpointer b)
653 struct _alarm_data_s *p1 = (struct _alarm_data_s *)a;
654 struct _alarm_data_s *p2 = (struct _alarm_data_s *)b;
655 DBG("%lld) > (%lld)",p1->alert_utime, p2->alert_utime);
657 return p1->alert_utime < p2->alert_utime ? -1 : 1;
660 static GFunc _cal_server_alarm_print_cb(gpointer data, gpointer user_data)
662 struct _alarm_data_s *ad = (struct _alarm_data_s *)data;
663 DBG("id(%d) unit(%d) tick(%d) type(%d) time(%lld) datetime[%s]",
664 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
668 static int _cal_server_alarm_register(GList *alarm_list)
671 RETV_IF(NULL == alarm_list, CALENDAR_ERROR_INVALID_PARAMETER);
673 int ret = CALENDAR_ERROR_NONE;
674 GList *l = g_list_first(alarm_list);
675 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
676 RETVM_IF(NULL == ad, CALENDAR_ERROR_DB_FAILED, "No data");
678 /* clear all alarm which set by mine. */
679 ret = alarmmgr_enum_alarm_ids(_cal_server_alarm_clear_all_cb, NULL);
680 if (ret != ALARMMGR_RESULT_SUCCESS) {
681 ERR("alarmmgr_enum_alarm_ids() Fail");
685 time_t mod_time = (time_t)ad->alert_utime;
686 alarm_entry_t *alarm_info = NULL;
687 alarm_info = alarmmgr_create_alarm();
688 if (NULL == alarm_info)
690 ERR("Failed to create alarm");
691 return CALENDAR_ERROR_DB_FAILED;
694 struct tm st_alarm = {0};
696 switch (ad->system_type) {
697 case CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR:
698 gmtime_r(&mod_time, &st_alarm);
703 localtime_r(&mod_time, &st_alarm);
707 alarm_date_t date = {0};
708 date.year = st_alarm.tm_year + 1900;
709 date.month = st_alarm.tm_mon + 1;
710 date.day = st_alarm.tm_mday;
711 date.hour = st_alarm.tm_hour;
712 date.min = st_alarm.tm_min;
713 date.sec = st_alarm.tm_sec;
714 alarmmgr_set_time(alarm_info, date);
715 DBG(COLOR_CYAN" >>> registered record id (%d) at %04d/%02d/%02d %02d:%02d:%02d "COLOR_END" (utime(%lld), datetime[%s], tick(%d) unit(%d))",
716 ad->event_id, date.year, date.month, date.day, date.hour, date.min, date.sec,
717 ad->time, ad->datetime, ad->tick, ad->unit);
720 ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
722 ERR("alarmmgr_add_alarm_with_localtime Fail (%d)", ret);
723 alarmmgr_free_alarm(alarm_info);
726 DBG("alarmmgr id (%d)", alarm_id);
727 _cal_server_alarm_update_alarm_id(alarm_id, ad->event_id, ad->tick, ad->unit);
728 alarmmgr_free_alarm(alarm_info);
729 return CALENDAR_ERROR_NONE;
732 static bool __app_matched_cb(app_control_h app_control, const char *package, void *user_data)
735 struct alarm_ud *au = (struct alarm_ud *)user_data;
737 RETV_IF(NULL == user_data, true);
740 ret = app_control_get_mime(app_control, &mime);
741 RETVM_IF(APP_CONTROL_ERROR_NONE != ret, true, "app_control_get_mime() Fail(%d)", ret);
743 const char *reminder_mime = "application/x-tizen.calendar.reminder";
744 if (strncmp(mime, reminder_mime, strlen(reminder_mime))) { /* not same */
745 DBG("get mime[%s] is not [%s]", mime, reminder_mime);
751 GList *alarm_list = (GList *)user_data;
753 len = g_list_length(alarm_list);
755 DBG("len is 0, no alarm list");
759 app_control_h b = NULL;
760 app_control_create(&b);
761 app_control_set_operation(b, APP_CONTROL_OPERATION_DEFAULT);
762 app_control_set_app_id(b, package);
765 ids = calloc(len, sizeof(char *));
767 ERR("calloc() Fail");
768 app_control_destroy(b);
769 return CALENDAR_ERROR_DB_FAILED;
771 GList *l = g_list_first(alarm_list);
773 for (i = 0; i < len; i++) {
774 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
780 DBG("pkg[%s] time[%lld] tick[%d] unit[%d] record_type[%d]",
781 package, ad->time, ad->tick, ad->unit, ad->record);
783 char buf_event_id[128] = {0};
784 char buf_time[128] = {0};
785 char buf_tick[128] = {0};
786 char buf_unit[128] = {0};
787 char buf_record_type[128] = {0};
788 snprintf(buf_event_id, sizeof(buf_event_id), "%d", ad->event_id);
789 snprintf(buf_time, sizeof(buf_time), "%lld", ad->time);
790 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
791 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
792 snprintf(buf_record_type, sizeof(buf_record_type), "%d", ad->record);
795 cal_server_reminder_add_callback_data(&p, "id", buf_event_id);
796 cal_server_reminder_add_callback_data(&p, "time", buf_time);
797 cal_server_reminder_add_callback_data(&p, "tick", buf_tick);
798 cal_server_reminder_add_callback_data(&p, "unit", buf_unit);
799 cal_server_reminder_add_callback_data(&p, "type", buf_record_type);
801 app_control_add_extra_data(b, buf_event_id, p); // key: id, value: id=4&time=123123&..
806 ids[i] = strdup(buf_event_id);
810 app_control_add_extra_data_array(b, "ids", (const char **)ids, len);
811 app_control_send_launch_request (b, NULL, NULL);
812 app_control_destroy(b);
814 for (i = 0; i < len; i++) {
823 static void _cal_server_alarm_noti_with_control(GList *alarm_list)
825 RETM_IF(NULL == alarm_list, "No alarm list");
827 app_control_h app_control = NULL;
828 app_control_create(&app_control);
829 app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW);
830 app_control_set_mime(app_control, "application/x-tizen.calendar.reminder");
831 app_control_foreach_app_matched(app_control, __app_matched_cb, alarm_list);
832 app_control_destroy(app_control);
835 static void _cal_server_alarm_noti_with_callback(GList *alarm_list)
837 RETM_IF(NULL == alarm_list, "No alarm list");
839 GList *l = g_list_first(alarm_list);
841 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
847 DBG("callback time[%lld] tick[%d] unit[%d] record_type[%d]",
848 ad->time, ad->tick, ad->unit, ad->record);
850 char buf_event_id[128] = {0};
851 char buf_time[128] = {0};
852 char buf_tick[128] = {0};
853 char buf_unit[128] = {0};
854 char buf_record_type[128] = {0};
855 snprintf(buf_event_id, sizeof(buf_event_id), "%d", ad->event_id);
856 snprintf(buf_time, sizeof(buf_time), "%lld", ad->time);
857 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
858 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
859 snprintf(buf_record_type, sizeof(buf_record_type), "%d", ad->record);
862 cal_server_reminder_add_callback_data(&p, "id", buf_event_id);
863 cal_server_reminder_add_callback_data(&p, "time", buf_time);
864 cal_server_reminder_add_callback_data(&p, "tick", buf_tick);
865 cal_server_reminder_add_callback_data(&p, "unit", buf_unit);
866 cal_server_reminder_add_callback_data(&p, "type", buf_record_type);
867 cal_server_reminder_publish(p);
874 int cal_server_alarm_register_next_alarm(time_t utime)
877 _cal_server_alarm_get_latest(utime, false, &l);
879 return CALENDAR_ERROR_NONE;
882 l = g_list_sort(l, _cal_server_alarm_sort_cb);
883 g_list_foreach(l, (GFunc)_cal_server_alarm_print_cb, NULL);
884 _cal_server_alarm_register(l);
886 g_list_free_full(l, free);
887 return CALENDAR_ERROR_NONE;
890 void cal_server_alarm_alert(time_t tt_alert)
893 _cal_server_alarm_get_latest(tt_alert, true, &l);
894 _cal_server_alarm_noti_with_callback(l);
895 _cal_server_alarm_noti_with_control(l);
898 static int _alert_cb(alarm_id_t alarm_id, void *data)
901 DBG("alarm_id (%ld)", alarm_id);
904 char *zone_name = data;
905 cal_server_alarm_get_alert_time(alarm_id, &tt_alert);
906 cal_server_alarm_alert(tt_alert);
907 _cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
908 cal_server_alarm_register_next_alarm(tt_alert);
912 static void _cal_server_alarm_timechange_cb(keynode_t *node, void *data)
918 t = vconf_keynode_get_int(node);
920 vconf_get_int(VCONFKEY_SYSTEM_TIMECHANGE, &t);
925 cal_server_alarm_alert(t);
926 cal_server_alarm_register_next_alarm(t);
929 void _cal_server_alarm_set_timechange(void)
931 vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
932 _cal_server_alarm_timechange_cb, NULL);
934 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT,
935 _cal_server_alarm_timechange_cb, NULL);
936 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT,
937 _cal_server_alarm_timechange_cb, NULL);
938 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE,
939 _cal_server_alarm_timechange_cb, NULL);
942 static void __changed_cb(const char* view_uri, void* data)
945 cal_server_alarm_register_next_alarm(time(NULL));
948 static int _cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
950 cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
951 cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
955 void cal_server_alarm_init(void)
958 _cal_server_alarm_set_timechange();
960 ret = alarmmgr_init("calendar-service");
961 RETM_IF(ret < 0, "alarmmgr_init() Fail(%d)", ret);
964 void cal_server_alarm_register(void)
969 ret = alarmmgr_set_cb(_alert_cb, NULL);
970 RETM_IF(ret < 0, "alarmmgr_set_cb() Fail(%d)", ret);
971 _cal_server_alarm_set_inotify(__changed_cb);
972 cal_server_alarm_register_next_alarm(time(NULL));
975 void cal_server_alarm_fini(void)