add comment LCOV_EXCL
[platform/core/pim/calendar-service.git] / server / cal_server_alarm.c
1 /*
2  * Calendar Service
3  *
4  * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 #include <stdlib.h>
21
22 #include <sys/time.h>
23 #include <unistd.h>
24 #include <alarm.h>
25 #include <vconf.h>
26 #include <app.h>
27
28 #include "calendar.h"
29 #include "cal_typedef.h"
30 #include "cal_internal.h"
31 #include "cal_time.h"
32 #include "cal_inotify.h"
33 #include "cal_db_util.h"
34 #include "cal_db.h"
35 #include "cal_db_query.h"
36 #include "cal_server_dbus.h"
37
38 #define CAL_SEARCH_LOOP_MAX 4
39
40 struct _alarm_data_s {
41         int event_id;
42         long long int alert_utime; /* to compare */
43         int unit;
44         int tick;
45         int type; /* utime, localtime */
46         long long int time;
47         int record; /* todo, event */
48         char datetime[CAL_STR_SHORT_LEN32];
49         int system_type;
50 };
51
52 /* this api is necessary for repeat instance. */
53 static int _cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
54 {
55         char query[CAL_DB_SQL_MAX_LEN] = {0};
56         int ret = 0;
57
58         ret = cal_db_util_begin_trans();
59         if (CALENDAR_ERROR_NONE != ret) {
60                 /* LCOV_EXCL_START */
61                 ERR("cal_db_util_begin_trans() Fail");
62                 return CALENDAR_ERROR_DB_FAILED;
63                 /* LCOV_EXCL_STOP */
64         }
65
66         DBG("alarm_id(%d)", alarm_id);
67
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                 /* LCOV_EXCL_START */
73                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
74                 SECURE("[%s]", query);
75                 cal_db_util_end_trans(false);
76                 return ret;
77                 /* LCOV_EXCL_STOP */
78         }
79         cal_db_util_end_trans(true);
80         return CALENDAR_ERROR_NONE;
81 }
82
83 static int _cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
84 {
85         int ret;
86
87         DBG("remove alarm id(%d)", alarm_id);
88         _cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
89         ret = alarmmgr_remove_alarm(alarm_id);
90         if (ret != ALARMMGR_RESULT_SUCCESS) {
91                 /* LCOV_EXCL_START */
92                 ERR("alarmmgr_remove_alarm() Fail(ret:%d)", ret);
93                 return ret;
94                 /* LCOV_EXCL_STOP */
95         }
96         return CALENDAR_ERROR_NONE;
97 }
98
99 static int _cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
100 {
101         char query[CAL_DB_SQL_MAX_LEN] = {0};
102         int ret = 0;
103
104         ret = cal_db_util_begin_trans();
105         if (CALENDAR_ERROR_NONE != ret) {
106                 /* LCOV_EXCL_START */
107                 ERR("cal_db_util_begin_trans() Fail");
108                 return CALENDAR_ERROR_DB_FAILED;
109                 /* LCOV_EXCL_STOP */
110         }
111
112         DBG("Update alarm_id(%d) in alarm table", alarm_id);
113         snprintf(query, sizeof(query), "UPDATE %s SET alarm_id =%d "
114                         "WHERE event_id =%d AND remind_tick =%d AND remind_tick_unit =%d",
115                         CAL_TABLE_ALARM, alarm_id, event_id, tick, unit);
116         ret = cal_db_util_query_exec(query);
117         if (CALENDAR_ERROR_NONE != ret) {
118                 /* LCOV_EXCL_START */
119                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
120                 SECURE("[%s]", query);
121                 cal_db_util_end_trans(false);
122                 return ret;
123                 /* LCOV_EXCL_STOP */
124         }
125         cal_db_util_end_trans(true);
126         return CALENDAR_ERROR_NONE;
127 }
128
129 static long long int _cal_server_alarm_get_alert_utime(const char *field, int event_id, time_t current)
130 {
131         int ret = 0;
132         char query[CAL_DB_SQL_MAX_LEN] = {0};
133         snprintf(query, sizeof(query), "SELECT %s FROM %s "
134                         "WHERE event_id=%d AND %s>%ld ORDER BY %s LIMIT 1",
135                         field, CAL_TABLE_NORMAL_INSTANCE, event_id, field, current, field);
136
137         sqlite3_stmt *stmt = NULL;
138         ret = cal_db_util_query_prepare(query, &stmt);
139         if (CALENDAR_ERROR_NONE != ret) {
140                 /* LCOV_EXCL_START */
141                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
142                 SECURE("query[%s]", query);
143                 return ret;
144                 /* LCOV_EXCL_STOP */
145         }
146
147         long long int utime = 0;
148         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
149                 utime = sqlite3_column_int(stmt, 0);
150
151         sqlite3_finalize(stmt);
152         return utime;
153 }
154
155 static int _cal_server_alarm_get_alert_localtime(const char *field, int event_id, time_t current)
156 {
157         int ret = 0;
158         char query[CAL_DB_SQL_MAX_LEN] = {0};
159         struct tm st = {0};
160         tzset();
161         localtime_r(&current, &st);
162         time_t mod_current = timegm(&st);
163         snprintf(query, sizeof(query), "SELECT %s FROM %s "
164                         "WHERE event_id=%d AND strftime('%%s', %s)>%ld ORDER BY %s LIMIT 1",
165                         field, CAL_TABLE_ALLDAY_INSTANCE, event_id, field, mod_current, field);
166
167         sqlite3_stmt *stmt = NULL;
168         ret = cal_db_util_query_prepare(query, &stmt);
169         if (CALENDAR_ERROR_NONE != ret) {
170                 /* LCOV_EXCL_START */
171                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
172                 SECURE("query[%s]", query);
173                 return ret;
174                 /* LCOV_EXCL_STOP */
175         }
176
177         const char *datetime = NULL;
178         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
179                 datetime = (const char *)sqlite3_column_text(stmt, 0);
180
181         if (NULL == datetime || '\0' == *datetime) {
182                 /* LCOV_EXCL_START */
183                 ERR("Invalid datetime [%s]", datetime);
184                 sqlite3_finalize(stmt);
185                 return 0;
186                 /* LCOV_EXCL_STOP */
187         }
188
189         int y = 0, m = 0, d = 0;
190         int h = 0, n = 0, s = 0;
191         sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
192         sqlite3_finalize(stmt);
193
194         st.tm_year = y - 1900;
195         st.tm_mon = m - 1;
196         st.tm_mday = d;
197         st.tm_hour = h;
198         st.tm_min = n;
199         st.tm_sec = s;
200
201         return (long long int)mktime(&st);
202 }
203
204 /*
205  * to get aler time, time(NULL) is not accurate. 1 secs diff could be occured.
206  * so, searching DB is neccessary to find alert time.
207  */
208 int cal_server_alarm_get_alert_time(int alarm_id, time_t *tt_alert)
209 {
210         int ret = 0;
211         RETV_IF(NULL == tt_alert, CALENDAR_ERROR_INVALID_PARAMETER);
212
213         char query[CAL_DB_SQL_MAX_LEN] = {0};
214         snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
215                         "A.alarm_type, A.alarm_utime, A.alarm_datetime, B.type, B.dtstart_type, "
216                         "B.dtend_type FROM %s as A, %s as B ON A.event_id =B.id WHERE alarm_id =%d ",
217                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE, alarm_id);
218
219         sqlite3_stmt *stmt = NULL;
220         ret = cal_db_util_query_prepare(query, &stmt);
221         if (CALENDAR_ERROR_NONE != ret) {
222                 /* LCOV_EXCL_START */
223                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
224                 SECURE("query[%s]", query);
225                 return ret;
226                 /* LCOV_EXCL_STOP */
227         }
228
229         int event_id = 0;
230         int unit = 0;
231         int tick = 0;
232         int type = 0;
233         long long int utime = 0;
234         const char *datetime = NULL;
235         int record_type = 0;
236         int dtstart_type = 0;
237         int dtend_type = 0;
238         struct tm st = {0};
239
240         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
241                 event_id = sqlite3_column_int(stmt, 0);
242                 unit = sqlite3_column_int(stmt, 1);
243                 tick = sqlite3_column_int(stmt, 2);
244                 type = sqlite3_column_int(stmt, 3);
245                 utime = sqlite3_column_int64(stmt, 4);
246                 datetime = (const char *)sqlite3_column_text(stmt, 5);
247                 record_type = sqlite3_column_int(stmt, 6);
248                 dtstart_type = sqlite3_column_int(stmt, 7);
249                 dtend_type = sqlite3_column_int(stmt, 8);
250         }
251
252         if (NULL == tt_alert) {
253                 /* LCOV_EXCL_START */
254                 ERR("Invalid parameter: tt_alert is NULL");
255                 sqlite3_finalize(stmt);
256                 return CALENDAR_ERROR_INVALID_PARAMETER;
257                 /* LCOV_EXCL_STOP */
258         }
259
260         if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
261                 if (CALENDAR_TIME_UTIME == type) {
262                         *tt_alert = utime;
263                 } else {
264                         int y = 0, m = 0, d = 0;
265                         int h = 0, n = 0, s = 0;
266                         if (datetime) {
267                                 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
268
269                                 st.tm_year = y - 1900;
270                                 st.tm_mon = m - 1;
271                                 st.tm_mday = d;
272                                 st.tm_hour = h;
273                                 st.tm_min = n;
274                                 st.tm_sec = s;
275                                 *tt_alert = mktime(&st);
276                                 DBG("datetime[%s] to %02d:%02d:%02d (%d)", datetime, h, n, s, *tt_alert);
277                         }
278                 }
279                 sqlite3_finalize(stmt);
280                 return CALENDAR_ERROR_NONE;
281         }
282         sqlite3_finalize(stmt);
283
284         time_t current = time(NULL);
285         current += (tick * unit);
286         current -= 2; /* in case time passed */
287
288         switch (record_type) {
289         case CALENDAR_BOOK_TYPE_EVENT:
290                 switch (dtstart_type) {
291                 case CALENDAR_TIME_UTIME:
292                         utime = _cal_server_alarm_get_alert_utime("dtstart_utime", event_id, current);
293                         break;
294
295                 case CALENDAR_TIME_LOCALTIME:
296                         utime = _cal_server_alarm_get_alert_localtime("dtstart_datetime", event_id, current);
297                         break;
298                 }
299                 break;
300
301         case CALENDAR_BOOK_TYPE_TODO:
302                 switch (dtend_type) {
303                 case CALENDAR_TIME_UTIME:
304                         utime = _cal_server_alarm_get_alert_utime("dtend_utime", event_id, current);
305                         break;
306
307                 case CALENDAR_TIME_LOCALTIME:
308                         utime = _cal_server_alarm_get_alert_localtime("dtend_datetime", event_id, current);
309                         break;
310                 }
311                 break;
312         }
313         DBG("alert_time(%d) = utime(%lld) - (tick(%d) * unit(%d))", *tt_alert, utime, tick, unit);
314
315         *tt_alert = utime - (tick * unit);
316         return CALENDAR_ERROR_NONE;
317 }
318
319 /*
320  * bool get_all is
321  * true : to get all alarms including same time event.
322  * (ig. if 3 diffrent alarms exist at 06:30, list has 3 data)
323  * false : to get only one alarm to register in alarm-manager.
324  * (ig. if 3 diffrent alarms exist at 06:30, list has only one)
325  */
326 static void _cal_server_alarm_get_upcoming_specific_utime(time_t utime, bool get_all, GList **l)
327 {
328         int ret = 0;
329         char query[CAL_DB_SQL_MAX_LEN] = {0};
330         snprintf(query, sizeof(query), "SELECT event_id,remind_tick_unit,remind_tick,"
331                         "alarm_type,alarm_utime,alarm_datetime "
332                         "FROM %s WHERE remind_tick_unit =%d AND alarm_type =%d AND alarm_utime %s %ld %s",
333                         CAL_TABLE_ALARM, CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
334                         true == get_all ? "=" : ">", utime,
335                         true == get_all ? "" : "ORDER BY alarm_utime ASC LIMIT 1");
336
337         sqlite3_stmt *stmt = NULL;
338         ret = cal_db_util_query_prepare(query, &stmt);
339         if (CALENDAR_ERROR_NONE != ret) {
340                 /* LCOV_EXCL_START */
341                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
342                 SECURE("query[%s]", query);
343                 return;
344                 /* LCOV_EXCL_STOP */
345         }
346
347         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
348                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
349                 if (NULL == ad) {
350                         /* LCOV_EXCL_START */
351                         ERR("calloc() Fail");
352                         sqlite3_finalize(stmt);
353                         return;
354                         /* LCOV_EXCL_STOP */
355                 }
356
357                 ad->event_id = sqlite3_column_int(stmt, 0);
358                 ad->unit = sqlite3_column_int(stmt, 1);
359                 ad->tick = sqlite3_column_int(stmt, 2);
360                 ad->type = sqlite3_column_int(stmt, 3);
361                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
362                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
363                 *l = g_list_append(*l, ad);
364                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
365                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
366                 ad->alert_utime = ad->time;
367                 if (false == get_all) break;
368         }
369         sqlite3_finalize(stmt);
370 }
371
372 static void _cal_server_alarm_get_upcoming_specific_localtime(const char *datetime, bool get_all, GList **l)
373 {
374         int ret = 0;
375         char query[CAL_DB_SQL_MAX_LEN] = {0};
376         snprintf(query, sizeof(query), "SELECT event_id,remind_tick_unit,remind_tick,"
377                         "alarm_type,alarm_utime,alarm_datetime "
378                         "FROM %s WHERE remind_tick_unit=%d AND alarm_type=%d AND alarm_datetime %s '%s' %s",
379                         CAL_TABLE_ALARM, CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
380                         true == get_all ? "=" : ">", datetime,
381                         true == get_all ? "" : "ORDER BY alarm_datetime ASC LIMIT 1");
382
383         sqlite3_stmt *stmt = NULL;
384         ret = cal_db_util_query_prepare(query, &stmt);
385         if (CALENDAR_ERROR_NONE != ret) {
386                 /* LCOV_EXCL_START */
387                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
388                 SECURE("query[%s]", query);
389                 return;
390                 /* LCOV_EXCL_STOP */
391         }
392
393         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
394                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
395                 if (NULL == ad) {
396                         /* LCOV_EXCL_START */
397                         ERR("calloc() Fail");
398                         sqlite3_finalize(stmt);
399                         return;
400                         /* LCOV_EXCL_STOP */
401                 }
402
403                 ad->event_id = sqlite3_column_int(stmt, 0);
404                 ad->unit = sqlite3_column_int(stmt, 1);
405                 ad->tick = sqlite3_column_int(stmt, 2);
406                 ad->type = sqlite3_column_int(stmt, 3);
407                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
408                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
409                 *l = g_list_append(*l, ad);
410                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
411                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
412
413                 int y = 0, m = 0, d = 0;
414                 int h = 0, n = 0, s = 0;
415                 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
416
417                 struct tm st = {0};
418                 st.tm_year = y - 1900;
419                 st.tm_mon = m -1;
420                 st.tm_mday = d;
421                 st.tm_hour = h;
422                 st.tm_min = n;
423                 st.tm_sec = s;
424                 ad->alert_utime = (long long int)mktime(&st);
425                 if (false == get_all) break;
426         }
427         sqlite3_finalize(stmt);
428 }
429
430 static void _cal_server_alarm_get_upcoming_nonspecific_event_utime(time_t utime, bool get_all, GList **l)
431 {
432         int ret = 0;
433         /*
434          * A:alarm
435          * B:normal instance
436          */
437         char query[CAL_DB_SQL_MAX_LEN] = {0};
438         snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
439                         "A.alarm_type,B.dtstart_utime,A.alarm_datetime "
440                         "FROM %s as A, %s as B ON A.event_id = B.event_id "
441                         "WHERE A.remind_tick_unit >%d AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
442                         CAL_TABLE_ALARM, CAL_TABLE_NORMAL_INSTANCE, CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
443                         true == get_all ? "=" : ">", utime,
444                         true == get_all ? "" : "ORDER BY (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1");
445
446         sqlite3_stmt *stmt = NULL;
447         ret = cal_db_util_query_prepare(query, &stmt);
448         if (CALENDAR_ERROR_NONE != ret) {
449                 /* LCOV_EXCL_START */
450                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
451                 SECURE("query[%s]", query);
452                 return;
453                 /* LCOV_EXCL_STOP */
454         }
455
456         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
457                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
458                 if (NULL == ad) {
459                         /* LCOV_EXCL_START */
460                         ERR("calloc() Fail");
461                         sqlite3_finalize(stmt);
462                         return;
463                         /* LCOV_EXCL_STOP */
464                 }
465
466                 ad->event_id = sqlite3_column_int(stmt, 0);
467                 ad->unit = sqlite3_column_int(stmt, 1);
468                 ad->tick = sqlite3_column_int(stmt, 2);
469                 ad->type = sqlite3_column_int(stmt, 3);
470                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
471                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
472                 *l = g_list_append(*l, ad);
473                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
474                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
475
476                 ad->alert_utime = ad->time - (ad->tick * ad->unit);
477                 if (false == get_all) break;
478         }
479         sqlite3_finalize(stmt);
480 }
481
482 static void _cal_server_alarm_get_upcoming_nonspecific_event_localtime(const char *datetime, bool get_all, GList **l)
483 {
484         int ret = 0;
485         /*
486          * A:alarm
487          * B:allday
488          */
489         char query[CAL_DB_SQL_MAX_LEN] = {0};
490         snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
491                         "A.alarm_type,A.alarm_utime,B.dtstart_datetime "
492                         "FROM %s as A, %s as B ON A.event_id = B.event_id "
493                         "WHERE A.remind_tick_unit >%d AND "
494                         "(strftime('%%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
495                         CAL_TABLE_ALARM, CAL_TABLE_ALLDAY_INSTANCE, CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
496                         datetime, true == get_all ? "=" : ">",
497                         true == get_all ? "" : "ORDER BY (strftime('%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
498         sqlite3_stmt *stmt = NULL;
499         ret = cal_db_util_query_prepare(query, &stmt);
500         if (CALENDAR_ERROR_NONE != ret) {
501                 /* LCOV_EXCL_START */
502                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
503                 SECURE("query[%s]", query);
504                 return;
505                 /* LCOV_EXCL_STOP */
506         }
507
508         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
509                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
510                 if (NULL == ad) {
511                         /* LCOV_EXCL_START */
512                         ERR("calloc() Fail");
513                         sqlite3_finalize(stmt);
514                         return;
515                         /* LCOV_EXCL_STOP */
516                 }
517
518                 ad->event_id = sqlite3_column_int(stmt, 0);
519                 ad->unit = sqlite3_column_int(stmt, 1);
520                 ad->tick = sqlite3_column_int(stmt, 2);
521                 ad->type = sqlite3_column_int(stmt, 3);
522                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
523                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
524                 *l = g_list_append(*l, ad);
525                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
526                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
527
528                 int y = 0, m = 0, d = 0;
529                 int h = 0, n = 0, s = 0;
530                 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
531
532                 struct tm st = {0};
533                 st.tm_year = y - 1900;
534                 st.tm_mon = m -1;
535                 st.tm_mday = d;
536                 st.tm_hour = h;
537                 st.tm_min = n;
538                 st.tm_sec = s;
539                 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
540                 if (false == get_all) break;
541         }
542         sqlite3_finalize(stmt);
543 }
544
545 static void _cal_server_alarm_get_upcoming_nonspecific_todo_utime(time_t utime, bool get_all, GList **l)
546 {
547         int ret = 0;
548         /*
549          * A:alarm
550          * B:todo(normal)
551          */
552         char query[CAL_DB_SQL_MAX_LEN] = {0};
553         snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
554                         "A.alarm_type,B.dtend_utime,A.alarm_datetime "
555                         "FROM %s as A, %s as B ON A.event_id = B.id "
556                         "WHERE A.remind_tick_unit >%d AND B.type =%d "
557                         "AND (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
558                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
559                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
560                         true == get_all ? "=" : ">", utime,
561                         true == get_all ? "" : "ORDER BY (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
562
563         sqlite3_stmt *stmt = NULL;
564         ret = cal_db_util_query_prepare(query, &stmt);
565         if (CALENDAR_ERROR_NONE != ret) {
566                 /* LCOV_EXCL_START */
567                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
568                 SECURE("query[%s]", query);
569                 return;
570                 /* LCOV_EXCL_STOP */
571         }
572
573         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
574                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
575                 if (NULL == ad) {
576                         /* LCOV_EXCL_START */
577                         ERR("calloc() Fail");
578                         sqlite3_finalize(stmt);
579                         return;
580                         /* LCOV_EXCL_STOP */
581                 }
582
583                 ad->event_id = sqlite3_column_int(stmt, 0);
584                 ad->unit = sqlite3_column_int(stmt, 1);
585                 ad->tick = sqlite3_column_int(stmt, 2);
586                 ad->type = sqlite3_column_int(stmt, 3);
587                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
588                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
589                 *l = g_list_append(*l, ad);
590                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
591                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
592
593                 ad->alert_utime = ad->time - (ad->tick * ad->unit);
594                 if (false == get_all) break;
595         }
596         sqlite3_finalize(stmt);
597 }
598
599 static void _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(const char *datetime, bool get_all, GList **l)
600 {
601         int ret = 0;
602         /*
603          * A:alarm
604          * B:todo(allday)
605          */
606         char query[CAL_DB_SQL_MAX_LEN] = {0};
607         snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
608                         "A.alarm_type,A.alarm_utime,B.dtend_datetime "
609                         "FROM %s as A, %s as B ON A.event_id = B.id "
610                         "WHERE A.remind_tick_unit >%d AND B.type =%d "
611                         "AND (strftime('%%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
612                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
613                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
614                         datetime, true == get_all ? "=" : ">",
615                         true == get_all ? "" : "ORDER BY (strftime('%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
616
617         sqlite3_stmt *stmt = NULL;
618         ret = cal_db_util_query_prepare(query, &stmt);
619         if (CALENDAR_ERROR_NONE != ret) {
620                 /* LCOV_EXCL_START */
621                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
622                 SECURE("query[%s]", query);
623                 return;
624                 /* LCOV_EXCL_STOP */
625         }
626
627         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
628                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
629                 if (NULL == ad) {
630                         /* LCOV_EXCL_START */
631                         ERR("calloc() Fail");
632                         sqlite3_finalize(stmt);
633                         return;
634                         /* LCOV_EXCL_STOP */
635                 }
636
637                 ad->event_id = sqlite3_column_int(stmt, 0);
638                 ad->unit = sqlite3_column_int(stmt, 1);
639                 ad->tick = sqlite3_column_int(stmt, 2);
640                 ad->type = sqlite3_column_int(stmt, 3);
641                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
642                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
643                 *l = g_list_append(*l, ad);
644                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
645                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
646
647                 int y = 0, m = 0, d = 0;
648                 int h = 0, n = 0, s = 0;
649                 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
650
651                 struct tm st = {0};
652                 st.tm_year = y - 1900;
653                 st.tm_mon = m -1;
654                 st.tm_mday = d;
655                 st.tm_hour = h;
656                 st.tm_min = n;
657                 st.tm_sec = s;
658                 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
659                 if (false == get_all) break;
660         }
661         sqlite3_finalize(stmt);
662 }
663
664 static void _cal_server_alarm_get_latest(time_t utime, bool get_all, GList **out_l)
665 {
666         CAL_FN_CALL();
667         RET_IF(NULL == out_l);
668
669         tzset();
670         struct tm st_local = {0};
671         localtime_r(&utime, &st_local);
672
673         char datetime[CAL_STR_SHORT_LEN32] = {0};
674         snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
675                         st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
676                         st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
677         DBG("get alert to register with given time (%ld) datetime[%s]", utime, datetime);
678
679         GList *l = NULL;
680
681         _cal_server_alarm_get_upcoming_specific_utime(utime, get_all, &l);
682         _cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, get_all, &l);
683         _cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, get_all, &l);
684
685         _cal_server_alarm_get_upcoming_specific_localtime(datetime, get_all, &l);
686         _cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, get_all, &l);
687         _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, get_all, &l);
688
689         *out_l = l;
690 }
691
692 static gint _cal_server_alarm_sort_cb(gconstpointer a, gconstpointer b)
693 {
694         struct _alarm_data_s *p1 = (struct _alarm_data_s *)a;
695         struct _alarm_data_s *p2 = (struct _alarm_data_s *)b;
696         DBG("%lld) > (%lld)", p1->alert_utime, p2->alert_utime);
697
698         return p1->alert_utime < p2->alert_utime ? -1 : 1;
699 }
700
701 static GFunc _cal_server_alarm_print_cb(gpointer data, gpointer user_data)
702 {
703         struct _alarm_data_s *ad = (struct _alarm_data_s *)data;
704         DBG("id(%d) unit(%d) tick(%d) type(%d) time(%lld) datetime[%s]",
705                         ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
706         return 0;
707 }
708
709 static int _cal_server_alarm_register(GList *alarm_list)
710 {
711         CAL_FN_CALL();
712         RETV_IF(NULL == alarm_list, CALENDAR_ERROR_INVALID_PARAMETER);
713
714         int ret = CALENDAR_ERROR_NONE;
715         GList *l = g_list_first(alarm_list);
716         struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
717         RETVM_IF(NULL == ad, CALENDAR_ERROR_DB_FAILED, "No data");
718
719         /* clear all alarm which set by mine. */
720         ret = alarmmgr_enum_alarm_ids(_cal_server_alarm_clear_all_cb, NULL);
721         if (ret != ALARMMGR_RESULT_SUCCESS) {
722                 /* LCOV_EXCL_START */
723                 ERR("alarmmgr_enum_alarm_ids() Fail");
724                 return ret;
725                 /* LCOV_EXCL_STOP */
726         }
727
728         time_t mod_time = (time_t)ad->alert_utime;
729         alarm_entry_t *alarm_info = NULL;
730         alarm_info = alarmmgr_create_alarm();
731         if (NULL == alarm_info) {
732                 /* LCOV_EXCL_START */
733                 ERR("Failed to create alarm");
734                 return CALENDAR_ERROR_DB_FAILED;
735                 /* LCOV_EXCL_STOP */
736         }
737         tzset();
738         struct tm st_alarm = {0};
739
740         switch (ad->system_type) {
741         case CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR:
742                 gmtime_r(&mod_time, &st_alarm);
743                 break;
744
745         default:
746                 tzset();
747                 localtime_r(&mod_time, &st_alarm);
748                 break;
749         }
750
751         alarm_date_t date = {0};
752         date.year = st_alarm.tm_year + 1900;
753         date.month = st_alarm.tm_mon + 1;
754         date.day = st_alarm.tm_mday;
755         date.hour = st_alarm.tm_hour;
756         date.min = st_alarm.tm_min;
757         date.sec = st_alarm.tm_sec;
758         alarmmgr_set_time(alarm_info, date);
759         DBG(COLOR_CYAN" >>> registered record id (%d) at %04d/%02d/%02d %02d:%02d:%02d "COLOR_END" (utime(%lld), datetime[%s], tick(%d) unit(%d))",
760                         ad->event_id, date.year, date.month, date.day, date.hour, date.min, date.sec,
761                         ad->time, ad->datetime, ad->tick, ad->unit);
762
763         int alarm_id = 0;
764         ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
765         if (ret < 0) {
766                 /* LCOV_EXCL_START */
767                 ERR("alarmmgr_add_alarm_with_localtime Fail (%d)", ret);
768                 alarmmgr_free_alarm(alarm_info);
769                 return ret;
770                 /* LCOV_EXCL_STOP */
771         }
772         DBG("alarmmgr id (%d)", alarm_id);
773         _cal_server_alarm_update_alarm_id(alarm_id, ad->event_id, ad->tick, ad->unit);
774         alarmmgr_free_alarm(alarm_info);
775         return CALENDAR_ERROR_NONE;
776 }
777
778 struct alarm_ud {
779         GList *alarm_list;
780 };
781
782 static bool __app_matched_cb(app_control_h app_control, const char *package, void *user_data)
783 {
784         CAL_FN_CALL();
785
786         int ret = 0;
787         int i;
788
789         RETV_IF(NULL == user_data, true);
790
791         char *mime = NULL;
792         ret = app_control_get_mime(app_control, &mime);
793         RETVM_IF(APP_CONTROL_ERROR_NONE != ret, true, "app_control_get_mime() Fail(%d)", ret);
794
795         const char *reminder_mime = "application/x-tizen.calendar.reminder";
796         if (strncmp(mime, reminder_mime, strlen(reminder_mime))) { /* not same */
797                 DBG("get mime[%s] is not [%s]", mime, reminder_mime);
798                 free(mime);
799                 return true;
800         }
801         free(mime);
802
803         struct alarm_ud *au = (struct alarm_ud *)user_data;
804         GList *alarm_list = au->alarm_list;
805         if (NULL == alarm_list) {
806                 /* LCOV_EXCL_START */
807                 ERR("No list");
808                 return true;
809                 /* LCOV_EXCL_STOP */
810         }
811         int len = 0;
812         len = g_list_length(alarm_list);
813         if (0 == len) {
814                 DBG("len is 0, no alarm list");
815                 return true;
816         }
817
818         app_control_h ac = NULL;
819         ret = app_control_create(&ac);
820         if (APP_CONTROL_ERROR_NONE != ret) {
821                 /* LCOV_EXCL_START */
822                 ERR("app_control_create() Fail(%d)", ret);
823                 return true;
824                 /* LCOV_EXCL_STOP */
825         }
826         ret = app_control_set_operation(ac,  APP_CONTROL_OPERATION_DEFAULT);
827         if (APP_CONTROL_ERROR_NONE != ret) {
828                 /* LCOV_EXCL_START */
829                 ERR("app_control_create() Fail(%d)", ret);
830                 app_control_destroy(ac);
831                 return true;
832                 /* LCOV_EXCL_STOP */
833         }
834         ret = app_control_set_app_id(ac, package);
835         if (APP_CONTROL_ERROR_NONE != ret) {
836                 /* LCOV_EXCL_START */
837                 ERR("app_control_set_app_id() Fail(%d)", ret);
838                 app_control_destroy(ac);
839                 return true;
840                 /* LCOV_EXCL_STOP */
841         }
842
843         char **ids = NULL;
844         ids = calloc(len, sizeof(char *));
845         if (NULL == ids) {
846                 /* LCOV_EXCL_START */
847                 ERR("calloc() Fail");
848                 app_control_destroy(ac);
849                 return true;
850                 /* LCOV_EXCL_STOP */
851         }
852         GList *cursor = g_list_first(alarm_list);
853         for (i = 0; i < len; i++) {
854                 struct _alarm_data_s *ad = (struct _alarm_data_s *)cursor->data;
855                 if (NULL == ad) {
856                         WARN("No data");
857                         cursor = g_list_next(cursor);
858                         continue;
859                 }
860                 DBG("pkg[%s] time[%lld] tick[%d] unit[%d] record_type[%d]",
861                                 package, ad->time, ad->tick, ad->unit, ad->record);
862
863                 int slen = 0;
864                 char extra[CAL_STR_MIDDLE_LEN] = {0};
865                 slen = snprintf(extra, sizeof(extra), "%s=%d", "id", ad->event_id);
866                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%lld", "time", ad->time);
867                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "tick", ad->tick);
868                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "unit", ad->unit);
869                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "type", ad->record);
870
871                 /*
872                  * key: id, value: id=4&time=123123&..
873                  */
874                 char buf_id[CAL_STR_MIDDLE_LEN] = {0};
875                 snprintf(buf_id, sizeof(buf_id), "%d", ad->event_id);
876                 app_control_add_extra_data(ac, buf_id, extra);
877                 DBG("value[%s] id[%s]", extra, buf_id);
878
879                 /* append ids */
880                 ids[i] = strdup(buf_id);
881
882                 cursor = g_list_next(cursor);
883         }
884         app_control_add_extra_data_array(ac, "ids", (const char **)ids, len);
885         app_control_send_launch_request(ac, NULL, NULL);
886         app_control_destroy(ac);
887
888         g_list_free_full(alarm_list, free);
889         for (i = 0; i < len; i++) {
890                 free(ids[i]);
891                 ids[i] = NULL;
892         }
893         free(ids);
894
895         return true;
896 }
897
898 static void _cal_server_alarm_noti_with_control(GList *alarm_list)
899 {
900         CAL_FN_CALL();
901
902         int ret = 0;
903         RETM_IF(NULL == alarm_list, "No alarm list");
904
905         app_control_h app_control = NULL;
906         ret = app_control_create(&app_control);
907         if (APP_CONTROL_ERROR_NONE != ret) {
908                 /* LCOV_EXCL_START */
909                 ERR("app_control_create() Fail(%d)", ret);
910                 return;
911                 /* LCOV_EXCL_STOP */
912         }
913         ret = app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW);
914         if (APP_CONTROL_ERROR_NONE != ret) {
915                 /* LCOV_EXCL_START */
916                 ERR("app_control_set_operation() Fail(%d)", ret);
917                 app_control_destroy(app_control);
918                 return;
919                 /* LCOV_EXCL_STOP */
920         }
921         ret = app_control_set_mime(app_control, "application/x-tizen.calendar.reminder");
922         if (APP_CONTROL_ERROR_NONE != ret) {
923                 /* LCOV_EXCL_START */
924                 ERR("app_control_set_mime() Fail(%d)", ret);
925                 app_control_destroy(app_control);
926                 return;
927                 /* LCOV_EXCL_STOP */
928         }
929
930         struct alarm_ud *au = calloc(1, sizeof(struct alarm_ud));
931         if (NULL == au) {
932                 /* LCOV_EXCL_START */
933                 ERR("calloc() Fail");
934                 app_control_destroy(app_control);
935                 return;
936                 /* LCOV_EXCL_STOP */
937         }
938         au->alarm_list = alarm_list;
939         ret = app_control_foreach_app_matched(app_control, __app_matched_cb, au);
940         if (APP_CONTROL_ERROR_NONE != ret) {
941                 /* LCOV_EXCL_START */
942                 ERR("app_control_foreach_app_matched() Fail(%d)", ret);
943                 free(au);
944                 app_control_destroy(app_control);
945                 return;
946                 /* LCOV_EXCL_STOP */
947         }
948         free(au);
949         app_control_destroy(app_control);
950 }
951
952 static void _cal_server_alarm_noti_with_callback(GList *alarm_list)
953 {
954         RETM_IF(NULL == alarm_list, "No alarm list");
955
956         GList *l = g_list_first(alarm_list);
957         while (l) {
958                 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
959                 if (NULL == ad) {
960                         WARN("No data");
961                         l = g_list_next(l);
962                         continue;
963                 }
964                 DBG("callback time[%lld] tick[%d] unit[%d] record_type[%d]",
965                                 ad->time, ad->tick, ad->unit, ad->record);
966
967                 int len = 0;
968                 char extra[CAL_STR_MIDDLE_LEN] = {0};
969                 len = snprintf(extra, sizeof(extra), "%s=%d", "id", ad->event_id);
970                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%lld", "time", ad->time);
971                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "tick", ad->tick);
972                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "unit", ad->unit);
973                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "type", ad->record);
974                 cal_dbus_publish_reminder(len, extra);
975
976                 l = g_list_next(l);
977         }
978 }
979
980 int cal_server_alarm_register_next_alarm(time_t utime)
981 {
982         GList *l = NULL;
983         _cal_server_alarm_get_latest(utime, false, &l);
984         if (NULL == l)
985                 return CALENDAR_ERROR_NONE;
986
987         l = g_list_sort(l, _cal_server_alarm_sort_cb);
988         g_list_foreach(l, (GFunc)_cal_server_alarm_print_cb, NULL);
989         _cal_server_alarm_register(l);
990
991         g_list_free_full(l, free);
992         return CALENDAR_ERROR_NONE;
993 }
994
995 void cal_server_alarm_alert(time_t tt_alert)
996 {
997         GList *l = NULL;
998         _cal_server_alarm_get_latest(tt_alert, true, &l);
999         if (NULL == l)
1000                 return;
1001
1002         _cal_server_alarm_noti_with_callback(l);
1003         _cal_server_alarm_noti_with_control(l);
1004         /* DO NOT FREE LIST, list is freed in callback */
1005 }
1006
1007 static int _alert_cb(alarm_id_t alarm_id, void *data)
1008 {
1009         CAL_FN_CALL();
1010         DBG("alarm_id (%ld)", alarm_id);
1011
1012         time_t tt_alert = 0;
1013         cal_server_alarm_get_alert_time(alarm_id, &tt_alert);
1014         cal_server_alarm_alert(tt_alert);
1015         _cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
1016         cal_server_alarm_register_next_alarm(tt_alert);
1017         return 0;
1018 }
1019
1020 static void _cal_server_alarm_timechange_cb(keynode_t *node, void *data)
1021 {
1022         time_t t = time(NULL);
1023         cal_server_alarm_alert(t);
1024         cal_server_alarm_register_next_alarm(t);
1025 }
1026
1027 void _cal_server_alarm_set_timechange(void)
1028 {
1029         vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
1030                         _cal_server_alarm_timechange_cb, NULL);
1031         vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT,
1032                         _cal_server_alarm_timechange_cb, NULL);
1033         vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT,
1034                         _cal_server_alarm_timechange_cb, NULL);
1035         vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE,
1036                         _cal_server_alarm_timechange_cb, NULL);
1037 }
1038
1039 void _cal_server_alarm_unset_timechange(void)
1040 {
1041         vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
1042                         _cal_server_alarm_timechange_cb);
1043         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT,
1044                         _cal_server_alarm_timechange_cb);
1045         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT,
1046                         _cal_server_alarm_timechange_cb);
1047         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE,
1048                         _cal_server_alarm_timechange_cb);
1049 }
1050
1051 static void _changed_cb(const char* view_uri, void* data)
1052 {
1053         CAL_FN_CALL();
1054         cal_server_alarm_register_next_alarm(time(NULL));
1055 }
1056
1057 static int _cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
1058 {
1059         cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
1060         cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
1061         return 0;
1062 }
1063
1064 static void _cal_server_alarm_unset_inotify(calendar_db_changed_cb callback)
1065 {
1066         cal_inotify_unsubscribe(CAL_NOTI_EVENT_CHANGED, callback, NULL);
1067         cal_inotify_unsubscribe(CAL_NOTI_TODO_CHANGED, callback, NULL);
1068 }
1069
1070 int cal_server_alarm_init(void)
1071 {
1072         CAL_FN_CALL();
1073
1074         int ret = 0;
1075         _cal_server_alarm_set_timechange();
1076         _cal_server_alarm_set_inotify(_changed_cb);
1077
1078         ret = alarmmgr_init("calendar-service");
1079         if (ret < 0) {
1080                 /* LCOV_EXCL_START */
1081                 ERR("alarmmgr_init() Fail(%d)", ret);
1082                 return CALENDAR_ERROR_SYSTEM;
1083                 /* LCOV_EXCL_STOP */
1084         }
1085
1086         ret = alarmmgr_set_cb(_alert_cb, NULL);
1087         if (ret < 0) {
1088                 /* LCOV_EXCL_START */
1089                 ERR("alarmmgr_set_cb() Fail(%d)", ret);
1090                 return CALENDAR_ERROR_SYSTEM;
1091                 /* LCOV_EXCL_STOP */
1092         }
1093
1094         cal_server_alarm_register_next_alarm(time(NULL));
1095         return CALENDAR_ERROR_NONE;
1096 }
1097
1098 void cal_server_alarm_deinit(void)
1099 {
1100         alarmmgr_fini();
1101         _cal_server_alarm_unset_inotify(_changed_cb);
1102         _cal_server_alarm_unset_timechange();
1103
1104 }
1105