[Non-ACR] Temporarily Error logs added for VD alarm issue
[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 #include <sys/time.h>
22 #include <unistd.h>
23 #include <alarm.h>
24 #include <vconf.h>
25 #include <app.h>
26
27 #include "calendar.h"
28 #include "cal_typedef.h"
29 #include "cal_internal.h"
30 #include "cal_time.h"
31 #include "cal_inotify.h"
32 #include "cal_db_util.h"
33 #include "cal_db.h"
34 #include "cal_db_query.h"
35 #include "cal_server_service.h"
36 #include "cal_server_ondemand.h"
37 #include "cal_server_dbus.h"
38 #include "cal_server_alarm.h"
39
40 #define CAL_SERVER_ALARM_THREAD_NAME "cal_server_alarm"
41
42 GThread *_cal_server_alarm_thread = NULL;
43 GCond _cal_server_alarm_cond;
44 GMutex _cal_server_alarm_mutex;
45 static bool server_killed = false;
46 static bool signal_called = false;
47
48 struct _alarm_data_s {
49         int event_id;
50         long long int alert_utime; /* to compare */
51         int unit;
52         int tick;
53         int type; /* utime, localtime */
54         long long int time;
55         int record; /* todo, event */
56         char datetime[CAL_STR_SHORT_LEN32];
57         int system_type;
58 };
59
60 struct alarm_ud {
61         GList *alarm_list;
62 };
63
64 /* this api is necessary for repeat instance. */
65 static int cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
66 {
67         char query[CAL_DB_SQL_MAX_LEN] = {0};
68         int ret = 0;
69
70         ret = cal_db_util_begin_trans();
71         if (CALENDAR_ERROR_NONE != ret) {
72                 /* LCOV_EXCL_START */
73                 ERR("cal_db_util_begin_trans() Fail");
74                 return CALENDAR_ERROR_DB_FAILED;
75                 /* LCOV_EXCL_STOP */
76         }
77
78         DBG("alarm_id(%d)", alarm_id);
79
80         snprintf(query, sizeof(query), "UPDATE %s SET alarm_id = 0 WHERE alarm_id =%d ",
81                         CAL_TABLE_ALARM, alarm_id);
82         ret = cal_db_util_query_exec(query);
83         if (CALENDAR_ERROR_NONE != ret) {
84                 /* LCOV_EXCL_START */
85                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
86                 SECURE("[%s]", query);
87                 cal_db_util_end_trans(false);
88                 return ret;
89                 /* LCOV_EXCL_STOP */
90         }
91         cal_db_util_end_trans(true);
92         return CALENDAR_ERROR_NONE;
93 }
94
95 static int _cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
96 {
97         int ret;
98
99         DBG("remove alarm id(%d)", alarm_id);
100         cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
101         ret = alarmmgr_remove_alarm(alarm_id);
102         if (ret != ALARMMGR_RESULT_SUCCESS) {
103                 /* LCOV_EXCL_START */
104                 ERR("alarmmgr_remove_alarm() Fail(ret:%d)", ret);
105                 return ret;
106                 /* LCOV_EXCL_STOP */
107         }
108         return CALENDAR_ERROR_NONE;
109 }
110
111 static int _cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
112 {
113         char query[CAL_DB_SQL_MAX_LEN] = {0};
114         int ret = 0;
115
116         ret = cal_db_util_begin_trans();
117         if (CALENDAR_ERROR_NONE != ret) {
118                 /* LCOV_EXCL_START */
119                 ERR("cal_db_util_begin_trans() Fail");
120                 return CALENDAR_ERROR_DB_FAILED;
121                 /* LCOV_EXCL_STOP */
122         }
123
124         DBG("Update alarm_id(%d) in alarm table", alarm_id);
125         snprintf(query, sizeof(query), "UPDATE %s SET alarm_id =%d "
126                         "WHERE event_id =%d AND remind_tick =%d AND remind_tick_unit =%d",
127                         CAL_TABLE_ALARM, alarm_id, event_id, tick, unit);
128         ret = cal_db_util_query_exec(query);
129         if (CALENDAR_ERROR_NONE != ret) {
130                 /* LCOV_EXCL_START */
131                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
132                 SECURE("[%s]", query);
133                 cal_db_util_end_trans(false);
134                 return ret;
135                 /* LCOV_EXCL_STOP */
136         }
137         cal_db_util_end_trans(true);
138         return CALENDAR_ERROR_NONE;
139 }
140
141 static time_t _make_time(struct tm *time)
142 {
143         time_t utc = mktime(time);
144
145         /* If an error occurs when isdst is 1, retry it after chaning isdst is 0 */
146         if (utc < 0 && time->tm_isdst != 0 ) {
147                 time->tm_isdst = 0;
148                 utc = mktime(time);
149         }
150         return utc;
151 }
152
153 static long long int _get_event_alert_utime(const char *field, int event_id, time_t current)
154 {
155         int ret = 0;
156         char query[CAL_DB_SQL_MAX_LEN] = {0};
157         snprintf(query, sizeof(query), "SELECT %s FROM %s "
158                         "WHERE event_id=%d AND %s>%ld ORDER BY %s LIMIT 1",
159                         field, CAL_TABLE_UTIME_INSTANCE, event_id, field, current, field);
160
161         sqlite3_stmt *stmt = NULL;
162         ret = cal_db_util_query_prepare(query, &stmt);
163         if (CALENDAR_ERROR_NONE != ret) {
164                 /* LCOV_EXCL_START */
165                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
166                 SECURE("query[%s]", query);
167                 return ret;
168                 /* LCOV_EXCL_STOP */
169         }
170
171         long long int utime = 0;
172         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
173                 utime = sqlite3_column_int(stmt, 0);
174
175         sqlite3_finalize(stmt);
176         return utime;
177 }
178
179 static int _get_event_alert_localtime(const char *field, int event_id, time_t current)
180 {
181         int ret = 0;
182         char query[CAL_DB_SQL_MAX_LEN] = {0};
183         struct tm st = {0};
184         struct tm now_s = {0};
185         char buf[256] = {0};
186
187         localtime_r(&current, &now_s);
188         snprintf(buf, sizeof(buf), "%04d-%02d-%02dT%02d:%02d:%02d", (int)(now_s.tm_year + 1900),
189                                 (int)(now_s.tm_mon + 1), (int)now_s.tm_mday, (int)now_s.tm_hour,
190                                 (int)now_s.tm_min, (int)now_s.tm_sec);
191         DBG("Current time : (%s)", buf);
192
193         snprintf(query, sizeof(query), "SELECT %s FROM %s "
194                         "WHERE event_id=%d AND (strftime('%%s', %s) - strftime('%%s', '%s') > 0) ORDER BY %s LIMIT 1",
195                         field, CAL_TABLE_LOCALTIME_INSTANCE, event_id, field, buf, field);
196
197         sqlite3_stmt *stmt = NULL;
198         ret = cal_db_util_query_prepare(query, &stmt);
199         if (CALENDAR_ERROR_NONE != ret) {
200                 /* LCOV_EXCL_START */
201                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
202                 SECURE("query[%s]", query);
203                 return ret;
204                 /* LCOV_EXCL_STOP */
205         }
206
207         const char *datetime = NULL;
208         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
209                 datetime = (const char *)sqlite3_column_text(stmt, 0);
210
211
212         if (NULL == datetime || '\0' == *datetime) {
213                 /* LCOV_EXCL_START */
214                 ERR("Invalid datetime [%s]", datetime);
215                 sqlite3_finalize(stmt);
216                 return 0;
217                 /* LCOV_EXCL_STOP */
218         }
219
220         int y = 0, m = 0, d = 0;
221         int h = 0, n = 0, s = 0;
222         sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
223         sqlite3_finalize(stmt);
224
225         st.tm_year = y - 1900;
226         st.tm_mon = m - 1;
227         st.tm_mday = d;
228         st.tm_hour = h;
229         st.tm_min = n;
230         st.tm_sec = s;
231         st.tm_isdst = cal_time_is_dst_savings();
232
233         return (long long int)_make_time(&st);
234 }
235
236 static int64_t _get_todo_alert_utime(const char *field, int id, time_t now_t)
237 {
238         int ret = 0;
239         char query[CAL_DB_SQL_MAX_LEN] = {0};
240         snprintf(query, sizeof(query), "SELECT %s FROM "CAL_TABLE_SCHEDULE" "
241                         "WHERE id=%d AND %s>%ld ORDER BY %s LIMIT 1", field, id, field, now_t, field);
242
243         sqlite3_stmt *stmt = NULL;
244         ret = cal_db_util_query_prepare(query, &stmt);
245         if (CALENDAR_ERROR_NONE != ret) {
246                 /* LCOV_EXCL_START */
247                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
248                 SECURE("query[%s]", query);
249                 return ret;
250                 /* LCOV_EXCL_STOP */
251         }
252
253         int64_t utime = 0;
254         ret = cal_db_util_stmt_step(stmt);
255         switch (ret) {
256         case CAL_SQLITE_ROW:
257                 utime = (int64_t)sqlite3_column_int64(stmt, 0);
258                 break;
259                 /* LCOV_EXCL_START
260         case SQLITE_DONE:
261                 ERR("No data");
262                 break;*/ //Svace:371986
263         default:
264                 ERR("Invalid return(%d)", ret);
265                 break;
266                 /* LCOV_EXCL_STOP */
267         }
268
269         sqlite3_finalize(stmt);
270         return utime;
271 }
272
273 static int _get_todo_alert_localtime(const char *field, int event_id, time_t current)
274 {
275         int ret = 0;
276         char query[CAL_DB_SQL_MAX_LEN] = {0};
277         struct tm st = {0};
278         struct tm now_s = {0};
279         char buf[256] = {0};
280
281         localtime_r(&current, &now_s);
282         snprintf(buf, sizeof(buf), "%04d-%02d-%02dT%02d:%02d:%02d", (int)(now_s.tm_year + 1900),
283                                 (int)(now_s.tm_mon + 1), (int)now_s.tm_mday, (int)now_s.tm_hour,
284                                 (int)now_s.tm_min, (int)now_s.tm_sec);
285         DBG("Current time : (%s)", buf);
286
287         snprintf(query, sizeof(query), "SELECT %s FROM %s "
288                         "WHERE id=%d AND (strftime('%%s', %s) - strftime('%%s', '%s') > 0) ORDER BY %s LIMIT 1",
289                         field, CAL_TABLE_SCHEDULE, event_id, field, buf, field);
290
291         sqlite3_stmt *stmt = NULL;
292         ret = cal_db_util_query_prepare(query, &stmt);
293         if (CALENDAR_ERROR_NONE != ret) {
294                 /* LCOV_EXCL_START */
295                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
296                 SECURE("query[%s]", query);
297                 return ret;
298                 /* LCOV_EXCL_STOP */
299         }
300
301         const char *datetime = NULL;
302         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
303                 datetime = (const char *)sqlite3_column_text(stmt, 0);
304
305         if (NULL == datetime || '\0' == *datetime) {
306                 /* LCOV_EXCL_START */
307                 ERR("Invalid datetime [%s]", datetime);
308                 sqlite3_finalize(stmt);
309                 return 0;
310                 /* LCOV_EXCL_STOP */
311         }
312
313         int y = 0, m = 0, d = 0;
314         int h = 0, n = 0, s = 0;
315         sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
316         sqlite3_finalize(stmt);
317
318         st.tm_year = y - 1900;
319         st.tm_mon = m - 1;
320         st.tm_mday = d;
321         st.tm_hour = h;
322         st.tm_min = n;
323         st.tm_sec = s;
324         st.tm_isdst = cal_time_is_dst_savings();
325
326         return (long long int)_make_time(&st);
327 }
328 /*
329  * time(NULL) is not appropriate as parameter.
330  * 1 seconds could be flowed before calling function.(1 sec time diff)
331  * so, searching DB is neccessary to find alert time.
332  */
333 static int cal_server_alarm_get_alert_time(int alarm_id, time_t *tt_alert)
334 {
335         int ret = 0;
336         RETV_IF(NULL == tt_alert, CALENDAR_ERROR_INVALID_PARAMETER);
337
338         char query[CAL_DB_SQL_MAX_LEN] = {0};
339         snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
340                         "A.alarm_type, A.alarm_utime, A.alarm_datetime, B.type, B.dtstart_type, "
341                         "B.dtend_type FROM %s as A, %s as B ON A.event_id =B.id WHERE alarm_id =%d ",
342                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE, alarm_id);
343
344         sqlite3_stmt *stmt = NULL;
345         ret = cal_db_util_query_prepare(query, &stmt);
346         if (CALENDAR_ERROR_NONE != ret) {
347                 /* LCOV_EXCL_START */
348                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
349                 SECURE("query[%s]", query);
350                 return ret;
351                 /* LCOV_EXCL_STOP */
352         }
353
354         int event_id = 0;
355         int unit = 0;
356         int tick = 0;
357         int type = 0;
358         long long int utime = 0;
359         const char *datetime = NULL;
360         int record_type = 0;
361         int dtstart_type = 0;
362         int dtend_type = 0;
363         struct tm st = {0};
364
365         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
366                 event_id = sqlite3_column_int(stmt, 0);
367                 unit = sqlite3_column_int(stmt, 1);
368                 tick = sqlite3_column_int(stmt, 2);
369                 type = sqlite3_column_int(stmt, 3);
370                 utime = sqlite3_column_int64(stmt, 4);
371                 datetime = (const char *)sqlite3_column_text(stmt, 5);
372                 record_type = sqlite3_column_int(stmt, 6);
373                 dtstart_type = sqlite3_column_int(stmt, 7);
374                 dtend_type = sqlite3_column_int(stmt, 8);
375         }
376
377         if (CALENDAR_ALARM_TIME_UNIT_SPECIFIC == unit) {
378                 if (CALENDAR_TIME_UTIME == type) {
379                         *tt_alert = utime;
380                 } else {
381                         int y = 0, m = 0, d = 0;
382                         int h = 0, n = 0, s = 0;
383                         if (datetime) {
384                                 sscanf(datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
385
386                                 st.tm_year = y - 1900;
387                                 st.tm_mon = m - 1;
388                                 st.tm_mday = d;
389                                 st.tm_hour = h;
390                                 st.tm_min = n;
391                                 st.tm_sec = s;
392                                 st.tm_isdst = cal_time_is_dst_savings();
393                                 *tt_alert = _make_time(&st);
394                                 DBG("datetime[%s] to %02d:%02d:%02d (%ld)", datetime, h, n, s, *tt_alert);
395                         }
396                 }
397                 sqlite3_finalize(stmt);
398                 return CALENDAR_ERROR_NONE;
399         }
400         sqlite3_finalize(stmt);
401
402         time_t current = time(NULL);
403
404         current += (tick * unit);
405         current -= 2; /* in case time passed */
406
407         switch (record_type) {
408         case CALENDAR_BOOK_TYPE_EVENT:
409                 switch (dtstart_type) {
410                 case CALENDAR_TIME_UTIME:
411                         utime = _get_event_alert_utime("dtstart_utime", event_id, current);
412                         break;
413
414                 case CALENDAR_TIME_LOCALTIME:
415                         utime = _get_event_alert_localtime("dtstart_datetime", event_id, current);
416                         break;
417                 }
418                 break;
419
420         case CALENDAR_BOOK_TYPE_TODO:
421                 switch (dtend_type) {
422                 case CALENDAR_TIME_UTIME:
423                         utime = _get_todo_alert_utime("dtend_utime", event_id, current);
424                         break;
425
426                 case CALENDAR_TIME_LOCALTIME:
427                         utime = _get_todo_alert_localtime("dtend_datetime", event_id, current);
428                         break;
429                 }
430                 break;
431         }
432         *tt_alert = utime - (tick * unit);
433
434         DBG("alert_time(%ld) = utime(%lld) - (tick(%d) * unit(%d))", *tt_alert, utime, tick, unit);
435
436         return CALENDAR_ERROR_NONE;
437 }
438
439 /*
440  * bool get_all is
441  * true : to get all alarms including same time event.
442  * (ig. if 3 diffrent alarms exist at 06:30, list has 3 data)
443  * false : to get only one alarm to register in alarm-manager.
444  * (ig. if 3 diffrent alarms exist at 06:30, list has only one)
445  */
446 static void _cal_server_alarm_get_upcoming_specific_utime(time_t utime, bool get_all, GList **l)
447 {
448         CAL_FN_CALL();
449         int ret = 0;
450         char query[CAL_DB_SQL_MAX_LEN] = {0};
451         snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick,"
452                         "A.alarm_type, A.alarm_utime, A.alarm_datetime "
453                         "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as S ON A.event_id = S.id "
454                         "WHERE S.link_base_id = 0 AND A.remind_tick_unit = %d AND A.alarm_type = %d "
455                         "AND A.alarm_utime %s %ld %s",
456                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
457                         true == get_all ? "=" : ">", utime,
458                         true == get_all ? "" : "ORDER BY alarm_utime ASC LIMIT 1");
459
460         sqlite3_stmt *stmt = NULL;
461         ret = cal_db_util_query_prepare(query, &stmt);
462         if (CALENDAR_ERROR_NONE != ret) {
463                 /* LCOV_EXCL_START */
464                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
465                 SECURE("query[%s]", query);
466                 return;
467                 /* LCOV_EXCL_STOP */
468         }
469
470         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
471                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
472                 if (NULL == ad) {
473                         /* LCOV_EXCL_START */
474                         ERR("calloc() Fail");
475                         sqlite3_finalize(stmt);
476                         return;
477                         /* LCOV_EXCL_STOP */
478                 }
479
480                 ad->event_id = sqlite3_column_int(stmt, 0);
481                 ad->unit = sqlite3_column_int(stmt, 1);
482                 ad->tick = sqlite3_column_int(stmt, 2);
483                 ad->type = sqlite3_column_int(stmt, 3);
484                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
485                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
486                 *l = g_list_append(*l, ad);
487                 ERR("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
488                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
489                 ad->alert_utime = ad->time;
490                 if (false == get_all) break;
491         }
492         sqlite3_finalize(stmt);
493 }
494
495 static void _cal_server_alarm_get_upcoming_specific_localtime(const char *datetime, bool get_all, GList **l)
496 {
497         CAL_FN_CALL();
498         int ret = 0;
499         char query[CAL_DB_SQL_MAX_LEN] = {0};
500         snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick,"
501                         "A.alarm_type, A.alarm_utime, A.alarm_datetime "
502                         "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as S ON A.event_id = S.id "
503                         "WHERE S.link_base_id = 0 AND A.remind_tick_unit = %d AND A.alarm_type = %d "
504                         "AND A.alarm_datetime %s '%s' %s",
505                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
506                         true == get_all ? "=" : ">", datetime,
507                         true == get_all ? "" : "ORDER BY alarm_datetime ASC LIMIT 1");
508
509         sqlite3_stmt *stmt = NULL;
510         ret = cal_db_util_query_prepare(query, &stmt);
511         if (CALENDAR_ERROR_NONE != ret) {
512                 /* LCOV_EXCL_START */
513                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
514                 SECURE("query[%s]", query);
515                 return;
516                 /* LCOV_EXCL_STOP */
517         }
518
519         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
520                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
521                 if (NULL == ad) {
522                         /* LCOV_EXCL_START */
523                         ERR("calloc() Fail");
524                         sqlite3_finalize(stmt);
525                         return;
526                         /* LCOV_EXCL_STOP */
527                 }
528
529                 ad->event_id = sqlite3_column_int(stmt, 0);
530                 ad->unit = sqlite3_column_int(stmt, 1);
531                 ad->tick = sqlite3_column_int(stmt, 2);
532                 ad->type = sqlite3_column_int(stmt, 3);
533                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
534                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
535                 *l = g_list_append(*l, ad);
536                 ERR("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
537                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
538
539                 int y = 0, m = 0, d = 0;
540                 int h = 0, n = 0, s = 0;
541                 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
542
543                 struct tm st = {0};
544                 st.tm_year = y - 1900;
545                 st.tm_mon = m -1;
546                 st.tm_mday = d;
547                 st.tm_hour = h;
548                 st.tm_min = n;
549                 st.tm_sec = s;
550                 st.tm_isdst = cal_time_is_dst_savings();
551                 ad->alert_utime = (long long int)_make_time(&st);
552                 if (false == get_all) break;
553         }
554         sqlite3_finalize(stmt);
555 }
556
557 static void _cal_server_alarm_get_upcoming_nonspecific_event_utime(time_t utime, bool get_all, GList **l)
558 {
559         CAL_FN_CALL();
560         int ret = 0;
561         /*
562          * A:alarm
563          * B:utime
564          */
565         char query[CAL_DB_SQL_MAX_LEN] = {0};
566         snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
567                         "A.alarm_type,B.dtstart_utime,A.alarm_datetime "
568                         "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_UTIME_INSTANCE" as B, "CAL_TABLE_SCHEDULE" as S "
569                         "ON A.event_id = B.event_id AND B.event_id = S.id "
570                         "WHERE S.link_base_id = 0 AND A.remind_tick_unit > %d "
571                         "AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
572                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
573                         true == get_all ? "=" : ">", utime,
574                         true == get_all ? "" : "ORDER BY (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1");
575
576         sqlite3_stmt *stmt = NULL;
577         ret = cal_db_util_query_prepare(query, &stmt);
578         if (CALENDAR_ERROR_NONE != ret) {
579                 /* LCOV_EXCL_START */
580                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
581                 SECURE("query[%s]", query);
582                 return;
583                 /* LCOV_EXCL_STOP */
584         }
585
586         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
587                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
588                 if (NULL == ad) {
589                         /* LCOV_EXCL_START */
590                         ERR("calloc() Fail");
591                         sqlite3_finalize(stmt);
592                         return;
593                         /* LCOV_EXCL_STOP */
594                 }
595
596                 ad->event_id = sqlite3_column_int(stmt, 0);
597                 ad->unit = sqlite3_column_int(stmt, 1);
598                 ad->tick = sqlite3_column_int(stmt, 2);
599                 ad->type = sqlite3_column_int(stmt, 3);
600                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
601                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
602                 *l = g_list_append(*l, ad);
603                 ERR("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
604                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
605
606                 ad->alert_utime = ad->time - (ad->tick * ad->unit);
607                 if (false == get_all) break;
608         }
609         sqlite3_finalize(stmt);
610 }
611
612 static void _cal_server_alarm_get_upcoming_nonspecific_event_localtime(const char *datetime, bool get_all, GList **l)
613 {
614         CAL_FN_CALL();
615         int ret = 0;
616         /*
617          * A:alarm
618          * B:localtime
619          */
620         char query[CAL_DB_SQL_MAX_LEN] = {0};
621         snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
622                         "A.alarm_type, A.alarm_utime, B.dtstart_datetime "
623                         "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_LOCALTIME_INSTANCE" as B, "CAL_TABLE_SCHEDULE" as S "
624                         "ON A.event_id = B.event_id AND B.event_id = S.id "
625                         "WHERE S.link_base_id = 0 AND A.remind_tick_unit >%d AND "
626                         "(strftime('%%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
627                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
628                         datetime, true == get_all ? "=" : ">",
629                         true == get_all ? "" : "ORDER BY (strftime('%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
630         sqlite3_stmt *stmt = NULL;
631         ret = cal_db_util_query_prepare(query, &stmt);
632         if (CALENDAR_ERROR_NONE != ret) {
633                 /* LCOV_EXCL_START */
634                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
635                 SECURE("query[%s]", query);
636                 return;
637                 /* LCOV_EXCL_STOP */
638         }
639
640         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
641                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
642                 if (NULL == ad) {
643                         /* LCOV_EXCL_START */
644                         ERR("calloc() Fail");
645                         sqlite3_finalize(stmt);
646                         return;
647                         /* LCOV_EXCL_STOP */
648                 }
649
650                 ad->event_id = sqlite3_column_int(stmt, 0);
651                 ad->unit = sqlite3_column_int(stmt, 1);
652                 ad->tick = sqlite3_column_int(stmt, 2);
653                 ad->type = sqlite3_column_int(stmt, 3);
654                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
655                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
656                 *l = g_list_append(*l, ad);
657                 ERR("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
658                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
659
660                 int y = 0, m = 0, d = 0;
661                 int h = 0, n = 0, s = 0;
662                 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
663
664                 struct tm st = {0};
665                 st.tm_year = y - 1900;
666                 st.tm_mon = m -1;
667                 st.tm_mday = d;
668                 st.tm_hour = h;
669                 st.tm_min = n;
670                 st.tm_sec = s;
671                 st.tm_isdst = cal_time_is_dst_savings();
672                 ad->alert_utime = (long long int)_make_time(&st) - (ad->tick * ad->unit);
673                 if (false == get_all) break;
674         }
675         sqlite3_finalize(stmt);
676 }
677
678 static void _cal_server_alarm_get_upcoming_nonspecific_todo_utime(time_t utime, bool get_all, GList **l)
679 {
680         CAL_FN_CALL();
681         int ret = 0;
682         /*
683          * A:alarm
684          * S:todo(utime)
685          */
686         char query[CAL_DB_SQL_MAX_LEN] = {0};
687         snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick,"
688                         "A.alarm_type, S.dtend_utime, A.alarm_datetime "
689                         "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as S ON A.event_id = S.id "
690                         "WHERE A.remind_tick_unit > %d AND S.type = %d "
691                         "AND (S.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
692                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
693                         true == get_all ? "=" : ">", utime,
694                         true == get_all ? "" : "ORDER BY (S.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
695
696         sqlite3_stmt *stmt = NULL;
697         ret = cal_db_util_query_prepare(query, &stmt);
698         if (CALENDAR_ERROR_NONE != ret) {
699                 /* LCOV_EXCL_START */
700                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
701                 SECURE("query[%s]", query);
702                 return;
703                 /* LCOV_EXCL_STOP */
704         }
705
706         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
707                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
708                 if (NULL == ad) {
709                         /* LCOV_EXCL_START */
710                         ERR("calloc() Fail");
711                         sqlite3_finalize(stmt);
712                         return;
713                         /* LCOV_EXCL_STOP */
714                 }
715
716                 ad->event_id = sqlite3_column_int(stmt, 0);
717                 ad->unit = sqlite3_column_int(stmt, 1);
718                 ad->tick = sqlite3_column_int(stmt, 2);
719                 ad->type = sqlite3_column_int(stmt, 3);
720                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
721                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
722                 *l = g_list_append(*l, ad);
723                 ERR("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
724                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
725
726                 ad->alert_utime = ad->time - (ad->tick * ad->unit);
727                 if (false == get_all) break;
728         }
729         sqlite3_finalize(stmt);
730 }
731
732 static void _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(const char *datetime, bool get_all, GList **l)
733 {
734         CAL_FN_CALL();
735         int ret = 0;
736         /*
737          * A:alarm
738          * B:todo(localtime)
739          */
740         char query[CAL_DB_SQL_MAX_LEN] = {0};
741         snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
742                         "A.alarm_type,A.alarm_utime,B.dtend_datetime "
743                         "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as B ON A.event_id = B.id "
744                         "WHERE A.remind_tick_unit >%d AND B.type =%d "
745                         "AND (strftime('%%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
746                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
747                         datetime, true == get_all ? "=" : ">",
748                         true == get_all ? "" : "ORDER BY (strftime('%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
749
750         sqlite3_stmt *stmt = NULL;
751         ret = cal_db_util_query_prepare(query, &stmt);
752         if (CALENDAR_ERROR_NONE != ret) {
753                 /* LCOV_EXCL_START */
754                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
755                 SECURE("query[%s]", query);
756                 return;
757                 /* LCOV_EXCL_STOP */
758         }
759
760         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
761                 struct _alarm_data_s *ad = calloc(1, sizeof(struct _alarm_data_s));
762                 if (NULL == ad) {
763                         /* LCOV_EXCL_START */
764                         ERR("calloc() Fail");
765                         sqlite3_finalize(stmt);
766                         return;
767                         /* LCOV_EXCL_STOP */
768                 }
769
770                 ad->event_id = sqlite3_column_int(stmt, 0);
771                 ad->unit = sqlite3_column_int(stmt, 1);
772                 ad->tick = sqlite3_column_int(stmt, 2);
773                 ad->type = sqlite3_column_int(stmt, 3);
774                 ad->time = (long long int)sqlite3_column_int64(stmt, 4);
775                 snprintf(ad->datetime, sizeof(ad->datetime), "%s", (const char *)sqlite3_column_text(stmt, 5));
776                 *l = g_list_append(*l, ad);
777                 ERR("found id(%d) unit(%d) tick(%d) type(%d) time(%lld) [%s]",
778                                 ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime);
779
780                 int y = 0, m = 0, d = 0;
781                 int h = 0, n = 0, s = 0;
782                 sscanf(ad->datetime, CAL_FORMAT_LOCAL_DATETIME, &y, &m, &d, &h, &n, &s);
783
784                 struct tm st = {0};
785                 st.tm_year = y - 1900;
786                 st.tm_mon = m -1;
787                 st.tm_mday = d;
788                 st.tm_hour = h;
789                 st.tm_min = n;
790                 st.tm_sec = s;
791                 st.tm_isdst = cal_time_is_dst_savings();
792                 ad->alert_utime = (long long int)_make_time(&st) - (ad->tick * ad->unit);
793                 if (false == get_all) break;
794         }
795         sqlite3_finalize(stmt);
796 }
797
798 static void _cal_server_alarm_get_latest(time_t utime, bool get_all, GList **out_l)
799 {
800         int ret = 0;
801         CAL_FN_CALL();
802         RET_IF(NULL == out_l);
803
804         tzset();
805         struct tm st_local = {0};
806         localtime_r(&utime, &st_local);
807
808         char datetime[CAL_STR_SHORT_LEN32] = {0};
809         ret = snprintf(datetime, sizeof(datetime), CAL_FORMAT_LOCAL_DATETIME,
810                         st_local.tm_year +1900, st_local.tm_mon + 1, st_local.tm_mday,
811                         st_local.tm_hour, st_local.tm_min, st_local.tm_sec);
812
813         if(ret < 0){
814                 WARN("datetime is truncated (%s)",datetime);
815         }
816
817         ERR("get alert to register with given time (%ld) datetime[%s]", utime, datetime); //Temporarily changed to ERR
818
819         GList *l = NULL;
820
821         _cal_server_alarm_get_upcoming_specific_utime(utime, get_all, &l);
822         _cal_server_alarm_get_upcoming_nonspecific_event_utime(utime, get_all, &l);
823         _cal_server_alarm_get_upcoming_nonspecific_todo_utime(utime, get_all, &l);
824
825         _cal_server_alarm_get_upcoming_specific_localtime(datetime, get_all, &l);
826         _cal_server_alarm_get_upcoming_nonspecific_event_localtime(datetime, get_all, &l);
827         _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(datetime, get_all, &l);
828
829         *out_l = l;
830 }
831
832 static gint _cal_server_alarm_sort_cb(gconstpointer a, gconstpointer b)
833 {
834         struct _alarm_data_s *p1 = (struct _alarm_data_s *)a;
835         struct _alarm_data_s *p2 = (struct _alarm_data_s *)b;
836         DBG("%lld) > (%lld)", p1->alert_utime, p2->alert_utime);
837
838         return p1->alert_utime < p2->alert_utime ? -1 : 1;
839 }
840
841 static GFunc _cal_server_alarm_print_cb(gpointer data, gpointer user_data)
842 {
843         struct _alarm_data_s *ad = (struct _alarm_data_s *)data;
844         DBG("id(%d) unit(%d) tick(%d) type(%d) time(%lld) datetime[%s] alert_utime[%lld]",
845                         ad->event_id, ad->unit, ad->tick, ad->type, ad->time, ad->datetime, ad->alert_utime);
846         return 0;
847 }
848
849 static int _cal_server_alarm_register(GList *alarm_list)
850 {
851         CAL_FN_CALL();
852         RETV_IF(NULL == alarm_list, CALENDAR_ERROR_INVALID_PARAMETER);
853
854         int ret = CALENDAR_ERROR_NONE;
855         GList *l = g_list_first(alarm_list);
856         RETV_IF(NULL == l, CALENDAR_ERROR_INVALID_PARAMETER);
857
858         struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
859         RETVM_IF(NULL == ad, CALENDAR_ERROR_DB_FAILED, "No data");
860
861         /* clear all alarm which set by mine. */
862         ret = alarmmgr_enum_alarm_ids(_cal_server_alarm_clear_all_cb, NULL);
863         if (ret != ALARMMGR_RESULT_SUCCESS) {
864                 /* LCOV_EXCL_START */
865                 ERR("alarmmgr_enum_alarm_ids() Fail");
866                 return ret;
867                 /* LCOV_EXCL_STOP */
868         }
869
870         time_t mod_time = (time_t)ad->alert_utime;
871         /*Temporarily added error logs to handle a defect*/
872         ERR("_cal_server_alarm_register ad->alert_utime (%lld) mod_time (%ld)", ad->alert_utime, mod_time);
873         alarm_entry_t *alarm_info = NULL;
874         alarm_info = alarmmgr_create_alarm();
875         if (NULL == alarm_info) {
876                 /* LCOV_EXCL_START */
877                 ERR("Failed to create alarm");
878                 return CALENDAR_ERROR_DB_FAILED;
879                 /* LCOV_EXCL_STOP */
880         }
881         tzset();
882         struct tm st_alarm = {0};
883
884         switch (ad->system_type) {
885         case CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR:
886                 gmtime_r(&mod_time, &st_alarm);
887                 break;
888
889         default:
890                 tzset();
891                 ERR("This case have been choosen "); //Temporarily logs
892                 localtime_r(&mod_time, &st_alarm);
893                 break;
894         }
895
896         alarm_date_t date = {0};
897         date.year = st_alarm.tm_year + 1900;
898         date.month = st_alarm.tm_mon + 1;
899         date.day = st_alarm.tm_mday;
900         date.hour = st_alarm.tm_hour;
901         date.min = st_alarm.tm_min;
902         date.sec = st_alarm.tm_sec;
903         alarmmgr_set_time(alarm_info, date);
904         /*Temporarily added error logs to handle a defect*/
905         ERR(COLOR_CYAN" >>> registered record id (%d) at %04d/%02d/%02d %02d:%02d:%02d "COLOR_END" (utime(%lld), datetime[%s], tick(%d) unit(%d))",
906                         ad->event_id, date.year, date.month, date.day, date.hour, date.min, date.sec,
907                         ad->time, ad->datetime, ad->tick, ad->unit);
908
909         int alarm_id = 0;
910         ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
911         if (ret < 0) {
912                 /* LCOV_EXCL_START */
913                 ERR("alarmmgr_add_alarm_with_localtime Fail (%d)", ret);
914                 alarmmgr_free_alarm(alarm_info);
915                 return ret;
916                 /* LCOV_EXCL_STOP */
917         }
918         DBG("alarmmgr id (%d)", alarm_id);
919         _cal_server_alarm_update_alarm_id(alarm_id, ad->event_id, ad->tick, ad->unit);
920         alarmmgr_free_alarm(alarm_info);
921         return CALENDAR_ERROR_NONE;
922 }
923
924 static bool __app_matched_cb(app_control_h app_control, const char *package, void *user_data)
925 {
926         CAL_FN_CALL();
927
928         int ret = 0;
929         int i;
930
931         RETV_IF(NULL == user_data, true);
932
933         char *mime = NULL;
934         ret = app_control_get_mime(app_control, &mime);
935         RETVM_IF(APP_CONTROL_ERROR_NONE != ret, true, "app_control_get_mime() Fail(%d)", ret);
936
937         const char *reminder_mime = "application/x-tizen.calendar.reminder";
938         if (strncmp(mime, reminder_mime, strlen(reminder_mime))) { /* not same */
939                 DBG("get mime[%s] is not [%s]", mime, reminder_mime);
940                 free(mime);
941                 return true;
942         }
943         free(mime);
944
945         struct alarm_ud *au = (struct alarm_ud *)user_data;
946         GList *alarm_list = au->alarm_list;
947         if (NULL == alarm_list) {
948                 /* LCOV_EXCL_START */
949                 ERR("No list");
950                 return true;
951                 /* LCOV_EXCL_STOP */
952         }
953         int len = 0;
954         len = g_list_length(alarm_list);
955         if (0 == len) {
956                 DBG("len is 0, no alarm list");
957                 return true;
958         }
959
960         app_control_h ac = NULL;
961         ret = app_control_create(&ac);
962         if (APP_CONTROL_ERROR_NONE != ret) {
963                 /* LCOV_EXCL_START */
964                 ERR("app_control_create() Fail(%d)", ret);
965                 return true;
966                 /* LCOV_EXCL_STOP */
967         }
968         ret = app_control_set_operation(ac,  APP_CONTROL_OPERATION_DEFAULT);
969         if (APP_CONTROL_ERROR_NONE != ret) {
970                 /* LCOV_EXCL_START */
971                 ERR("app_control_create() Fail(%d)", ret);
972                 app_control_destroy(ac);
973                 return true;
974                 /* LCOV_EXCL_STOP */
975         }
976         ret = app_control_set_app_id(ac, package);
977         if (APP_CONTROL_ERROR_NONE != ret) {
978                 /* LCOV_EXCL_START */
979                 ERR("app_control_set_app_id() Fail(%d)", ret);
980                 app_control_destroy(ac);
981                 return true;
982                 /* LCOV_EXCL_STOP */
983         }
984
985         char **ids = NULL;
986         ids = calloc(len, sizeof(char *));
987         if (NULL == ids) {
988                 /* LCOV_EXCL_START */
989                 ERR("calloc() Fail");
990                 app_control_destroy(ac);
991                 return true;
992                 /* LCOV_EXCL_STOP */
993         }
994         GList *cursor = g_list_first(alarm_list);
995         for (i = 0; i < len; i++) {
996                 if (NULL == cursor) {
997                         ERR("cursor is NULL");
998                         break;
999                 }
1000                 struct _alarm_data_s *ad = (struct _alarm_data_s *)cursor->data;
1001                 if (NULL == ad) {
1002                         WARN("No data");
1003                         cursor = g_list_next(cursor);
1004                         continue;
1005                 }
1006                 DBG("pkg[%s] time[%lld] tick[%d] unit[%d] record_type[%d]",
1007                                 package, ad->time, ad->tick, ad->unit, ad->record);
1008
1009                 int slen = 0;
1010                 char extra[CAL_STR_MIDDLE_LEN] = {0};
1011                 slen = snprintf(extra, sizeof(extra), "%s=%d", "id", ad->event_id);
1012                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%lld", "time", ad->time);
1013                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "tick", ad->tick);
1014                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "unit", ad->unit);
1015                 slen += snprintf(extra+slen, sizeof(extra)-slen, "&%s=%d", "type", ad->record);
1016
1017                 /*
1018                  * key: id, value: id=4&time=123123&..
1019                  */
1020                 char buf_id[CAL_STR_MIDDLE_LEN] = {0};
1021                 snprintf(buf_id, sizeof(buf_id), "%d", ad->event_id);
1022                 app_control_add_extra_data(ac, buf_id, extra);
1023                 DBG("value[%s] id[%s]", extra, buf_id);
1024
1025                 /* append ids */
1026                 ids[i] = strdup(buf_id);
1027
1028                 cursor = g_list_next(cursor);
1029         }
1030         app_control_add_extra_data_array(ac, "ids", (const char **)ids, len);
1031         app_control_send_launch_request(ac, NULL, NULL);
1032         app_control_destroy(ac);
1033
1034         for (i = 0; i < len; i++) {
1035                 free(ids[i]);
1036                 ids[i] = NULL;
1037         }
1038         free(ids);
1039
1040         return true;
1041 }
1042
1043 static void _cal_server_alarm_noti_with_control(GList *alarm_list)
1044 {
1045         CAL_FN_CALL();
1046
1047         int ret = 0;
1048         RETM_IF(NULL == alarm_list, "No alarm list");
1049
1050         app_control_h app_control = NULL;
1051         ret = app_control_create(&app_control);
1052         if (APP_CONTROL_ERROR_NONE != ret) {
1053                 /* LCOV_EXCL_START */
1054                 ERR("app_control_create() Fail(%d)", ret);
1055                 return;
1056                 /* LCOV_EXCL_STOP */
1057         }
1058         ret = app_control_set_operation(app_control, APP_CONTROL_OPERATION_VIEW);
1059         if (APP_CONTROL_ERROR_NONE != ret) {
1060                 /* LCOV_EXCL_START */
1061                 ERR("app_control_set_operation() Fail(%d)", ret);
1062                 app_control_destroy(app_control);
1063                 return;
1064                 /* LCOV_EXCL_STOP */
1065         }
1066         ret = app_control_set_mime(app_control, "application/x-tizen.calendar.reminder");
1067         if (APP_CONTROL_ERROR_NONE != ret) {
1068                 /* LCOV_EXCL_START */
1069                 ERR("app_control_set_mime() Fail(%d)", ret);
1070                 app_control_destroy(app_control);
1071                 return;
1072                 /* LCOV_EXCL_STOP */
1073         }
1074
1075         struct alarm_ud *au = calloc(1, sizeof(struct alarm_ud));
1076         if (NULL == au) {
1077                 /* LCOV_EXCL_START */
1078                 ERR("calloc() Fail");
1079                 app_control_destroy(app_control);
1080                 return;
1081                 /* LCOV_EXCL_STOP */
1082         }
1083         au->alarm_list = alarm_list;
1084         ret = app_control_foreach_app_matched(app_control, __app_matched_cb, au);
1085         if (APP_CONTROL_ERROR_NONE != ret) {
1086                 /* LCOV_EXCL_START */
1087                 ERR("app_control_foreach_app_matched() Fail(%d)", ret);
1088                 free(au);
1089                 app_control_destroy(app_control);
1090                 return;
1091                 /* LCOV_EXCL_STOP */
1092         }
1093         free(au);
1094         app_control_destroy(app_control);
1095 }
1096
1097 static void _cal_server_alarm_noti_with_callback(GList *alarm_list)
1098 {
1099         RETM_IF(NULL == alarm_list, "No alarm list");
1100
1101         GList *l = g_list_first(alarm_list);
1102         while (l) {
1103                 struct _alarm_data_s *ad = (struct _alarm_data_s *)l->data;
1104                 if (NULL == ad) {
1105                         WARN("No data");
1106                         l = g_list_next(l);
1107                         continue;
1108                 }
1109                 DBG("callback time[%lld] tick[%d] unit[%d] record_type[%d]",
1110                                 ad->time, ad->tick, ad->unit, ad->record);
1111
1112                 int len = 0;
1113                 char extra[CAL_STR_MIDDLE_LEN] = {0};
1114                 len = snprintf(extra, sizeof(extra), "%s=%d", "id", ad->event_id);
1115                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%lld", "time", ad->time);
1116                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "tick", ad->tick);
1117                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "unit", ad->unit);
1118                 len += snprintf(extra+len, sizeof(extra)-len, "&%s=%d", "type", ad->record);
1119                 cal_dbus_publish_reminder(len, extra);
1120
1121                 l = g_list_next(l);
1122         }
1123 }
1124
1125 static void cal_server_alarm_register_next_alarm(time_t utime)
1126 {
1127         CAL_FN_CALL();
1128
1129         ERR(" cal_server_alarm_register_next_alarm  utime = %ld", utime); // Temporarily logs
1130         GList *l = NULL;
1131         _cal_server_alarm_get_latest(utime, false, &l);
1132         if (NULL == l)
1133                 return;
1134
1135         l = g_list_sort(l, _cal_server_alarm_sort_cb);
1136         g_list_foreach(l, (GFunc)_cal_server_alarm_print_cb, NULL);
1137         _cal_server_alarm_register(l);
1138
1139         g_list_free_full(l, free);
1140 }
1141
1142 static void cal_server_alarm_alert(time_t tt_alert)
1143 {
1144         GList *l = NULL;
1145         _cal_server_alarm_get_latest(tt_alert, true, &l);
1146         if (NULL == l)
1147                 return;
1148
1149         _cal_server_alarm_noti_with_callback(l);
1150         _cal_server_alarm_noti_with_control(l);
1151         g_list_free_full(l, free);
1152 }
1153
1154 static int _alert_cb(alarm_id_t alarm_id, void *data)
1155 {
1156         CAL_FN_CALL();
1157         DBG("alarm_id (%d)", (int)alarm_id);
1158
1159         time_t tt_alert = 0;
1160         cal_server_alarm_get_alert_time(alarm_id, &tt_alert);
1161         cal_server_alarm_alert(tt_alert);
1162         cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
1163         cal_server_alarm_start();
1164         return 0;
1165 }
1166
1167 static void _timechanged_cb(keynode_t *node, void *data)
1168 {
1169         cal_server_alarm_alert(time(NULL));
1170         cal_server_alarm_start();
1171 }
1172
1173 static void _cal_server_alarm_set_timechange(void)
1174 {
1175         vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, _timechanged_cb, NULL);
1176         vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT, _timechanged_cb, NULL);
1177         vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE, _timechanged_cb, NULL);
1178         vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT, _timechanged_cb, NULL);
1179 }
1180
1181 static void _cal_server_alarm_unset_timechange(void)
1182 {
1183         vconf_ignore_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, _timechanged_cb);
1184         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT, _timechanged_cb);
1185         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_ZONE, _timechanged_cb);
1186         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT, _timechanged_cb);
1187 }
1188
1189 static void _changed_cb(const char* view_uri, void* data)
1190 {
1191         DBG("Receive alarm change signal");
1192         cal_server_alarm_start();
1193 }
1194
1195 static int _cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
1196 {
1197         cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_FILE_EVENT, callback, NULL);
1198         cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_FILE_TODO, callback, NULL);
1199         return 0;
1200 }
1201
1202 static void _cal_server_alarm_unset_inotify(calendar_db_changed_cb callback)
1203 {
1204         cal_inotify_unsubscribe(CAL_NOTI_FILE_EVENT, callback, NULL);
1205         cal_inotify_unsubscribe(CAL_NOTI_FILE_TODO, callback, NULL);
1206 }
1207
1208 static int cal_server_alarm_init(void)
1209 {
1210         int ret = 0;
1211
1212         _cal_server_alarm_set_timechange();
1213         _cal_server_alarm_set_inotify(_changed_cb);
1214
1215         ret = alarmmgr_set_cb(_alert_cb, NULL);
1216         if (ret < 0) {
1217                 /* LCOV_EXCL_START */
1218                 ERR("alarmmgr_set_cb() Fail(%d)", ret);
1219                 return CALENDAR_ERROR_SYSTEM;
1220                 /* LCOV_EXCL_STOP */
1221         }
1222
1223         ret = alarmmgr_init("calendar-service");
1224         if (ret < 0) {
1225                 /* LCOV_EXCL_START */
1226                 ERR("alarmmgr_init() Fail(%d)", ret);
1227                 return CALENDAR_ERROR_SYSTEM;
1228                 /* LCOV_EXCL_STOP */
1229         }
1230
1231         return CALENDAR_ERROR_NONE;
1232 }
1233
1234 static gpointer _cal_server_alarm_main(gpointer user_data)
1235 {
1236         DBG("thread alarm: start");
1237
1238         int ret = 0;
1239         bool is_initialized = false;
1240
1241         while (1) {
1242                 g_mutex_lock(&_cal_server_alarm_mutex);
1243                 /*
1244                  * While syncing with contacts,
1245                  * because calendar-service could be stopped by on-demand,
1246                  * holding on-demand is needed.
1247                  */
1248                 cal_server_ondemand_hold();
1249
1250                 do {
1251                         if (false == is_initialized) {
1252                                 ret = cal_server_alarm_init();
1253                                 if (CALENDAR_ERROR_NONE != ret) {
1254                                         /* LCOV_EXCL_START */
1255                                         ERR("cal_server_alarm_init() Fail(%d)", ret);
1256                                         break;
1257                                         /* LCOV_EXCL_STOP */
1258                                 }
1259                                 DBG("thread alarm: init");
1260                                 is_initialized = true;
1261                         }
1262
1263                         ret = cal_connect();
1264                         if (CALENDAR_ERROR_NONE != ret) {
1265                                 /* LCOV_EXCL_START */
1266                                 ERR("cal_connect() Fail(%d)", ret);
1267                                 break;
1268                                 /* LCOV_EXCL_STOP */
1269                         }
1270
1271                         cal_server_alarm_register_next_alarm(time(NULL));
1272                         cal_disconnect();
1273
1274                 } while (0);
1275
1276                 cal_server_ondemand_release();
1277                 cal_server_ondemand_start();
1278
1279                 DBG("thread alarm: wait");
1280                 while (false == signal_called)
1281                         g_cond_wait(&_cal_server_alarm_cond, &_cal_server_alarm_mutex);
1282                 signal_called = false;
1283                 g_mutex_unlock(&_cal_server_alarm_mutex);
1284
1285                 if (server_killed)
1286                         break;
1287         }
1288         DBG("thread alarm: end");
1289         g_thread_exit(NULL);
1290
1291         return NULL;
1292 }
1293
1294 void cal_server_alarm_send_signal(void)
1295 {
1296         g_mutex_lock(&_cal_server_alarm_mutex);
1297         signal_called = true;
1298         g_cond_signal(&_cal_server_alarm_cond);
1299         g_mutex_unlock(&_cal_server_alarm_mutex);
1300 }
1301
1302 void cal_server_alarm_start(void)
1303 {
1304         CAL_FN_CALL();
1305
1306         if (NULL == _cal_server_alarm_thread) {
1307                 g_mutex_init(&_cal_server_alarm_mutex);
1308                 g_cond_init(&_cal_server_alarm_cond);
1309                 _cal_server_alarm_thread = g_thread_new(CAL_SERVER_ALARM_THREAD_NAME,
1310                                 _cal_server_alarm_main, NULL);
1311         }
1312         cal_server_alarm_send_signal();
1313 }
1314
1315 static void cal_server_alarm_deinit(void)
1316 {
1317         alarmmgr_fini();
1318         _cal_server_alarm_unset_inotify(_changed_cb);
1319         _cal_server_alarm_unset_timechange();
1320 }
1321
1322 void cal_server_alarm_end(void)
1323 {
1324         CAL_FN_CALL();
1325
1326         server_killed = true;
1327
1328         cal_server_alarm_deinit();
1329         cal_server_alarm_send_signal();
1330
1331         g_cond_clear(&_cal_server_alarm_cond);
1332         g_thread_join(_cal_server_alarm_thread);
1333         g_thread_unref(_cal_server_alarm_thread);
1334         _cal_server_alarm_thread = NULL;
1335 }