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_dbus.h"
38 #define CAL_SEARCH_LOOP_MAX 4
40 struct _alarm_data_s {
42 long long int alert_utime; /* to compare */
45 int type; /* utime, localtime */
47 int record; /* todo, event */
48 char datetime[CAL_STR_SHORT_LEN32];
52 /* this api is necessary for repeat instance. */
53 static int _cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
55 char query[CAL_DB_SQL_MAX_LEN] = {0};
58 ret = cal_db_util_begin_trans();
59 if (CALENDAR_ERROR_NONE != ret) {
60 ERR("cal_db_util_begin_trans() Fail");
61 return CALENDAR_ERROR_DB_FAILED;
64 DBG("alarm_id(%d)", alarm_id);
66 snprintf(query, sizeof(query), "UPDATE %s SET alarm_id = 0 WHERE alarm_id =%d ",
67 CAL_TABLE_ALARM, alarm_id);
68 ret = cal_db_util_query_exec(query);
69 if (CALENDAR_ERROR_NONE != ret) {
70 ERR("cal_db_util_query_exec() Fail(%d)", ret);
71 SECURE("[%s]", query);
72 cal_db_util_end_trans(false);
75 cal_db_util_end_trans(true);
76 return CALENDAR_ERROR_NONE;
79 static int _cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
83 DBG("remove alarm id(%d)", alarm_id);
84 _cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
85 ret = alarmmgr_remove_alarm(alarm_id);
86 if (ret != ALARMMGR_RESULT_SUCCESS) {
87 ERR("alarmmgr_remove_alarm() Fail(ret:%d)", ret);
90 return CALENDAR_ERROR_NONE;
93 static int _cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
95 char query[CAL_DB_SQL_MAX_LEN] = {0};
98 ret = cal_db_util_begin_trans();
99 if (CALENDAR_ERROR_NONE != ret) {
100 ERR("cal_db_util_begin_trans() Fail");
101 return CALENDAR_ERROR_DB_FAILED;
104 DBG("Update alarm_id(%d) in alarm table", alarm_id);
105 snprintf(query, sizeof(query), "UPDATE %s SET alarm_id =%d "
106 "WHERE event_id =%d AND remind_tick =%d AND remind_tick_unit =%d",
107 CAL_TABLE_ALARM, alarm_id, event_id, tick, unit);
108 ret = cal_db_util_query_exec(query);
109 if (CALENDAR_ERROR_NONE != ret) {
110 ERR("cal_db_util_query_exec() Fail(%d)", ret);
111 SECURE("[%s]", query);
112 cal_db_util_end_trans(false);
115 cal_db_util_end_trans(true);
116 return CALENDAR_ERROR_NONE;
119 static long long int _cal_server_alarm_get_alert_utime(const char *field, int event_id, time_t current)
122 char query[CAL_DB_SQL_MAX_LEN] = {0};
123 snprintf(query, sizeof(query), "SELECT %s FROM %s "
124 "WHERE event_id=%d AND %s>%ld ORDER BY %s LIMIT 1",
125 field, CAL_TABLE_NORMAL_INSTANCE, event_id, field, current, field);
127 sqlite3_stmt *stmt = NULL;
128 ret = cal_db_util_query_prepare(query, &stmt);
129 if (CALENDAR_ERROR_NONE != ret) {
130 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
131 SECURE("query[%s]", query);
135 long long int utime = 0;
136 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
137 utime = sqlite3_column_int(stmt, 0);
139 sqlite3_finalize(stmt);
143 static int _cal_server_alarm_get_alert_localtime(const char *field, int event_id, time_t current)
146 char query[CAL_DB_SQL_MAX_LEN] = {0};
149 localtime_r(¤t, &st);
150 time_t mod_current = timegm(&st);
151 snprintf(query, sizeof(query), "SELECT %s FROM %s "
152 "WHERE event_id=%d AND strftime('%%s', %s)>%ld ORDER BY %s LIMIT 1",
153 field, CAL_TABLE_ALLDAY_INSTANCE, event_id, field, mod_current, field);
155 sqlite3_stmt *stmt = NULL;
156 ret = cal_db_util_query_prepare(query, &stmt);
157 if (CALENDAR_ERROR_NONE != ret) {
158 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
159 SECURE("query[%s]", query);
163 const char *datetime = NULL;
164 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
165 datetime = (const char *)sqlite3_column_text(stmt, 0);
167 if (NULL == datetime || '\0' == *datetime) {
168 ERR("Invalid datetime [%s]", datetime);
169 sqlite3_finalize(stmt);
173 int y = 0, m = 0, d = 0;
174 int h = 0, n = 0, s = 0;
175 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
176 sqlite3_finalize(stmt);
178 st.tm_year = y - 1900;
185 return (long long int)mktime(&st);
189 * to get aler time, time(NULL) is not accurate. 1 secs diff could be occured.
190 * so, searching DB is neccessary to find alert time.
192 int cal_server_alarm_get_alert_time(int alarm_id, time_t *tt_alert)
195 RETV_IF(NULL == tt_alert, CALENDAR_ERROR_INVALID_PARAMETER);
197 char query[CAL_DB_SQL_MAX_LEN] = {0};
198 snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
199 "A.alarm_type, A.alarm_utime, A.alarm_datetime, B.type, B.dtstart_type, "
200 "B.dtend_type FROM %s as A, %s as B ON A.event_id =B.id WHERE alarm_id =%d ",
201 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE, alarm_id);
203 sqlite3_stmt *stmt = NULL;
204 ret = cal_db_util_query_prepare(query, &stmt);
205 if (CALENDAR_ERROR_NONE != ret) {
206 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
207 SECURE("query[%s]", query);
215 long long int utime = 0;
216 const char *datetime = NULL;
218 int dtstart_type = 0;
222 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
223 event_id = sqlite3_column_int(stmt, 0);
224 unit = sqlite3_column_int(stmt, 1);
225 tick = sqlite3_column_int(stmt, 2);
226 type = sqlite3_column_int(stmt, 3);
227 utime = sqlite3_column_int64(stmt, 4);
228 datetime = (const char *)sqlite3_column_text(stmt, 5);
229 record_type = sqlite3_column_int(stmt, 6);
230 dtstart_type = sqlite3_column_int(stmt, 7);
231 dtend_type = sqlite3_column_int(stmt, 8);
234 if (NULL == tt_alert) {
235 ERR("Invalid parameter: tt_alert is NULL");
236 sqlite3_finalize(stmt);
237 return CALENDAR_ERROR_INVALID_PARAMETER;
240 if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
241 if (CALENDAR_TIME_UTIME == type) {
244 int y = 0, m = 0, d = 0;
245 int h = 0, n = 0, s = 0;
246 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
248 st.tm_year = y - 1900;
254 *tt_alert = mktime(&st);
255 DBG("datetime[%s] to %02d:%02d:%02d (%d)", datetime, h, n, s, *tt_alert);
257 sqlite3_finalize(stmt);
258 return CALENDAR_ERROR_NONE;
260 sqlite3_finalize(stmt);
262 time_t current = time(NULL);
263 current += (tick * unit);
264 current -= 2; /* in case time passed */
266 switch (record_type) {
267 case CALENDAR_BOOK_TYPE_EVENT:
268 switch (dtstart_type) {
269 case CALENDAR_TIME_UTIME:
270 utime = _cal_server_alarm_get_alert_utime("dtstart_utime", event_id, current);
273 case CALENDAR_TIME_LOCALTIME:
274 utime = _cal_server_alarm_get_alert_localtime("dtstart_datetime", event_id, current);
279 case CALENDAR_BOOK_TYPE_TODO:
280 switch (dtend_type) {
281 case CALENDAR_TIME_UTIME:
282 utime = _cal_server_alarm_get_alert_utime("dtend_utime", event_id, current);
285 case CALENDAR_TIME_LOCALTIME:
286 utime = _cal_server_alarm_get_alert_localtime("dtend_datetime", event_id, current);
291 DBG("alert_time(%d) = utime(%lld) - (tick(%d) * unit(%d))", *tt_alert, utime, tick, unit);
293 *tt_alert = utime - (tick * unit);
294 return CALENDAR_ERROR_NONE;
299 * true : to get all alarms including same time event.
300 * (ig. if 3 diffrent alarms exist at 06:30, list has 3 data)
301 * false : to get only one alarm to register in alarm-manager.
302 * (ig. if 3 diffrent alarms exist at 06:30, list has only one)
304 static void _cal_server_alarm_get_upcoming_specific_utime(time_t utime, bool get_all, GList **l)
307 char query[CAL_DB_SQL_MAX_LEN] = {0};
308 snprintf(query, sizeof(query), "SELECT event_id,remind_tick_unit,remind_tick,"
309 "alarm_type,alarm_utime,alarm_datetime "
310 "FROM %s WHERE remind_tick_unit =%d AND alarm_type =%d AND alarm_utime %s %ld %s",
311 CAL_TABLE_ALARM, CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
312 true == get_all ? "=" : ">", utime,
313 true == get_all ? "" : "ORDER BY alarm_utime ASC LIMIT 1");
315 sqlite3_stmt *stmt = NULL;
316 ret = cal_db_util_query_prepare(query, &stmt);
317 if (CALENDAR_ERROR_NONE != ret) {
318 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
319 SECURE("query[%s]", query);
323 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
324 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
326 ERR("calloc() Fail");
327 sqlite3_finalize(stmt);
331 ad->event_id = sqlite3_column_int(stmt, 0);
332 ad->unit = sqlite3_column_int(stmt, 1);
333 ad->tick = sqlite3_column_int(stmt, 2);
334 ad->type = sqlite3_column_int(stmt, 3);
335 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
336 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
337 *l = g_list_append(*l, ad);
338 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
339 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
340 ad->alert_utime = ad->time;
341 if (false == get_all) break;
343 sqlite3_finalize(stmt);
346 static void _cal_server_alarm_get_upcoming_specific_localtime(const char *datetime, bool get_all, GList **l)
349 char query[CAL_DB_SQL_MAX_LEN] = {0};
350 snprintf(query, sizeof(query), "SELECT event_id,remind_tick_unit,remind_tick,"
351 "alarm_type,alarm_utime,alarm_datetime "
352 "FROM %s WHERE remind_tick_unit=%d AND alarm_type=%d AND alarm_datetime %s '%s' %s",
353 CAL_TABLE_ALARM, CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
354 true == get_all ? "=" : ">", datetime,
355 true == get_all ? "" : "ORDER BY alarm_datetime ASC LIMIT 1");
357 sqlite3_stmt *stmt = NULL;
358 ret = cal_db_util_query_prepare(query, &stmt);
359 if (CALENDAR_ERROR_NONE != ret) {
360 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
361 SECURE("query[%s]", query);
365 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
366 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
368 ERR("calloc() Fail");
369 sqlite3_finalize(stmt);
373 ad->event_id = sqlite3_column_int(stmt, 0);
374 ad->unit = sqlite3_column_int(stmt, 1);
375 ad->tick = sqlite3_column_int(stmt, 2);
376 ad->type = sqlite3_column_int(stmt, 3);
377 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
378 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
379 *l = g_list_append(*l, ad);
380 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
381 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
383 int y = 0, m = 0, d = 0;
384 int h = 0, n = 0, s = 0;
385 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
388 st.tm_year = y - 1900;
394 ad->alert_utime = (long long int)mktime(&st);
395 if (false == get_all) break;
397 sqlite3_finalize(stmt);
400 static void _cal_server_alarm_get_upcoming_nonspecific_event_utime(time_t utime, bool get_all, GList **l)
407 char query[CAL_DB_SQL_MAX_LEN] = {0};
408 snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
409 "A.alarm_type,B.dtstart_utime,A.alarm_datetime "
410 "FROM %s as A, %s as B ON A.event_id = B.event_id "
411 "WHERE A.remind_tick_unit >%d AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
412 CAL_TABLE_ALARM, CAL_TABLE_NORMAL_INSTANCE, CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
413 true == get_all ? "=" : ">", utime,
414 true == get_all ? "" : "ORDER BY (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1");
416 sqlite3_stmt *stmt = NULL;
417 ret = cal_db_util_query_prepare(query, &stmt);
418 if (CALENDAR_ERROR_NONE != ret) {
419 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
420 SECURE("query[%s]", query);
424 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
425 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
427 ERR("calloc() Fail");
428 sqlite3_finalize(stmt);
432 ad->event_id = sqlite3_column_int(stmt, 0);
433 ad->unit = sqlite3_column_int(stmt, 1);
434 ad->tick = sqlite3_column_int(stmt, 2);
435 ad->type = sqlite3_column_int(stmt, 3);
436 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
437 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
438 *l = g_list_append(*l, ad);
439 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
440 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
442 ad->alert_utime = ad->time - (ad->tick * ad->unit);
443 if (false == get_all) break;
445 sqlite3_finalize(stmt);
448 static void _cal_server_alarm_get_upcoming_nonspecific_event_localtime(const char *datetime, bool get_all, GList **l)
455 char query[CAL_DB_SQL_MAX_LEN] = {0};
456 snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
457 "A.alarm_type,A.alarm_utime,B.dtstart_datetime "
458 "FROM %s as A, %s as B ON A.event_id = B.event_id "
459 "WHERE A.remind_tick_unit >%d AND "
460 "(strftime('%%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
461 CAL_TABLE_ALARM, CAL_TABLE_ALLDAY_INSTANCE, CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
462 datetime, true == get_all ? "=" : ">",
463 true == get_all ? "" : "ORDER BY (strftime('%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
464 sqlite3_stmt *stmt = NULL;
465 ret = cal_db_util_query_prepare(query, &stmt);
466 if (CALENDAR_ERROR_NONE != ret) {
467 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
468 SECURE("query[%s]", query);
472 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
473 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
475 ERR("calloc() Fail");
476 sqlite3_finalize(stmt);
480 ad->event_id = sqlite3_column_int(stmt, 0);
481 ad->unit = sqlite3_column_int(stmt, 1);
482 ad->tick = sqlite3_column_int(stmt, 2);
483 ad->type = sqlite3_column_int(stmt, 3);
484 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
485 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
486 *l = g_list_append(*l, ad);
487 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
488 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
490 int y = 0, m = 0, d = 0;
491 int h = 0, n = 0, s = 0;
492 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
495 st.tm_year = y - 1900;
501 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
502 if (false == get_all) break;
504 sqlite3_finalize(stmt);
507 static void _cal_server_alarm_get_upcoming_nonspecific_todo_utime(time_t utime, bool get_all, GList **l)
514 char query[CAL_DB_SQL_MAX_LEN] = {0};
515 snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
516 "A.alarm_type,B.dtend_utime,A.alarm_datetime "
517 "FROM %s as A, %s as B ON A.event_id = B.id "
518 "WHERE A.remind_tick_unit >%d AND B.type =%d "
519 "AND (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
520 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
521 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
522 true == get_all ? "=" : ">", utime,
523 true == get_all ? "" : "ORDER BY (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
525 sqlite3_stmt *stmt = NULL;
526 ret = cal_db_util_query_prepare(query, &stmt);
527 if (CALENDAR_ERROR_NONE != ret) {
528 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
529 SECURE("query[%s]", query);
533 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
534 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
536 ERR("calloc() Fail");
537 sqlite3_finalize(stmt);
541 ad->event_id = sqlite3_column_int(stmt, 0);
542 ad->unit = sqlite3_column_int(stmt, 1);
543 ad->tick = sqlite3_column_int(stmt, 2);
544 ad->type = sqlite3_column_int(stmt, 3);
545 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
546 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
547 *l = g_list_append(*l, ad);
548 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
549 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
551 ad->alert_utime = ad->time - (ad->tick * ad->unit);
552 if (false == get_all) break;
554 sqlite3_finalize(stmt);
557 static void _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(const char *datetime, bool get_all, GList **l)
564 char query[CAL_DB_SQL_MAX_LEN] = {0};
565 snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
566 "A.alarm_type,A.alarm_utime,B.dtend_datetime "
567 "FROM %s as A, %s as B ON A.event_id = B.id "
568 "WHERE A.remind_tick_unit >%d AND B.type =%d "
569 "AND (strftime('%%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
570 CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
571 CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
572 datetime, true == get_all ? "=" : ">",
573 true == get_all ? "" : "ORDER BY (strftime('%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
575 sqlite3_stmt *stmt = NULL;
576 ret = cal_db_util_query_prepare(query, &stmt);
577 if (CALENDAR_ERROR_NONE != ret) {
578 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
579 SECURE("query[%s]", query);
583 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
584 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
586 ERR("calloc() Fail");
587 sqlite3_finalize(stmt);
591 ad->event_id = sqlite3_column_int(stmt, 0);
592 ad->unit = sqlite3_column_int(stmt, 1);
593 ad->tick = sqlite3_column_int(stmt, 2);
594 ad->type = sqlite3_column_int(stmt, 3);
595 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
596 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
597 *l = g_list_append(*l, ad);
598 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
599 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
601 int y = 0, m = 0, d = 0;
602 int h = 0, n = 0, s = 0;
603 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
606 st.tm_year = y - 1900;
612 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
613 if (false == get_all) break;
615 sqlite3_finalize(stmt);
618 static void _cal_server_alarm_get_latest(time_t utime, bool get_all, GList **out_l)
621 RET_IF(NULL == out_l);
624 struct tm st_local = {0};
625 localtime_r(&utime, &st_local);
627 char datetime[CAL_STR_SHORT_LEN32] = {0};
628 snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
629 st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
630 st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
631 DBG("get alert to register with given time (%ld) datetime[%s]", utime, datetime);
635 _cal_server_alarm_get_upcoming_specific_utime(utime, get_all, &l);
636 _cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, get_all, &l);
637 _cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, get_all, &l);
639 _cal_server_alarm_get_upcoming_specific_localtime(datetime, get_all, &l);
640 _cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, get_all, &l);
641 _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, get_all, &l);
646 static gint _cal_server_alarm_sort_cb(gconstpointer a, gconstpointer b)
648 struct _alarm_data_s *p1 = (struct _alarm_data_s *)a;
649 struct _alarm_data_s *p2 = (struct _alarm_data_s *)b;
650 DBG("%lld) > (%lld)", p1->alert_utime, p2->alert_utime);
652 return p1->alert_utime < p2->alert_utime ? -1 : 1;
655 static GFunc _cal_server_alarm_print_cb(gpointer data, gpointer user_data)
657 struct _alarm_data_s *ad = (struct _alarm_data_s *)data;
658 DBG("id(%d) unit(%d) tick(%d) type(%d) time(%lld) datetime[%s]",
659 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
663 static int _cal_server_alarm_register(GList *alarm_list)
666 RETV_IF(NULL == alarm_list, CALENDAR_ERROR_INVALID_PARAMETER);
668 int ret = CALENDAR_ERROR_NONE;
669 GList *l = g_list_first(alarm_list);
670 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
671 RETVM_IF(NULL == ad, CALENDAR_ERROR_DB_FAILED, "No data");
673 /* clear all alarm which set by mine. */
674 ret = alarmmgr_enum_alarm_ids(_cal_server_alarm_clear_all_cb, NULL);
675 if (ret != ALARMMGR_RESULT_SUCCESS) {
676 ERR("alarmmgr_enum_alarm_ids() Fail");
680 time_t mod_time = (time_t)ad->alert_utime;
681 alarm_entry_t *alarm_info = NULL;
682 alarm_info = alarmmgr_create_alarm();
683 if (NULL == alarm_info) {
684 ERR("Failed to create alarm");
685 return CALENDAR_ERROR_DB_FAILED;
688 struct tm st_alarm = {0};
690 switch (ad->system_type) {
691 case CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR:
692 gmtime_r(&mod_time, &st_alarm);
697 localtime_r(&mod_time, &st_alarm);
701 alarm_date_t date = {0};
702 date.year = st_alarm.tm_year + 1900;
703 date.month = st_alarm.tm_mon + 1;
704 date.day = st_alarm.tm_mday;
705 date.hour = st_alarm.tm_hour;
706 date.min = st_alarm.tm_min;
707 date.sec = st_alarm.tm_sec;
708 alarmmgr_set_time(alarm_info, date);
709 DBG(COLOR_CYAN" >>> registered record id (%d) at %04d/%02d/%02d %02d:%02d:%02d "COLOR_END" (utime(%lld), datetime[%s], tick(%d) unit(%d))",
710 ad->event_id, date.year, date.month, date.day, date.hour, date.min, date.sec,
711 ad->time, ad->datetime, ad->tick, ad->unit);
714 ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
716 ERR("alarmmgr_add_alarm_with_localtime Fail (%d)", ret);
717 alarmmgr_free_alarm(alarm_info);
720 DBG("alarmmgr id (%d)", alarm_id);
721 _cal_server_alarm_update_alarm_id(alarm_id, ad->event_id, ad->tick, ad->unit);
722 alarmmgr_free_alarm(alarm_info);
723 return CALENDAR_ERROR_NONE;
730 static bool __app_matched_cb(app_control_h app_control, const char *package, void *user_data)
736 RETV_IF(NULL == user_data, true);
739 ret = app_control_get_mime(app_control, &mime);
740 RETVM_IF(APP_CONTROL_ERROR_NONE != ret, true, "app_control_get_mime() Fail(%d)", ret);
742 const char *reminder_mime = "application/x-tizen.calendar.reminder";
743 if (strncmp(mime, reminder_mime, strlen(reminder_mime))) { /* not same */
744 DBG("get mime[%s] is not [%s]", mime, reminder_mime);
750 GList *alarm_list = (GList *)user_data;
752 len = g_list_length(alarm_list);
754 DBG("len is 0, no alarm list");
758 app_control_h b = NULL;
759 app_control_create(&b);
760 app_control_set_operation(b, APP_CONTROL_OPERATION_DEFAULT);
761 app_control_set_app_id(b, package);
764 ids = calloc(len, sizeof(char *));
766 ERR("calloc() Fail");
767 app_control_destroy(b);
768 return CALENDAR_ERROR_OUT_OF_MEMORY;
770 GList *l = g_list_first(alarm_list);
772 for (i = 0; i < len; i++) {
773 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
779 DBG("pkg[%s] time[%lld] tick[%d] unit[%d] record_type[%d]",
780 package, ad->time, ad->tick, ad->unit, ad->record);
783 char extra[CAL_STR_MIDDLE_LEN] = {0};
784 len = snprintf(extra, sizeof(extra), "%s=%d", "id", ad->event_id);
785 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%lld", "time", ad->time);
786 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "tick", ad->tick);
787 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "unit", ad->unit);
788 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "type", ad->record);
790 char buf_id[CAL_STR_MIDDLE_LEN] = {0};
791 snprintf(buf_id, sizeof(buf_id), "%d", ad->event_id);
792 app_control_add_extra_data(b, buf_id, extra); /* key: id, value: id=4&time=123123&.. */
793 DBG("value[%s]", extra);
796 ids[i] = strdup(buf_id);
800 app_control_add_extra_data_array(b, "ids", (const char **)ids, len);
801 app_control_send_launch_request(b, NULL, NULL);
802 app_control_destroy(b);
804 for (i = 0; i < len; i++) {
813 static void _cal_server_alarm_noti_with_control(GList *alarm_list)
816 RETM_IF(NULL == alarm_list, "No alarm list");
818 app_control_h app_control = NULL;
819 app_control_create(&app_control);
820 app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW);
821 app_control_set_mime(app_control, "application/x-tizen.calendar.reminder");
823 struct alarm_ud *au = calloc(1, sizeof(struct alarm_ud));
825 ERR("calloc() Fail");
826 app_control_destroy(app_control);
829 au->alarm_list = alarm_list;
830 app_control_foreach_app_matched(app_control, __app_matched_cb, au);
831 app_control_destroy(app_control);
834 static void _cal_server_alarm_noti_with_callback(GList *alarm_list)
836 RETM_IF(NULL == alarm_list, "No alarm list");
838 GList *l = g_list_first(alarm_list);
840 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
846 DBG("callback time[%lld] tick[%d] unit[%d] record_type[%d]",
847 ad->time, ad->tick, ad->unit, ad->record);
850 char extra[CAL_STR_MIDDLE_LEN] = {0};
851 len = snprintf(extra, sizeof(extra), "%s=%d", "id", ad->event_id);
852 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%lld", "time", ad->time);
853 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "tick", ad->tick);
854 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "unit", ad->unit);
855 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "type", ad->record);
856 cal_dbus_publish_reminder(len, extra);
862 int cal_server_alarm_register_next_alarm(time_t utime)
865 _cal_server_alarm_get_latest(utime, false, &l);
867 return CALENDAR_ERROR_NONE;
869 l = g_list_sort(l, _cal_server_alarm_sort_cb);
870 g_list_foreach(l, (GFunc)_cal_server_alarm_print_cb, NULL);
871 _cal_server_alarm_register(l);
873 g_list_free_full(l, free);
874 return CALENDAR_ERROR_NONE;
877 void cal_server_alarm_alert(time_t tt_alert)
880 _cal_server_alarm_get_latest(tt_alert, true, &l);
881 _cal_server_alarm_noti_with_callback(l);
882 _cal_server_alarm_noti_with_control(l);
885 static int _alert_cb(alarm_id_t alarm_id, void *data)
888 DBG("alarm_id (%ld)", alarm_id);
891 cal_server_alarm_get_alert_time(alarm_id, &tt_alert);
892 cal_server_alarm_alert(tt_alert);
893 _cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
894 cal_server_alarm_register_next_alarm(tt_alert);
898 static void _cal_server_alarm_timechange_cb(keynode_t *node, void *data)
900 time_t t = time(NULL);
901 cal_server_alarm_alert(t);
902 cal_server_alarm_register_next_alarm(t);
905 void _cal_server_alarm_set_timechange(void)
907 vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
908 _cal_server_alarm_timechange_cb, NULL);
910 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT,
911 _cal_server_alarm_timechange_cb, NULL);
912 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT,
913 _cal_server_alarm_timechange_cb, NULL);
914 vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE,
915 _cal_server_alarm_timechange_cb, NULL);
918 static void _changed_cb(const char* view_uri, void* data)
921 cal_server_alarm_register_next_alarm(time(NULL));
924 static int _cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
926 cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
927 cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
931 int cal_server_alarm_init(void)
936 _cal_server_alarm_set_timechange();
937 _cal_server_alarm_set_inotify(_changed_cb);
939 ret = alarmmgr_init("calendar-service");
941 ERR("alarmmgr_init() Fail(%d)", ret);
942 return CALENDAR_ERROR_SYSTEM;
945 ret = alarmmgr_set_cb(_alert_cb, NULL);
947 ERR("alarmmgr_set_cb() Fail(%d)", ret);
948 return CALENDAR_ERROR_SYSTEM;
951 cal_server_alarm_register_next_alarm(time(NULL));
952 return CALENDAR_ERROR_NONE;
955 void cal_server_alarm_deinit(void)