modify terminology:calendar->book,allday->localtime,normal->utime,svc->service
[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 _get_event_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_UTIME_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 _get_event_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_LOCALTIME_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 static int64_t _get_todo_alert_utime(const char *field, int id, time_t now_t)
205 {
206         int ret = 0;
207         char query[CAL_DB_SQL_MAX_LEN] = {0};
208         snprintf(query, sizeof(query), "SELECT %s FROM "CAL_TABLE_SCHEDULE" "
209                         "WHERE id=%d AND %s>%ld ORDER BY %s LIMIT 1", field, id, field, now_t, field);
210
211         sqlite3_stmt *stmt = NULL;
212         ret = cal_db_util_query_prepare(query, &stmt);
213         if (CALENDAR_ERROR_NONE != ret) {
214                 /* LCOV_EXCL_START */
215                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
216                 SECURE("query[%s]", query);
217                 return ret;
218                 /* LCOV_EXCL_STOP */
219         }
220
221         int64_t utime = 0;
222         ret = cal_db_util_stmt_step(stmt);
223         switch (ret) {
224         case CAL_SQLITE_ROW:
225                 utime = (int64_t)sqlite3_column_int64(stmt, 0);
226                 break;
227                 /* LCOV_EXCL_START */
228         case SQLITE_DONE:
229                 ERR("No data");
230                 break;
231         default:
232                 ERR("Invalid return(%d)", ret);
233                 break;
234                 /* LCOV_EXCL_STOP */
235         }
236
237         sqlite3_finalize(stmt);
238         return utime;
239 }
240
241 static int _get_todo_alert_localtime(const char *field, int event_id, time_t current)
242 {
243         int ret = 0;
244         char query[CAL_DB_SQL_MAX_LEN] = {0};
245         struct tm st = {0};
246         tzset();
247         localtime_r(&current, &st);
248         time_t mod_current = timegm(&st);
249         snprintf(query, sizeof(query), "SELECT %s FROM %s "
250                         "WHERE id=%d AND strftime('%%s', %s)>%ld ORDER BY %s LIMIT 1",
251                         field, CAL_TABLE_SCHEDULE, event_id, field, mod_current, field);
252
253         sqlite3_stmt *stmt = NULL;
254         ret = cal_db_util_query_prepare(query, &stmt);
255         if (CALENDAR_ERROR_NONE != ret) {
256                 /* LCOV_EXCL_START */
257                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
258                 SECURE("query[%s]", query);
259                 return ret;
260                 /* LCOV_EXCL_STOP */
261         }
262
263         const char *datetime = NULL;
264         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
265                 datetime = (const char *)sqlite3_column_text(stmt, 0);
266
267         if (NULL == datetime || '\0' == *datetime) {
268                 /* LCOV_EXCL_START */
269                 ERR("Invalid datetime [%s]", datetime);
270                 sqlite3_finalize(stmt);
271                 return 0;
272                 /* LCOV_EXCL_STOP */
273         }
274
275         int y = 0, m = 0, d = 0;
276         int h = 0, n = 0, s = 0;
277         sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
278         sqlite3_finalize(stmt);
279
280         st.tm_year = y - 1900;
281         st.tm_mon = m - 1;
282         st.tm_mday = d;
283         st.tm_hour = h;
284         st.tm_min = n;
285         st.tm_sec = s;
286
287         return (long long int)mktime(&st);
288 }
289 /*
290  * to get aler time, time(NULL) is not accurate. 1 secs diff could be occured.
291  * so, searching DB is neccessary to find alert time.
292  */
293 int cal_server_alarm_get_alert_time(int alarm_id, time_t *tt_alert)
294 {
295         int ret = 0;
296         RETV_IF(NULL == tt_alert, CALENDAR_ERROR_INVALID_PARAMETER);
297
298         char query[CAL_DB_SQL_MAX_LEN] = {0};
299         snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
300                         "A.alarm_type, A.alarm_utime, A.alarm_datetime, B.type, B.dtstart_type, "
301                         "B.dtend_type FROM %s as A, %s as B ON A.event_id =B.id WHERE alarm_id =%d ",
302                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE, alarm_id);
303
304         sqlite3_stmt *stmt = NULL;
305         ret = cal_db_util_query_prepare(query, &stmt);
306         if (CALENDAR_ERROR_NONE != ret) {
307                 /* LCOV_EXCL_START */
308                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
309                 SECURE("query[%s]", query);
310                 return ret;
311                 /* LCOV_EXCL_STOP */
312         }
313
314         int event_id = 0;
315         int unit = 0;
316         int tick = 0;
317         int type = 0;
318         long long int utime = 0;
319         const char *datetime = NULL;
320         int record_type = 0;
321         int dtstart_type = 0;
322         int dtend_type = 0;
323         struct tm st = {0};
324
325         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
326                 event_id = sqlite3_column_int(stmt, 0);
327                 unit = sqlite3_column_int(stmt, 1);
328                 tick = sqlite3_column_int(stmt, 2);
329                 type = sqlite3_column_int(stmt, 3);
330                 utime = sqlite3_column_int64(stmt, 4);
331                 datetime = (const char *)sqlite3_column_text(stmt, 5);
332                 record_type = sqlite3_column_int(stmt, 6);
333                 dtstart_type = sqlite3_column_int(stmt, 7);
334                 dtend_type = sqlite3_column_int(stmt, 8);
335         }
336
337         if (NULL == tt_alert) {
338                 /* LCOV_EXCL_START */
339                 ERR("Invalid parameter: tt_alert is NULL");
340                 sqlite3_finalize(stmt);
341                 return CALENDAR_ERROR_INVALID_PARAMETER;
342                 /* LCOV_EXCL_STOP */
343         }
344
345         if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
346                 if (CALENDAR_TIME_UTIME == type) {
347                         *tt_alert = utime;
348                 } else {
349                         int y = 0, m = 0, d = 0;
350                         int h = 0, n = 0, s = 0;
351                         if (datetime) {
352                                 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
353
354                                 st.tm_year = y - 1900;
355                                 st.tm_mon = m - 1;
356                                 st.tm_mday = d;
357                                 st.tm_hour = h;
358                                 st.tm_min = n;
359                                 st.tm_sec = s;
360                                 *tt_alert = mktime(&st);
361                                 DBG("datetime[%s] to %02d:%02d:%02d (%d)", datetime, h, n, s, *tt_alert);
362                         }
363                 }
364                 sqlite3_finalize(stmt);
365                 return CALENDAR_ERROR_NONE;
366         }
367         sqlite3_finalize(stmt);
368
369         time_t current = time(NULL);
370         current += (tick * unit);
371         current -= 2; /* in case time passed */
372
373         switch (record_type) {
374         case CALENDAR_BOOK_TYPE_EVENT:
375                 switch (dtstart_type) {
376                 case CALENDAR_TIME_UTIME:
377                         utime = _get_event_alert_utime("dtstart_utime", event_id, current);
378                         break;
379
380                 case CALENDAR_TIME_LOCALTIME:
381                         utime = _get_event_alert_localtime("dtstart_datetime", event_id, current);
382                         break;
383                 }
384                 break;
385
386         case CALENDAR_BOOK_TYPE_TODO:
387                 switch (dtend_type) {
388                 case CALENDAR_TIME_UTIME:
389                         utime = _get_todo_alert_utime("dtend_utime", event_id, current);
390                         break;
391
392                 case CALENDAR_TIME_LOCALTIME:
393                         utime = _get_todo_alert_localtime("dtend_datetime", event_id, current);
394                         break;
395                 }
396                 break;
397         }
398         DBG("alert_time(%d) = utime(%lld) - (tick(%d) * unit(%d))", *tt_alert, utime, tick, unit);
399
400         *tt_alert = utime - (tick * unit);
401         return CALENDAR_ERROR_NONE;
402 }
403
404 /*
405  * bool get_all is
406  * true : to get all alarms including same time event.
407  * (ig. if 3 diffrent alarms exist at 06:30, list has 3 data)
408  * false : to get only one alarm to register in alarm-manager.
409  * (ig. if 3 diffrent alarms exist at 06:30, list has only one)
410  */
411 static void _cal_server_alarm_get_upcoming_specific_utime(time_t utime, bool get_all, GList **l)
412 {
413         int ret = 0;
414         char query[CAL_DB_SQL_MAX_LEN] = {0};
415         snprintf(query, sizeof(query), "SELECT event_id,remind_tick_unit,remind_tick,"
416                         "alarm_type,alarm_utime,alarm_datetime "
417                         "FROM %s WHERE remind_tick_unit =%d AND alarm_type =%d AND alarm_utime %s %ld %s",
418                         CAL_TABLE_ALARM, CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
419                         true == get_all ? "=" : ">", utime,
420                         true == get_all ? "" : "ORDER BY alarm_utime ASC LIMIT 1");
421
422         sqlite3_stmt *stmt = NULL;
423         ret = cal_db_util_query_prepare(query, &stmt);
424         if (CALENDAR_ERROR_NONE != ret) {
425                 /* LCOV_EXCL_START */
426                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
427                 SECURE("query[%s]", query);
428                 return;
429                 /* LCOV_EXCL_STOP */
430         }
431
432         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
433                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
434                 if (NULL == ad) {
435                         /* LCOV_EXCL_START */
436                         ERR("calloc() Fail");
437                         sqlite3_finalize(stmt);
438                         return;
439                         /* LCOV_EXCL_STOP */
440                 }
441
442                 ad->event_id = sqlite3_column_int(stmt, 0);
443                 ad->unit = sqlite3_column_int(stmt, 1);
444                 ad->tick = sqlite3_column_int(stmt, 2);
445                 ad->type = sqlite3_column_int(stmt, 3);
446                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
447                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
448                 *l = g_list_append(*l, ad);
449                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
450                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
451                 ad->alert_utime = ad->time;
452                 if (false == get_all) break;
453         }
454         sqlite3_finalize(stmt);
455 }
456
457 static void _cal_server_alarm_get_upcoming_specific_localtime(const char *datetime, bool get_all, GList **l)
458 {
459         int ret = 0;
460         char query[CAL_DB_SQL_MAX_LEN] = {0};
461         snprintf(query, sizeof(query), "SELECT event_id,remind_tick_unit,remind_tick,"
462                         "alarm_type,alarm_utime,alarm_datetime "
463                         "FROM %s WHERE remind_tick_unit=%d AND alarm_type=%d AND alarm_datetime %s '%s' %s",
464                         CAL_TABLE_ALARM, CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
465                         true == get_all ? "=" : ">", datetime,
466                         true == get_all ? "" : "ORDER BY alarm_datetime ASC LIMIT 1");
467
468         sqlite3_stmt *stmt = NULL;
469         ret = cal_db_util_query_prepare(query, &stmt);
470         if (CALENDAR_ERROR_NONE != ret) {
471                 /* LCOV_EXCL_START */
472                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
473                 SECURE("query[%s]", query);
474                 return;
475                 /* LCOV_EXCL_STOP */
476         }
477
478         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
479                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
480                 if (NULL == ad) {
481                         /* LCOV_EXCL_START */
482                         ERR("calloc() Fail");
483                         sqlite3_finalize(stmt);
484                         return;
485                         /* LCOV_EXCL_STOP */
486                 }
487
488                 ad->event_id = sqlite3_column_int(stmt, 0);
489                 ad->unit = sqlite3_column_int(stmt, 1);
490                 ad->tick = sqlite3_column_int(stmt, 2);
491                 ad->type = sqlite3_column_int(stmt, 3);
492                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
493                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
494                 *l = g_list_append(*l, ad);
495                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
496                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
497
498                 int y = 0, m = 0, d = 0;
499                 int h = 0, n = 0, s = 0;
500                 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
501
502                 struct tm st = {0};
503                 st.tm_year = y - 1900;
504                 st.tm_mon = m -1;
505                 st.tm_mday = d;
506                 st.tm_hour = h;
507                 st.tm_min = n;
508                 st.tm_sec = s;
509                 ad->alert_utime = (long long int)mktime(&st);
510                 if (false == get_all) break;
511         }
512         sqlite3_finalize(stmt);
513 }
514
515 static void _cal_server_alarm_get_upcoming_nonspecific_event_utime(time_t utime, bool get_all, GList **l)
516 {
517         int ret = 0;
518         /*
519          * A:alarm
520          * B:utime
521          */
522         char query[CAL_DB_SQL_MAX_LEN] = {0};
523         snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
524                         "A.alarm_type,B.dtstart_utime,A.alarm_datetime "
525                         "FROM %s as A, %s as B ON A.event_id = B.event_id "
526                         "WHERE A.remind_tick_unit >%d AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
527                         CAL_TABLE_ALARM, CAL_TABLE_UTIME_INSTANCE, CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
528                         true == get_all ? "=" : ">", utime,
529                         true == get_all ? "" : "ORDER BY (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1");
530
531         sqlite3_stmt *stmt = NULL;
532         ret = cal_db_util_query_prepare(query, &stmt);
533         if (CALENDAR_ERROR_NONE != ret) {
534                 /* LCOV_EXCL_START */
535                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
536                 SECURE("query[%s]", query);
537                 return;
538                 /* LCOV_EXCL_STOP */
539         }
540
541         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
542                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
543                 if (NULL == ad) {
544                         /* LCOV_EXCL_START */
545                         ERR("calloc() Fail");
546                         sqlite3_finalize(stmt);
547                         return;
548                         /* LCOV_EXCL_STOP */
549                 }
550
551                 ad->event_id = sqlite3_column_int(stmt, 0);
552                 ad->unit = sqlite3_column_int(stmt, 1);
553                 ad->tick = sqlite3_column_int(stmt, 2);
554                 ad->type = sqlite3_column_int(stmt, 3);
555                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
556                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
557                 *l = g_list_append(*l, ad);
558                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
559                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
560
561                 ad->alert_utime = ad->time - (ad->tick * ad->unit);
562                 if (false == get_all) break;
563         }
564         sqlite3_finalize(stmt);
565 }
566
567 static void _cal_server_alarm_get_upcoming_nonspecific_event_localtime(const char *datetime, bool get_all, GList **l)
568 {
569         int ret = 0;
570         /*
571          * A:alarm
572          * B:localtime
573          */
574         char query[CAL_DB_SQL_MAX_LEN] = {0};
575         snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
576                         "A.alarm_type,A.alarm_utime,B.dtstart_datetime "
577                         "FROM %s as A, %s as B ON A.event_id = B.event_id "
578                         "WHERE A.remind_tick_unit >%d AND "
579                         "(strftime('%%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
580                         CAL_TABLE_ALARM, CAL_TABLE_LOCALTIME_INSTANCE, CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
581                         datetime, true == get_all ? "=" : ">",
582                         true == get_all ? "" : "ORDER BY (strftime('%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
583         sqlite3_stmt *stmt = NULL;
584         ret = cal_db_util_query_prepare(query, &stmt);
585         if (CALENDAR_ERROR_NONE != ret) {
586                 /* LCOV_EXCL_START */
587                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
588                 SECURE("query[%s]", query);
589                 return;
590                 /* LCOV_EXCL_STOP */
591         }
592
593         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
594                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
595                 if (NULL == ad) {
596                         /* LCOV_EXCL_START */
597                         ERR("calloc() Fail");
598                         sqlite3_finalize(stmt);
599                         return;
600                         /* LCOV_EXCL_STOP */
601                 }
602
603                 ad->event_id = sqlite3_column_int(stmt, 0);
604                 ad->unit = sqlite3_column_int(stmt, 1);
605                 ad->tick = sqlite3_column_int(stmt, 2);
606                 ad->type = sqlite3_column_int(stmt, 3);
607                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
608                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
609                 *l = g_list_append(*l, ad);
610                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
611                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
612
613                 int y = 0, m = 0, d = 0;
614                 int h = 0, n = 0, s = 0;
615                 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
616
617                 struct tm st = {0};
618                 st.tm_year = y - 1900;
619                 st.tm_mon = m -1;
620                 st.tm_mday = d;
621                 st.tm_hour = h;
622                 st.tm_min = n;
623                 st.tm_sec = s;
624                 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
625                 if (false == get_all) break;
626         }
627         sqlite3_finalize(stmt);
628 }
629
630 static void _cal_server_alarm_get_upcoming_nonspecific_todo_utime(time_t utime, bool get_all, GList **l)
631 {
632         int ret = 0;
633         /*
634          * A:alarm
635          * B:todo(utime)
636          */
637         char query[CAL_DB_SQL_MAX_LEN] = {0};
638         snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
639                         "A.alarm_type,B.dtend_utime,A.alarm_datetime "
640                         "FROM %s as A, %s as B ON A.event_id = B.id "
641                         "WHERE A.remind_tick_unit >%d AND B.type =%d "
642                         "AND (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
643                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
644                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
645                         true == get_all ? "=" : ">", utime,
646                         true == get_all ? "" : "ORDER BY (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
647
648         sqlite3_stmt *stmt = NULL;
649         ret = cal_db_util_query_prepare(query, &stmt);
650         if (CALENDAR_ERROR_NONE != ret) {
651                 /* LCOV_EXCL_START */
652                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
653                 SECURE("query[%s]", query);
654                 return;
655                 /* LCOV_EXCL_STOP */
656         }
657
658         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
659                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
660                 if (NULL == ad) {
661                         /* LCOV_EXCL_START */
662                         ERR("calloc() Fail");
663                         sqlite3_finalize(stmt);
664                         return;
665                         /* LCOV_EXCL_STOP */
666                 }
667
668                 ad->event_id = sqlite3_column_int(stmt, 0);
669                 ad->unit = sqlite3_column_int(stmt, 1);
670                 ad->tick = sqlite3_column_int(stmt, 2);
671                 ad->type = sqlite3_column_int(stmt, 3);
672                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
673                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
674                 *l = g_list_append(*l, ad);
675                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
676                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
677
678                 ad->alert_utime = ad->time - (ad->tick * ad->unit);
679                 if (false == get_all) break;
680         }
681         sqlite3_finalize(stmt);
682 }
683
684 static void _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(const char *datetime, bool get_all, GList **l)
685 {
686         int ret = 0;
687         /*
688          * A:alarm
689          * B:todo(localtime)
690          */
691         char query[CAL_DB_SQL_MAX_LEN] = {0};
692         snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
693                         "A.alarm_type,A.alarm_utime,B.dtend_datetime "
694                         "FROM %s as A, %s as B ON A.event_id = B.id "
695                         "WHERE A.remind_tick_unit >%d AND B.type =%d "
696                         "AND (strftime('%%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
697                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
698                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
699                         datetime, true == get_all ? "=" : ">",
700                         true == get_all ? "" : "ORDER BY (strftime('%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
701
702         sqlite3_stmt *stmt = NULL;
703         ret = cal_db_util_query_prepare(query, &stmt);
704         if (CALENDAR_ERROR_NONE != ret) {
705                 /* LCOV_EXCL_START */
706                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
707                 SECURE("query[%s]", query);
708                 return;
709                 /* LCOV_EXCL_STOP */
710         }
711
712         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
713                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
714                 if (NULL == ad) {
715                         /* LCOV_EXCL_START */
716                         ERR("calloc() Fail");
717                         sqlite3_finalize(stmt);
718                         return;
719                         /* LCOV_EXCL_STOP */
720                 }
721
722                 ad->event_id = sqlite3_column_int(stmt, 0);
723                 ad->unit = sqlite3_column_int(stmt, 1);
724                 ad->tick = sqlite3_column_int(stmt, 2);
725                 ad->type = sqlite3_column_int(stmt, 3);
726                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
727                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
728                 *l = g_list_append(*l, ad);
729                 DBG("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
730                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
731
732                 int y = 0, m = 0, d = 0;
733                 int h = 0, n = 0, s = 0;
734                 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
735
736                 struct tm st = {0};
737                 st.tm_year = y - 1900;
738                 st.tm_mon = m -1;
739                 st.tm_mday = d;
740                 st.tm_hour = h;
741                 st.tm_min = n;
742                 st.tm_sec = s;
743                 ad->alert_utime = (long long int)mktime(&st) - (ad->tick * ad->unit);
744                 if (false == get_all) break;
745         }
746         sqlite3_finalize(stmt);
747 }
748
749 static void _cal_server_alarm_get_latest(time_t utime, bool get_all, GList **out_l)
750 {
751         CAL_FN_CALL();
752         RET_IF(NULL == out_l);
753
754         tzset();
755         struct tm st_local = {0};
756         localtime_r(&utime, &st_local);
757
758         char datetime[CAL_STR_SHORT_LEN32] = {0};
759         snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
760                         st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
761                         st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
762         DBG("get alert to register with given time (%ld) datetime[%s]", utime, datetime);
763
764         GList *l = NULL;
765
766         _cal_server_alarm_get_upcoming_specific_utime(utime, get_all, &l);
767         _cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, get_all, &l);
768         _cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, get_all, &l);
769
770         _cal_server_alarm_get_upcoming_specific_localtime(datetime, get_all, &l);
771         _cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, get_all, &l);
772         _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, get_all, &l);
773
774         *out_l = l;
775 }
776
777 static gint _cal_server_alarm_sort_cb(gconstpointer a, gconstpointer b)
778 {
779         struct _alarm_data_s *p1 = (struct _alarm_data_s *)a;
780         struct _alarm_data_s *p2 = (struct _alarm_data_s *)b;
781         DBG("%lld) > (%lld)", p1->alert_utime, p2->alert_utime);
782
783         return p1->alert_utime < p2->alert_utime ? -1 : 1;
784 }
785
786 static GFunc _cal_server_alarm_print_cb(gpointer data, gpointer user_data)
787 {
788         struct _alarm_data_s *ad = (struct _alarm_data_s *)data;
789         DBG("id(%d) unit(%d) tick(%d) type(%d) time(%lld) datetime[%s]",
790                         ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
791         return 0;
792 }
793
794 static int _cal_server_alarm_register(GList *alarm_list)
795 {
796         CAL_FN_CALL();
797         RETV_IF(NULL == alarm_list, CALENDAR_ERROR_INVALID_PARAMETER);
798
799         int ret = CALENDAR_ERROR_NONE;
800         GList *l = g_list_first(alarm_list);
801         struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
802         RETVM_IF(NULL == ad, CALENDAR_ERROR_DB_FAILED, "No data");
803
804         /* clear all alarm which set by mine. */
805         ret = alarmmgr_enum_alarm_ids(_cal_server_alarm_clear_all_cb, NULL);
806         if (ret != ALARMMGR_RESULT_SUCCESS) {
807                 /* LCOV_EXCL_START */
808                 ERR("alarmmgr_enum_alarm_ids() Fail");
809                 return ret;
810                 /* LCOV_EXCL_STOP */
811         }
812
813         time_t mod_time = (time_t)ad->alert_utime;
814         alarm_entry_t *alarm_info = NULL;
815         alarm_info = alarmmgr_create_alarm();
816         if (NULL == alarm_info) {
817                 /* LCOV_EXCL_START */
818                 ERR("Failed to create alarm");
819                 return CALENDAR_ERROR_DB_FAILED;
820                 /* LCOV_EXCL_STOP */
821         }
822         tzset();
823         struct tm st_alarm = {0};
824
825         switch (ad->system_type) {
826         case CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR:
827                 gmtime_r(&mod_time, &st_alarm);
828                 break;
829
830         default:
831                 tzset();
832                 localtime_r(&mod_time, &st_alarm);
833                 break;
834         }
835
836         alarm_date_t date = {0};
837         date.year = st_alarm.tm_year + 1900;
838         date.month = st_alarm.tm_mon + 1;
839         date.day = st_alarm.tm_mday;
840         date.hour = st_alarm.tm_hour;
841         date.min = st_alarm.tm_min;
842         date.sec = st_alarm.tm_sec;
843         alarmmgr_set_time(alarm_info, date);
844         DBG(COLOR_CYAN" >>> registered record id (%d) at %04d/%02d/%02d %02d:%02d:%02d "COLOR_END" (utime(%lld), datetime[%s], tick(%d) unit(%d))",
845                         ad->event_id, date.year, date.month, date.day, date.hour, date.min, date.sec,
846                         ad->time, ad->datetime, ad->tick, ad->unit);
847
848         int alarm_id = 0;
849         ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
850         if (ret < 0) {
851                 /* LCOV_EXCL_START */
852                 ERR("alarmmgr_add_alarm_with_localtime Fail (%d)", ret);
853                 alarmmgr_free_alarm(alarm_info);
854                 return ret;
855                 /* LCOV_EXCL_STOP */
856         }
857         DBG("alarmmgr id (%d)", alarm_id);
858         _cal_server_alarm_update_alarm_id(alarm_id, ad->event_id, ad->tick, ad->unit);
859         alarmmgr_free_alarm(alarm_info);
860         return CALENDAR_ERROR_NONE;
861 }
862
863 struct alarm_ud {
864         GList *alarm_list;
865 };
866
867 static bool __app_matched_cb(app_control_h app_control, const char *package, void *user_data)
868 {
869         CAL_FN_CALL();
870
871         int ret = 0;
872         int i;
873
874         RETV_IF(NULL == user_data, true);
875
876         char *mime = NULL;
877         ret = app_control_get_mime(app_control, &mime);
878         RETVM_IF(APP_CONTROL_ERROR_NONE != ret, true, "app_control_get_mime() Fail(%d)", ret);
879
880         const char *reminder_mime = "application/x-tizen.calendar.reminder";
881         if (strncmp(mime, reminder_mime, strlen(reminder_mime))) { /* not same */
882                 DBG("get mime[%s] is not [%s]", mime, reminder_mime);
883                 free(mime);
884                 return true;
885         }
886         free(mime);
887
888         struct alarm_ud *au = (struct alarm_ud *)user_data;
889         GList *alarm_list = au->alarm_list;
890         if (NULL == alarm_list) {
891                 /* LCOV_EXCL_START */
892                 ERR("No list");
893                 return true;
894                 /* LCOV_EXCL_STOP */
895         }
896         int len = 0;
897         len = g_list_length(alarm_list);
898         if (0 == len) {
899                 DBG("len is 0, no alarm list");
900                 return true;
901         }
902
903         app_control_h ac = NULL;
904         ret = app_control_create(&ac);
905         if (APP_CONTROL_ERROR_NONE != ret) {
906                 /* LCOV_EXCL_START */
907                 ERR("app_control_create() Fail(%d)", ret);
908                 return true;
909                 /* LCOV_EXCL_STOP */
910         }
911         ret = app_control_set_operation(ac,  APP_CONTROL_OPERATION_DEFAULT);
912         if (APP_CONTROL_ERROR_NONE != ret) {
913                 /* LCOV_EXCL_START */
914                 ERR("app_control_create() Fail(%d)", ret);
915                 app_control_destroy(ac);
916                 return true;
917                 /* LCOV_EXCL_STOP */
918         }
919         ret = app_control_set_app_id(ac, package);
920         if (APP_CONTROL_ERROR_NONE != ret) {
921                 /* LCOV_EXCL_START */
922                 ERR("app_control_set_app_id() Fail(%d)", ret);
923                 app_control_destroy(ac);
924                 return true;
925                 /* LCOV_EXCL_STOP */
926         }
927
928         char **ids = NULL;
929         ids = calloc(len, sizeof(char *));
930         if (NULL == ids) {
931                 /* LCOV_EXCL_START */
932                 ERR("calloc() Fail");
933                 app_control_destroy(ac);
934                 return true;
935                 /* LCOV_EXCL_STOP */
936         }
937         GList *cursor = g_list_first(alarm_list);
938         for (i = 0; i < len; i++) {
939                 struct _alarm_data_s *ad = (struct _alarm_data_s *)cursor->data;
940                 if (NULL == ad) {
941                         WARN("No data");
942                         cursor = g_list_next(cursor);
943                         continue;
944                 }
945                 DBG("pkg[%s] time[%lld] tick[%d] unit[%d] record_type[%d]",
946                                 package, ad->time, ad->tick, ad->unit, ad->record);
947
948                 int slen = 0;
949                 char extra[CAL_STR_MIDDLE_LEN] = {0};
950                 slen = snprintf(extra, sizeof(extra), "%s=%d", "id", ad->event_id);
951                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%lld", "time", ad->time);
952                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "tick", ad->tick);
953                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "unit", ad->unit);
954                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "type", ad->record);
955
956                 /*
957                  * key: id, value: id=4&time=123123&..
958                  */
959                 char buf_id[CAL_STR_MIDDLE_LEN] = {0};
960                 snprintf(buf_id, sizeof(buf_id), "%d", ad->event_id);
961                 app_control_add_extra_data(ac, buf_id, extra);
962                 DBG("value[%s] id[%s]", extra, buf_id);
963
964                 /* append ids */
965                 ids[i] = strdup(buf_id);
966
967                 cursor = g_list_next(cursor);
968         }
969         app_control_add_extra_data_array(ac, "ids", (const char **)ids, len);
970         app_control_send_launch_request(ac, NULL, NULL);
971         app_control_destroy(ac);
972
973         g_list_free_full(alarm_list, free);
974         for (i = 0; i < len; i++) {
975                 free(ids[i]);
976                 ids[i] = NULL;
977         }
978         free(ids);
979
980         return true;
981 }
982
983 static void _cal_server_alarm_noti_with_control(GList *alarm_list)
984 {
985         CAL_FN_CALL();
986
987         int ret = 0;
988         RETM_IF(NULL == alarm_list, "No alarm list");
989
990         app_control_h app_control = NULL;
991         ret = app_control_create(&app_control);
992         if (APP_CONTROL_ERROR_NONE != ret) {
993                 /* LCOV_EXCL_START */
994                 ERR("app_control_create() Fail(%d)", ret);
995                 return;
996                 /* LCOV_EXCL_STOP */
997         }
998         ret = app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW);
999         if (APP_CONTROL_ERROR_NONE != ret) {
1000                 /* LCOV_EXCL_START */
1001                 ERR("app_control_set_operation() Fail(%d)", ret);
1002                 app_control_destroy(app_control);
1003                 return;
1004                 /* LCOV_EXCL_STOP */
1005         }
1006         ret = app_control_set_mime(app_control, "application/x-tizen.calendar.reminder");
1007         if (APP_CONTROL_ERROR_NONE != ret) {
1008                 /* LCOV_EXCL_START */
1009                 ERR("app_control_set_mime() Fail(%d)", ret);
1010                 app_control_destroy(app_control);
1011                 return;
1012                 /* LCOV_EXCL_STOP */
1013         }
1014
1015         struct alarm_ud *au = calloc(1, sizeof(struct alarm_ud));
1016         if (NULL == au) {
1017                 /* LCOV_EXCL_START */
1018                 ERR("calloc() Fail");
1019                 app_control_destroy(app_control);
1020                 return;
1021                 /* LCOV_EXCL_STOP */
1022         }
1023         au->alarm_list = alarm_list;
1024         ret = app_control_foreach_app_matched(app_control, __app_matched_cb, au);
1025         if (APP_CONTROL_ERROR_NONE != ret) {
1026                 /* LCOV_EXCL_START */
1027                 ERR("app_control_foreach_app_matched() Fail(%d)", ret);
1028                 free(au);
1029                 app_control_destroy(app_control);
1030                 return;
1031                 /* LCOV_EXCL_STOP */
1032         }
1033         free(au);
1034         app_control_destroy(app_control);
1035 }
1036
1037 static void _cal_server_alarm_noti_with_callback(GList *alarm_list)
1038 {
1039         RETM_IF(NULL == alarm_list, "No alarm list");
1040
1041         GList *l = g_list_first(alarm_list);
1042         while (l) {
1043                 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
1044                 if (NULL == ad) {
1045                         WARN("No data");
1046                         l = g_list_next(l);
1047                         continue;
1048                 }
1049                 DBG("callback time[%lld] tick[%d] unit[%d] record_type[%d]",
1050                                 ad->time, ad->tick, ad->unit, ad->record);
1051
1052                 int len = 0;
1053                 char extra[CAL_STR_MIDDLE_LEN] = {0};
1054                 len = snprintf(extra, sizeof(extra), "%s=%d", "id", ad->event_id);
1055                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%lld", "time", ad->time);
1056                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "tick", ad->tick);
1057                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "unit", ad->unit);
1058                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "type", ad->record);
1059                 cal_dbus_publish_reminder(len, extra);
1060
1061                 l = g_list_next(l);
1062         }
1063 }
1064
1065 int cal_server_alarm_register_next_alarm(time_t utime)
1066 {
1067         GList *l = NULL;
1068         _cal_server_alarm_get_latest(utime, false, &l);
1069         if (NULL == l)
1070                 return CALENDAR_ERROR_NONE;
1071
1072         l = g_list_sort(l, _cal_server_alarm_sort_cb);
1073         g_list_foreach(l, (GFunc)_cal_server_alarm_print_cb, NULL);
1074         _cal_server_alarm_register(l);
1075
1076         g_list_free_full(l, free);
1077         return CALENDAR_ERROR_NONE;
1078 }
1079
1080 void cal_server_alarm_alert(time_t tt_alert)
1081 {
1082         GList *l = NULL;
1083         _cal_server_alarm_get_latest(tt_alert, true, &l);
1084         if (NULL == l)
1085                 return;
1086
1087         _cal_server_alarm_noti_with_callback(l);
1088         _cal_server_alarm_noti_with_control(l);
1089         /* DO NOT FREE LIST, list is freed in callback */
1090 }
1091
1092 static int _alert_cb(alarm_id_t alarm_id, void *data)
1093 {
1094         CAL_FN_CALL();
1095         DBG("alarm_id (%ld)", alarm_id);
1096
1097         time_t tt_alert = 0;
1098         cal_server_alarm_get_alert_time(alarm_id, &tt_alert);
1099         cal_server_alarm_alert(tt_alert);
1100         _cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
1101         cal_server_alarm_register_next_alarm(tt_alert);
1102         return 0;
1103 }
1104
1105 static void _cal_server_alarm_timechange_cb(keynode_t *node, void *data)
1106 {
1107         time_t t = time(NULL);
1108         cal_server_alarm_alert(t);
1109         cal_server_alarm_register_next_alarm(t);
1110 }
1111
1112 void _cal_server_alarm_set_timechange(void)
1113 {
1114         vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
1115                         _cal_server_alarm_timechange_cb, NULL);
1116         vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT,
1117                         _cal_server_alarm_timechange_cb, NULL);
1118         vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT,
1119                         _cal_server_alarm_timechange_cb, NULL);
1120         vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE,
1121                         _cal_server_alarm_timechange_cb, NULL);
1122 }
1123
1124 void _cal_server_alarm_unset_timechange(void)
1125 {
1126         vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED,
1127                         _cal_server_alarm_timechange_cb);
1128         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT,
1129                         _cal_server_alarm_timechange_cb);
1130         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT,
1131                         _cal_server_alarm_timechange_cb);
1132         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE,
1133                         _cal_server_alarm_timechange_cb);
1134 }
1135
1136 static void _changed_cb(const char* view_uri, void* data)
1137 {
1138         CAL_FN_CALL();
1139         cal_server_alarm_register_next_alarm(time(NULL));
1140 }
1141
1142 static int _cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
1143 {
1144         cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_FILE_EVENT, callback, NULL);
1145         cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_FILE_TODO, callback, NULL);
1146         return 0;
1147 }
1148
1149 static void _cal_server_alarm_unset_inotify(calendar_db_changed_cb callback)
1150 {
1151         cal_inotify_unsubscribe(CAL_NOTI_FILE_EVENT, callback, NULL);
1152         cal_inotify_unsubscribe(CAL_NOTI_FILE_TODO, callback, NULL);
1153 }
1154
1155 int cal_server_alarm_init(void)
1156 {
1157         CAL_FN_CALL();
1158
1159         int ret = 0;
1160         _cal_server_alarm_set_timechange();
1161         _cal_server_alarm_set_inotify(_changed_cb);
1162
1163         ret = alarmmgr_init("calendar-service");
1164         if (ret < 0) {
1165                 /* LCOV_EXCL_START */
1166                 ERR("alarmmgr_init() Fail(%d)", ret);
1167                 return CALENDAR_ERROR_SYSTEM;
1168                 /* LCOV_EXCL_STOP */
1169         }
1170
1171         ret = alarmmgr_set_cb(_alert_cb, NULL);
1172         if (ret < 0) {
1173                 /* LCOV_EXCL_START */
1174                 ERR("alarmmgr_set_cb() Fail(%d)", ret);
1175                 return CALENDAR_ERROR_SYSTEM;
1176                 /* LCOV_EXCL_STOP */
1177         }
1178
1179         cal_server_alarm_register_next_alarm(time(NULL));
1180         return CALENDAR_ERROR_NONE;
1181 }
1182
1183 void cal_server_alarm_deinit(void)
1184 {
1185         alarmmgr_fini();
1186         _cal_server_alarm_unset_inotify(_changed_cb);
1187         _cal_server_alarm_unset_timechange();
1188
1189 }
1190