[issue#]N_SE-35479
[platform/core/pim/calendar-service.git] / server / cal_server_alarm.c
1 /*
2  * Calendar Service
3  *
4  * Copyright (c) 2012 - 2013 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 <appsvc.h>
23 #include <alarm.h>
24 #include <vconf.h>
25
26 #include "cal_internal.h"
27 #include "calendar2.h"
28 #include "cal_time.h"
29 #include "cal_typedef.h"
30 #include "cal_inotify.h"
31
32 #include "cal_db_util.h"
33 #include "cal_db.h"
34 #include "cal_db_query.h"
35 #include "cal_server_reminder.h"
36
37 static struct timeval stv; // check time
38 static struct timeval etv; // check time
39
40 static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id);
41
42 static int __cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
43 {
44         int ret;
45
46         DBG("remove alarm id(%d)", alarm_id);
47         __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
48         ret = alarmmgr_remove_alarm(alarm_id);
49         if (ret != ALARMMGR_RESULT_SUCCESS)
50         {
51                 ERR("alarmmgr_remove_alarm() failed(ret:%d)", ret);
52                 return ret;
53         }
54         return CALENDAR_ERROR_NONE;
55 }
56
57 struct _normal_data_s
58 {
59         int id;
60         long long int alarm_utime;
61         int tick;
62         int unit;
63         int alarm_id;
64         int record_type;
65 };
66
67 struct _allday_data_s
68 {
69         int id;
70         int alarm_datetime;
71         int tick;
72         int unit;
73         int alarm_id;
74         int record_type;
75 };
76
77 static int __cal_server_alarm_get_next_list_normal_event(long long int from_utime, long long int to_utime, GList **list, int *count)
78 {
79         int index;
80     char query[CAL_DB_SQL_MAX_LEN] = {0};
81     sqlite3_stmt *stmt = NULL;
82
83         DBG("searching normal event (%lld) ~ (%lld)", from_utime, to_utime);
84
85         snprintf(query, sizeof(query),
86                         "SELECT A.event_id, B.alarm_time, "
87                         "B.remind_tick, B.remind_tick_unit, B.alarm_id "
88                         "FROM %s as A, "                       // A is normal instance
89                         "%s as B ON A.event_id = B.event_id, " // B is alarm
90                         "%s as C ON B.event_id = C.id "        // c is schedule
91                         "WHERE C.has_alarm == 1 AND C.type = %d "
92                         "AND B.remind_tick_unit = %d AND B.alarm_time = %lld "
93                         "UNION "
94                         "SELECT A.event_id, A.dtstart_utime - (B.remind_tick * B.remind_tick_unit), "
95                         "B.remind_tick, B.remind_tick_unit, B.alarm_id "
96                         "FROM %s as A, "                       // A is normal instance
97                         "%s as B ON A.event_id = B.event_id, " // B is alarm
98                         "%s as C ON B.event_id = C.id "        // c is schedule
99                         "WHERE C.has_alarm = 1 AND C.type = %d "
100                         "AND B.remind_tick_unit > %d "
101                         "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) >= %lld "
102                         "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) < %lld "
103                         "ORDER BY (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit))",
104                         CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
105                         CALENDAR_BOOK_TYPE_EVENT,
106                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_utime,
107                         CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
108                         CALENDAR_BOOK_TYPE_EVENT,
109                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
110                         from_utime, to_utime);
111
112         stmt = _cal_db_util_query_prepare(query);
113         if (NULL == stmt)
114         {
115                 DBG("query[%s]", query);
116                 ERR("_cal_db_util_query_prepare() Failed");
117                 return CALENDAR_ERROR_DB_FAILED;
118         }
119
120         *count = 0;
121         while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
122         {
123                 struct _normal_data_s *nd = calloc(1, sizeof(struct _normal_data_s));
124
125                 index = 0;
126                 nd->id = sqlite3_column_int(stmt, index++);
127                 nd->alarm_utime = sqlite3_column_int64(stmt, index++);
128                 nd->tick = sqlite3_column_int(stmt, index++);
129                 nd->unit = sqlite3_column_int(stmt, index++);
130                 nd->alarm_id = sqlite3_column_int(stmt, index++);
131
132                 *list = g_list_append(*list, nd);
133                 (*count)++;
134         }
135         sqlite3_finalize(stmt);
136         return CALENDAR_ERROR_NONE;
137 }
138
139 static int __cal_server_alarm_get_next_list_normal_todo(long long int from_utime, long long int to_utime, GList **list, int *count)
140 {
141         int index;
142     char query[CAL_DB_SQL_MAX_LEN] = {0};
143     sqlite3_stmt *stmt = NULL;
144
145         DBG("searching normal todo (%lld) ~ (%lld)", from_utime, to_utime);
146
147         snprintf(query, sizeof(query),
148                         "SELECT B.id, A.alarm_time, "
149                         "A.remind_tick, A.remind_tick_unit, A.alarm_id "
150                         "FROM %s as A, "                          // A is alarm
151                         "%s as B ON A.event_id = B.id "           // B is schedule
152                         "WHERE B.has_alarm == 1 AND B.type = %d "
153                         "AND A.remind_tick_unit = %d AND A.alarm_time = %lld "
154                         "UNION "
155                         "SELECT B.id, B.dtend_utime - (A.remind_tick * A.remind_tick_unit), "
156                         "A.remind_tick, A.remind_tick_unit, A.alarm_id "
157                         "FROM %s as A, "                          // A is alarm
158                         "%s as B ON A.event_id = B.id "           // B is schedule
159                         "WHERE B.has_alarm = 1 AND B.type = %d "
160                         "AND A.remind_tick_unit > %d "
161                         "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) >= %lld "
162                         "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) < %lld "
163                         "ORDER BY (B.dtend_utime - (A.remind_tick * A.remind_tick_unit))",
164                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
165                         CALENDAR_BOOK_TYPE_TODO,
166                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_utime,
167                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
168                         CALENDAR_BOOK_TYPE_TODO,
169                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
170                         from_utime, to_utime);
171
172         stmt = _cal_db_util_query_prepare(query);
173         if (NULL == stmt)
174         {
175                 DBG("query[%s]", query);
176                 ERR("_cal_db_util_query_prepare() Failed");
177                 return CALENDAR_ERROR_DB_FAILED;
178         }
179
180         *count = 0;
181         while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
182         {
183                 struct _normal_data_s *nd = calloc(1, sizeof(struct _normal_data_s));
184
185                 index = 0;
186                 nd->id = sqlite3_column_int(stmt, index++);
187                 nd->alarm_utime = sqlite3_column_int64(stmt, index++);
188                 nd->tick = sqlite3_column_int(stmt, index++);
189                 nd->unit = sqlite3_column_int(stmt, index++);
190                 nd->alarm_id = sqlite3_column_int(stmt, index++);
191
192                 *list = g_list_append(*list, nd);
193                 (*count)++;
194         }
195         sqlite3_finalize(stmt);
196         return CALENDAR_ERROR_NONE;
197 }
198
199 static int __cal_server_alarm_get_next_list_allday_event(int from_datetime, int to_datetime, GList **list, int *count)
200 {
201         int index;
202     char query[CAL_DB_SQL_MAX_LEN] = {0};
203     sqlite3_stmt *stmt = NULL;
204
205         DBG("searching allday (%d) ~ (%d)", from_datetime, to_datetime);
206
207         snprintf(query, sizeof(query),
208                         "SELECT A.event_id, B.alarm_time, "
209                         "B.remind_tick, B.remind_tick_unit, B.alarm_id "
210                         "FROM %s as A, "                       // A is allday instance
211                         "%s as B ON A.event_id = B.event_id, " // B is alarm
212                         "%s as C ON B.event_id = C.id "        // C is schedule
213                         "WHERE C.has_alarm == 1 AND C.type = %d "
214                         "AND B.remind_tick_unit = %d AND B.alarm_time = %d "
215                         "UNION "
216                         "SELECT A.event_id, A.dtstart_datetime, "
217                         "B.remind_tick, B.remind_tick_unit, B.alarm_id "
218                         "FROM %s as A, "                       // A is allday instance
219                         "%s as B ON A.event_id = B.event_id, " // B is alarm
220                         "%s as C ON B.event_id = C.id "        // C is schedule
221                         "WHERE C.has_alarm = 1 AND C.type = %d "
222                         "AND B.remind_tick_unit > %d "
223                         "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 > %d "
224                         "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 <= %d ",
225                         CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
226                         CALENDAR_BOOK_TYPE_EVENT,
227                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_datetime,
228                         CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
229                         CALENDAR_BOOK_TYPE_EVENT,
230                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
231                         from_datetime, to_datetime);
232
233         stmt = _cal_db_util_query_prepare(query);
234         if (NULL == stmt)
235         {
236                 DBG("query[%s]", query);
237                 ERR("_cal_db_util_query_prepare() Failed");
238                 return CALENDAR_ERROR_DB_FAILED;
239         }
240
241         *count = 0;
242         while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
243         {
244                 struct _allday_data_s *ad = calloc(1, sizeof(struct _allday_data_s));
245
246                 index = 0;
247                 ad->id = sqlite3_column_int(stmt, index++);
248                 ad->alarm_datetime = sqlite3_column_int(stmt, index++);
249                 ad->tick = sqlite3_column_int(stmt, index++);
250                 ad->unit = sqlite3_column_int(stmt, index++);
251                 ad->alarm_id = sqlite3_column_int(stmt, index++);
252
253                 *list = g_list_append(*list, ad);
254                 (*count)++;
255         }
256         sqlite3_finalize(stmt);
257         return CALENDAR_ERROR_NONE;
258 }
259
260 static int __cal_server_alarm_get_next_list_allday_todo(int from_datetime, int to_datetime, GList **list, int *count)
261 {
262         int index;
263     char query[CAL_DB_SQL_MAX_LEN] = {0};
264     sqlite3_stmt *stmt = NULL;
265
266         DBG("searching allday todo(%d) ~ (%d)", from_datetime, to_datetime);
267
268         snprintf(query, sizeof(query),
269                         "SELECT A.event_id, A.alarm_time, "
270                         "A.remind_tick, A.remind_tick_unit, A.alarm_id "
271                         "FROM %s as A, "                // A is alarm
272                         "%s as B ON A.event_id = B.id " // B is schedule
273                         "WHERE B.has_alarm == 1 AND B.type = %d "
274                         "AND A.remind_tick_unit = %d AND A.alarm_time = %d "
275                         "UNION "
276                         "SELECT A.event_id, B.dtend_datetime, "
277                         "A.remind_tick, A.remind_tick_unit, A.alarm_id "
278                         "FROM %s as A, "                // A is alarm
279                         "%s as B ON A.event_id = B.id " // B is schedule
280                         "WHERE B.has_alarm = 1 AND B.type = %d "
281                         "AND A.remind_tick_unit > %d "
282                         "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 > %d "
283                         "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 <= %d ",
284                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
285                         CALENDAR_BOOK_TYPE_TODO,
286                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_datetime,
287                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
288                         CALENDAR_BOOK_TYPE_TODO,
289                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
290                         from_datetime, to_datetime);
291
292         stmt = _cal_db_util_query_prepare(query);
293         if (NULL == stmt)
294         {
295                 DBG("query[%s]", query);
296                 ERR("_cal_db_util_query_prepare() Failed");
297                 return CALENDAR_ERROR_DB_FAILED;
298         }
299
300         *count = 0;
301         while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
302         {
303                 struct _allday_data_s *ad = calloc(1, sizeof(struct _allday_data_s));
304
305                 index = 0;
306                 ad->id = sqlite3_column_int(stmt, index++);
307                 ad->alarm_datetime = sqlite3_column_int(stmt, index++);
308                 ad->tick = sqlite3_column_int(stmt, index++);
309                 ad->unit = sqlite3_column_int(stmt, index++);
310                 ad->alarm_id = sqlite3_column_int(stmt, index++);
311
312                 *list = g_list_append(*list, ad);
313                 (*count)++;
314         }
315         sqlite3_finalize(stmt);
316         return CALENDAR_ERROR_NONE;
317 }
318
319 static int __cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
320 {
321     char query[CAL_DB_SQL_MAX_LEN] = {0};
322     cal_db_util_error_e dbret = CAL_DB_OK;
323
324         DBG("Update alarm_id(%d) in alarm table", alarm_id);
325         snprintf(query, sizeof(query), "UPDATE %s SET "
326                         "alarm_id = %d "
327                         "WHERE event_id = %d AND remind_tick = %d AND remind_tick_unit = %d",
328                         CAL_TABLE_ALARM,
329                         alarm_id,
330                         event_id, tick, unit);
331
332         dbret = _cal_db_util_query_exec(query);
333         if (CAL_DB_OK != dbret)
334         {
335                 ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
336                 switch (dbret)
337                 {
338                 case CAL_DB_ERROR_NO_SPACE:
339                         return CALENDAR_ERROR_FILE_NO_SPACE;
340                 default:
341                         return CALENDAR_ERROR_DB_FAILED;
342                 }
343         }
344
345         return CALENDAR_ERROR_NONE;
346 }
347
348 static GFunc __cal_server_alarm_print_list_normal(gpointer data, gpointer user_data)
349 {
350         struct _normal_data_s *normal = (struct _normal_data_s *)data;
351         DBG("%02d:%lld", normal->id, normal->alarm_utime);
352         return 0;
353 }
354
355 static GFunc __cal_server_alarm_print_list_allday_todo(gpointer data, gpointer user_data)
356 {
357         struct _allday_data_s *allday = (struct _allday_data_s *)data;
358         DBG("%02d:%d", allday->id, allday->alarm_datetime);
359         return 0;
360 }
361
362 static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **normal_list, GList **allday_list)
363 {
364         int index;
365     char query[CAL_DB_SQL_MAX_LEN] = {0};
366     sqlite3_stmt *stmt = NULL;
367         struct _normal_data_s *nd;
368         struct _allday_data_s *ad;
369
370         snprintf(query, sizeof(query),
371                         "SELECT A.type, A.dtstart_type, A.dtend_type, B.remind_tick, B.remind_tick_unit "
372                         "FROM %s as A, "                // schedule
373                         "%s as B ON A.id = B.event_id " // alarm
374                         "WHERE B.alarm_id = %d",
375                         CAL_TABLE_SCHEDULE,
376                         CAL_TABLE_ALARM,
377                         alarm_id);
378
379         stmt = _cal_db_util_query_prepare(query);
380         if (NULL == stmt)
381         {
382                 DBG("query[%s]", query);
383                 ERR("_cal_db_util_query_prepare() Failed");
384                 return CALENDAR_ERROR_DB_FAILED;
385         }
386
387         int type = 0;
388         int dtstart_type = 0;
389         int dtend_type = 0;
390         int tick = 0;
391         int unit = 0;
392         if (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
393         {
394                 index = 0;
395                 type = sqlite3_column_int(stmt, index++);
396                 dtstart_type = sqlite3_column_int(stmt, index++);
397                 dtend_type = sqlite3_column_int(stmt, index++);
398                 tick = sqlite3_column_int(stmt, index++);
399                 unit = sqlite3_column_int(stmt, index++);
400         }
401         else
402         {
403                 ERR("No record");
404         }
405         sqlite3_finalize(stmt);
406         stmt = NULL;
407
408         if ((type == CALENDAR_BOOK_TYPE_EVENT && dtstart_type == CALENDAR_TIME_UTIME)
409                         || (type == CALENDAR_BOOK_TYPE_TODO && dtend_type == CALENDAR_TIME_UTIME))
410         {
411                 long long int now_utime;
412                 now_utime = _cal_time_get_now();
413                 now_utime -= now_utime % 60;
414
415                 snprintf(query, sizeof(query),
416                                 "SELECT A.event_id, A.dtstart_utime, "
417                                 "B.remind_tick, B.remind_tick_unit, "
418                                 "C.type "
419                                 "FROM %s as A, "                       // A is normal instance
420                                 "%s as B ON A.event_id = B.event_id, " // B is alarm
421                                 "%s as C ON B.event_id = C.id "        // c is schedule
422                                 "WHERE C.has_alarm == 1 AND C.type = %d "
423                                 "AND B.remind_tick_unit = %d "
424                                 "AND B.alarm_time = %lld "
425                                 "UNION "
426                                 "SELECT A.event_id, A.dtstart_utime, "
427                                 "B.remind_tick, B.remind_tick_unit, "
428                                 "C.type "
429                                 "FROM %s as A, "                       // A is normal instance
430                                 "%s as B ON A.event_id = B.event_id, " // B is alarm
431                                 "%s as C ON B.event_id = C.id "        // c is schedule
432                                 "WHERE C.has_alarm = 1 AND C.type = %d "
433                                 "AND B.remind_tick_unit > %d "
434                                 "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) >= %lld "
435                                 "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) < %lld "
436                                 "UNION "
437                                 "SELECT B.id, B.dtend_utime, "
438                                 "A.remind_tick, A.remind_tick_unit, "
439                                 "B.type "
440                                 "FROM %s as A, "                          // A is alarm
441                                 "%s as B ON A.event_id = B.id "           // B is schedule
442                                 "WHERE B.has_alarm == 1 AND B.type = %d "
443                                 "AND A.remind_tick_unit = %d "
444                                 "AND A.alarm_time = %lld "
445                                 "UNION "
446                                 "SELECT B.id, B.dtend_utime, "
447                                 "A.remind_tick, A.remind_tick_unit, "
448                                 "B.type "
449                                 "FROM %s as A, "                          // A is alarm
450                                 "%s as B ON A.event_id = B.id "           // B is schedule
451                                 "WHERE B.has_alarm = 1 AND B.type = %d "
452                                 "AND A.remind_tick_unit > %d "
453                                 "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) >= %lld "
454                                 "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) < %lld ",
455                         CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
456                         CALENDAR_BOOK_TYPE_EVENT,
457                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
458                         now_utime,
459                         CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
460                         CALENDAR_BOOK_TYPE_EVENT,
461                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
462                         now_utime, now_utime + 60,
463                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
464                         CALENDAR_BOOK_TYPE_TODO,
465                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
466                         now_utime,
467                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
468                         CALENDAR_BOOK_TYPE_TODO,
469                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
470                         now_utime, now_utime + 60);
471
472                 stmt = _cal_db_util_query_prepare(query);
473                 if (NULL == stmt)
474                 {
475                         DBG("query[%s]", query);
476                         ERR("_cal_db_util_query_prepare() Failed");
477                         return CALENDAR_ERROR_DB_FAILED;
478                 }
479
480                 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
481                 {
482                         index = 0;
483                         nd = calloc(1, sizeof(struct _normal_data_s));
484                         nd->id = sqlite3_column_int(stmt, index++);
485                         nd->alarm_utime = sqlite3_column_int64(stmt, index++); // dtstart, dtend
486                         nd->tick = sqlite3_column_int(stmt, index++);
487                         nd->unit = sqlite3_column_int(stmt, index++);
488                         nd->record_type = sqlite3_column_int(stmt, index++); // event, todo
489                         *normal_list = g_list_append(*normal_list, nd);
490                         DBG("(%d)", nd->id);
491                 }
492         }
493         else
494         {
495                 int now_datetime;
496                 time_t now_timet = time(NULL);
497                 struct tm start_tm = {0};
498                 now_timet -= now_timet % 60;
499                 gmtime_r(&now_timet, &start_tm);
500                 now_datetime = (start_tm.tm_year + 1900) * 10000
501                         + (start_tm.tm_mon + 1) * 100
502                         + (start_tm.tm_mday);
503
504                 snprintf(query, sizeof(query),
505                                 "SELECT A.event_id, A.dtstart_datetime, "
506                                 "B.remind_tick, B.remind_tick_unit, "
507                                 "C.type "
508                                 "FROM %s as A, "                       // A is allday instance
509                                 "%s as B ON A.event_id = B.event_id, " // B is alarm
510                                 "%s as C ON B.event_id = C.id "        // C is schedule
511                                 "WHERE C.has_alarm == 1 AND C.type = %d "
512                                 "AND B.remind_tick_unit = %d "
513                                 "AND B.alarm_time = %d "
514                                 "UNION "
515                                 "SELECT A.event_id, A.dtstart_datetime, "
516                                 "B.remind_tick, B.remind_tick_unit, "
517                                 "C.type "
518                                 "FROM %s as A, "                       // A is allday instance
519                                 "%s as B ON A.event_id = B.event_id, " // B is alarm
520                                 "%s as C ON B.event_id = C.id "        // C is schedule
521                                 "WHERE C.has_alarm = 1 AND C.type = %d "
522                                 "AND B.remind_tick_unit > %d "
523                                 "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 = %d "
524                                 "UNION "
525                                 "SELECT A.event_id, B.dtend_datetime, "
526                                 "A.remind_tick, A.remind_tick_unit, "
527                                 "B.type "
528                                 "FROM %s as A, "                // A is alarm
529                                 "%s as B ON A.event_id = B.id " // B is schedule
530                                 "WHERE B.has_alarm == 1 AND B.type = %d "
531                                 "AND A.remind_tick_unit = %d AND A.alarm_time = %d "
532                                 "UNION "
533                                 "SELECT A.event_id, B.dtend_datetime, "
534                                 "A.remind_tick, A.remind_tick_unit, "
535                                 "B.type "
536                                 "FROM %s as A, "                // A is alarm
537                                 "%s as B ON A.event_id = B.id " // B is schedule
538                                 "WHERE B.has_alarm = 1 AND B.type = %d "
539                                 "AND A.remind_tick_unit > %d "
540                                 "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 = %d ",
541                         CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
542                         CALENDAR_BOOK_TYPE_EVENT,
543                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
544                         now_datetime,
545                         CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
546                         CALENDAR_BOOK_TYPE_EVENT,
547                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
548                         now_datetime,
549                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
550                         CALENDAR_BOOK_TYPE_TODO,
551                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
552                         now_datetime,
553                         CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
554                         CALENDAR_BOOK_TYPE_TODO,
555                         CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
556                         now_datetime);
557
558                 stmt = _cal_db_util_query_prepare(query);
559                 if (NULL == stmt)
560                 {
561                         DBG("query[%s]", query);
562                         ERR("_cal_db_util_query_prepare() Failed");
563                         return CALENDAR_ERROR_DB_FAILED;
564                 }
565
566                 const unsigned char *temp;
567                 while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
568                 {
569                         index = 0;
570                         ad = calloc(1, sizeof(struct _allday_data_s));
571                         ad->id = sqlite3_column_int(stmt, index++);
572                         temp = sqlite3_column_text(stmt, index++); // dtstart, dtend
573                         ad->alarm_datetime = atoi((const char *)temp);
574                         ad->tick = sqlite3_column_int(stmt, index++);
575                         ad->unit = sqlite3_column_int(stmt, index++);
576                         ad->record_type = sqlite3_column_int(stmt, index++);
577                         *allday_list = g_list_append(*allday_list, ad);
578                 }
579         }
580         sqlite3_finalize(stmt);
581         return CALENDAR_ERROR_NONE;
582 }
583
584 // this api is necessary for repeat instance.
585 static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
586 {
587     char query[CAL_DB_SQL_MAX_LEN] = {0};
588     cal_db_util_error_e dbret = CAL_DB_OK;
589
590         DBG("alarm_id(%d)", alarm_id);
591
592         snprintf(query, sizeof(query),
593                         "UPDATE %s SET alarm_id = 0 WHERE alarm_id = %d ",
594                         CAL_TABLE_ALARM, alarm_id);
595
596         dbret = _cal_db_util_query_exec(query);
597         if (CAL_DB_OK != dbret)
598         {
599                 ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
600                 switch (dbret)
601                 {
602                 case CAL_DB_ERROR_NO_SPACE:
603                         return CALENDAR_ERROR_FILE_NO_SPACE;
604                 default:
605                         return CALENDAR_ERROR_DB_FAILED;
606                 }
607         }
608
609         return CALENDAR_ERROR_NONE;
610 }
611
612 static int __cal_server_alarm_alert_with_pkgname(const char *pkgname, char *id, char *time, char *tick, char *unit, char *type)
613 {
614         int ret = CALENDAR_ERROR_NONE;
615         int index;
616     char query[CAL_DB_SQL_MAX_LEN] = {0};
617         const char *key;
618         const char *value;
619     sqlite3_stmt *stmt = NULL;
620     cal_db_util_error_e dbret = CAL_DB_OK;
621
622         if (NULL == pkgname)
623         {
624                 ERR("Invalid parameter: pkgname is NULL");
625                 return CALENDAR_ERROR_INVALID_PARAMETER;
626         }
627
628         // get user key, value
629         snprintf(query, sizeof(query), "SELECT key, value FROM %s WHERE pkgname = '%s' ",
630                         CAL_REMINDER_ALERT, pkgname);
631     stmt = _cal_db_util_query_prepare(query);
632     if (NULL == stmt)
633     {
634         ERR("_cal_db_util_query_prepare() Failed");
635         return CALENDAR_ERROR_DB_FAILED;
636     }
637
638     while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
639     {
640                 index = 0;
641                 key = (const char *)sqlite3_column_text(stmt, index++);
642                 value = (const char *)sqlite3_column_text(stmt, index++);
643         }
644
645         // run appsvc
646         DBG("[%s][%s][%s][%s]", id, time, tick, unit);
647
648         bundle *b;
649         b = bundle_create();
650         appsvc_set_pkgname(b, pkgname);
651         appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT);
652         if (key && value) appsvc_add_data(b, key, value);
653         appsvc_add_data(b, "id", id);
654         appsvc_add_data(b, "time", time);
655         appsvc_add_data(b, "tick", tick);
656         appsvc_add_data(b, "unit", unit);
657         appsvc_add_data(b, "type", type);
658         ret = appsvc_run_service(b, 0, NULL, NULL);
659         bundle_free(b);
660
661         sqlite3_finalize(stmt);
662
663         // if no app, delete from the table
664         if (APPSVC_RET_ELAUNCH == ret)
665         {
666                 DBG("Deleted no responce pkg[%s]", pkgname);
667                 snprintf(query, sizeof(query), "DELETE FROM %s WHERE pkgname = '%s' ",
668                                 CAL_REMINDER_ALERT, pkgname);
669                 dbret = _cal_db_util_query_exec(query);
670                 if (CAL_DB_OK != dbret)
671                 {
672                         ERR("_cal_db_util_query_exec() failed(ret:%d)", ret);
673                         switch (dbret)
674                         {
675                         case CAL_DB_ERROR_NO_SPACE:
676                                 return CALENDAR_ERROR_FILE_NO_SPACE;
677                         default:
678                                 return CALENDAR_ERROR_DB_FAILED;
679                         }
680                 }
681
682         }
683         return CALENDAR_ERROR_NONE;
684 }
685
686 static int __cal_server_alarm_alert(char *id, char *time, char *tick, char *unit, char *type)
687 {
688         int index;
689     char query[CAL_DB_SQL_MAX_LEN] = {0};
690     sqlite3_stmt *stmt = NULL;
691
692         snprintf(query, sizeof(query), "SELECT pkgname FROM %s WHERE onoff = 1 ",
693                         CAL_REMINDER_ALERT);
694     stmt = _cal_db_util_query_prepare(query);
695     if (NULL == stmt)
696     {
697         ERR("_cal_db_util_query_prepare() Failed");
698         return CALENDAR_ERROR_DB_FAILED;
699     }
700
701     while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
702     {
703                 index = 0;
704                 const char *pkgname = (const char *)sqlite3_column_text(stmt, index++);
705                 DBG("pkgname[%s]", pkgname);
706                 __cal_server_alarm_alert_with_pkgname(pkgname, id, time, tick, unit, type);
707         }
708         sqlite3_finalize(stmt);
709
710         return CALENDAR_ERROR_NONE;
711 }
712
713 static int __cal_server_alarm_noti_with_appsvc(int alarm_id, GList *normal_list, GList *allday_list)
714 {
715         char buf_id[128] = {0};
716         char buf_time[128] = {0};
717         char buf_tick[128] = {0};
718         char buf_unit[128] = {0};
719         char buf_type[128] = {0};
720         GList *l = NULL;
721
722         l = g_list_first(normal_list);
723         if (NULL == l) DBG("normal list is NULL");
724         while (l)
725         {
726                 struct _normal_data_s *nd = (struct _normal_data_s *)l->data;
727                 snprintf(buf_id, sizeof(buf_id), "%d", nd->id);
728                 snprintf(buf_time, sizeof(buf_time), "%lld", nd->alarm_utime);
729                 snprintf(buf_tick, sizeof(buf_tick), "%d", nd->tick);
730                 snprintf(buf_unit, sizeof(buf_unit), "%d", nd->unit);
731                 snprintf(buf_type, sizeof(buf_type), "%d", nd->record_type);
732
733                 __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit, buf_type);
734                 l = g_list_next(l);
735         }
736
737         l = NULL;
738         l = g_list_first(allday_list);
739         if (NULL == l) DBG("allday list is NULL");
740         while (l)
741         {
742                 struct _allday_data_s *ad = (struct _allday_data_s *)l->data;
743                 snprintf(buf_id, sizeof(buf_id), "%d",  ad->id);
744                 snprintf(buf_time, sizeof(buf_time), "%d", ad->alarm_datetime);
745                 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
746                 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
747                 snprintf(buf_type, sizeof(buf_type), "%d", ad->record_type);
748
749                 __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit, buf_type);
750                 l = g_list_next(l);
751         }
752         return CALENDAR_ERROR_NONE;
753 }
754
755 static int __cal_server_alarm_register_next_normal(long long int now_utime, GList *normal_list)
756 {
757         int ret;
758         int alarm_id;
759         struct _normal_data_s *nd;
760
761         GList *l = g_list_first(normal_list);
762
763         // try to save the first record.
764         // if alarm id exists, it means updated record is not earilier than already registerd one.
765         nd = (struct _normal_data_s *)l->data;
766         if (NULL == nd)
767         {
768                 ERR("No data");
769                 return CALENDAR_ERROR_DB_FAILED;
770         }
771
772         if (nd->alarm_id > 0)
773         {
774                 DBG("Already registered this id");
775                 return CALENDAR_ERROR_NONE;
776         }
777
778         DBG("new is earilier than registered.");
779
780         // clear all alarm which set by mine.
781         ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
782         if (ret != ALARMMGR_RESULT_SUCCESS)
783         {
784                 ERR("alarmmgr_enum_alarm_ids() failed");
785                 return ret;
786         }
787
788         // register new list
789         long long int mod_alarm_utime; // del seconds
790         mod_alarm_utime = nd->alarm_utime - (nd->alarm_utime % 60);
791 //      ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, (time_t)(mod_alarm_utime - now_utime), 0, NULL, &alarm_id);
792
793 ///////////////////////////////////////
794         alarm_entry_t *alarm_info = NULL;
795         alarm_info = alarmmgr_create_alarm();
796         if (NULL == alarm_info)
797         {
798                 ERR("Failed to create alarm");
799                 return CALENDAR_ERROR_DB_FAILED;
800         }
801         char *tzid = NULL;
802         tzid = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
803
804         alarm_date_t alarm_date;
805         _cal_time_utoi(mod_alarm_utime, tzid,
806                         &alarm_date.year, &alarm_date.month, &alarm_date.day,
807                         &alarm_date.hour, &alarm_date.min, &alarm_date.sec);
808         DBG("tzid[%s] datetime(%04d/%02d/%02d %02d:%02d:%02d", tzid,
809                         alarm_date.year, alarm_date.month, alarm_date.day,
810                         alarm_date.hour, alarm_date.min, alarm_date.sec);
811
812         alarmmgr_set_time(alarm_info, alarm_date);
813         ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
814         if (tzid) free(tzid);
815 ///////////////////////////////////////
816
817         if (ret < 0)
818         {
819                 ERR("alarmmgr_add_alarm_appsvc failed (%d)", ret);
820                 return ret;
821         }
822         DBG("Get normal alarmmgr id (%d)", alarm_id);
823         __cal_server_alarm_update_alarm_id(alarm_id, nd->id, nd->tick, nd->unit);
824
825         return CALENDAR_ERROR_NONE;
826 }
827
828 static int __cal_server_alarm_register_next_allday(time_t now_timet, GList *allday_list)
829 {
830         int ret;
831         int alarm_id;
832         struct _allday_data_s *ad;
833         time_t alarm_timet;
834
835         GList *l = g_list_first(allday_list);
836         alarm_id = 0;
837         ad = (struct _allday_data_s *)l->data;
838         if (NULL == ad)
839         {
840                 ERR("No data");
841                 return CALENDAR_ERROR_DB_FAILED;
842         }
843
844         if (ad->alarm_id > 0)
845         {
846                 DBG("Already registered this id");
847                 return CALENDAR_ERROR_NONE;
848         }
849
850         DBG("new is earilier than registered.");
851
852         // clear all alarm which set by mine.
853         ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
854         if (ret != ALARMMGR_RESULT_SUCCESS)
855         {
856                 ERR("alarmmgr_enum_alarm_ids() failed");
857                 return ret;
858         }
859
860         // register new list
861 //      ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, (time_t)(alarm_timet - (ad->tick * ad->unit) - now_timet), 0, NULL, &alarm_id);
862
863 ///////////////////////////////////////
864         alarm_entry_t *alarm_info = NULL;
865         alarm_info = alarmmgr_create_alarm();
866         if (NULL == alarm_info)
867         {
868                 ERR("Failed to create alarm");
869                 return CALENDAR_ERROR_DB_FAILED;
870         }
871         char *tzid = NULL;
872         tzid = vconf_get_str(VCONFKEY_SETAPPL_TIMEZONE_ID);
873
874         alarm_date_t alarm_date;
875         _cal_time_utoi((long long int)(alarm_timet - (ad->tick * ad->unit)), tzid,
876                         &alarm_date.year, &alarm_date.month, &alarm_date.day,
877                         &alarm_date.hour, &alarm_date.min, &alarm_date.sec);
878         alarmmgr_set_time(alarm_info, alarm_date);
879         ret = alarmmgr_add_alarm_with_localtime(alarm_info, NULL, &alarm_id);
880         if (tzid) free(tzid);
881 ///////////////////////////////////////
882
883         if (ret < 0)
884         {
885                 ERR("alarmmgr_add_alarm_appsvc failed (%d)", ret);
886                 return ret;
887         }
888         DBG("Get allday alarmmgr id (%d)", alarm_id);
889         __cal_server_alarm_update_alarm_id(alarm_id, ad->id, ad->tick, ad->unit);
890
891         return CALENDAR_ERROR_NONE;
892 }
893
894 static gint __cal_server_alarm_normal_sort_cb(gconstpointer a, gconstpointer b)
895 {
896         struct _normal_data_s *p1 = (struct _normal_data_s *)a;
897         struct _normal_data_s *p2 = (struct _normal_data_s *)b;
898
899         return p1->alarm_utime - p2->alarm_utime > 0 ? 1 : -1;
900 }
901
902 static gint __cal_server_alarm_allday_sort_cb(gconstpointer a, gconstpointer b)
903 {
904         struct _allday_data_s *p1 = (struct _allday_data_s *)a;
905         struct _allday_data_s *p2 = (struct _allday_data_s *)b;
906
907         return p1->alarm_datetime - p2->alarm_datetime > 0 ? 1 : -1;
908 }
909
910 static int __cal_server_alarm_register_with_alarmmgr(long long int now_utime)
911 {
912         GList *normal_list = NULL;
913         GList *allday_list = NULL;
914         int event_count;
915         int todo_count;
916         int loop_count;
917
918         gettimeofday(&stv, NULL); // check time
919
920         // for normal
921         long long int from_utime, to_utime;
922
923         event_count = 0;
924         todo_count = 0;
925         to_utime = now_utime - (now_utime %  60) + 60;
926
927         // searching 3months, next 6months, next 12months
928         for (loop_count = 1; loop_count < 4; loop_count++)
929         {
930                 from_utime = to_utime;
931                 to_utime = from_utime + (60 * 60 * 24 * 30 * 3 * loop_count);
932                 __cal_server_alarm_get_next_list_normal_event(from_utime, to_utime, &normal_list, &event_count);
933                 __cal_server_alarm_get_next_list_normal_todo(from_utime, to_utime, &normal_list, &todo_count);
934                 if (event_count + todo_count > 0)
935                 {
936                         break;
937                 }
938         }
939         DBG("event count(%d) todo count(%d)", event_count, todo_count);
940
941         if (event_count + todo_count > 0)
942         {
943                 normal_list = g_list_sort(normal_list, __cal_server_alarm_normal_sort_cb);
944                 DBG("after sorting");
945                 g_list_foreach(normal_list, (GFunc)__cal_server_alarm_print_list_normal, NULL);
946                 __cal_server_alarm_register_next_normal(now_utime, normal_list);
947
948         }
949         if (normal_list)
950         {
951                 g_list_free_full(normal_list, free);
952                 normal_list = NULL;
953         }
954
955         // for allday
956         DBG("allday");
957         time_t now_timet;
958         time_t from_timet, to_timet;
959         int from_datetime, to_datetime;
960         struct tm datetime_tm;
961         now_timet = (time_t)now_utime;
962
963         event_count = 0;
964         todo_count = 0;
965         to_timet = now_timet;
966
967         // searching 3months, next 6months, next 12months
968         for (loop_count = 1; loop_count < 4; loop_count++)
969         {
970                 from_timet = to_timet;
971                 gmtime_r(&from_timet, &datetime_tm);
972                 from_datetime = (1900 + datetime_tm.tm_year) * 10000 + (datetime_tm.tm_mon + 1) * 100 + datetime_tm.tm_mday;
973
974                 to_timet = from_timet + (60 * 60 * 24 * 30 * 3 * loop_count);
975                 gmtime_r(&to_timet, &datetime_tm);
976                 to_datetime = (1900 + datetime_tm.tm_year) * 10000 + (datetime_tm.tm_mon + 1) * 100 + datetime_tm.tm_mday;
977
978                 __cal_server_alarm_get_next_list_allday_event(from_datetime, to_datetime, &allday_list, &event_count);
979                 __cal_server_alarm_get_next_list_allday_todo(from_datetime, to_datetime, &allday_list, &todo_count);
980
981                 if (event_count + todo_count > 0)
982                 {
983                         break;
984                 }
985         }
986         DBG("event count(%d) todo count(%d)", event_count, todo_count);
987
988         if (event_count + todo_count > 0)
989         {
990                 allday_list = g_list_sort(allday_list, __cal_server_alarm_allday_sort_cb);
991                 DBG("after sorting");
992                 g_list_foreach(allday_list, (GFunc)__cal_server_alarm_print_list_allday_todo, NULL);
993                 __cal_server_alarm_register_next_allday(now_timet, allday_list);
994         }
995         if (allday_list)
996         {
997                 g_list_free_full(allday_list, free);
998                 allday_list = NULL;
999         }
1000
1001         int diff;
1002         gettimeofday(&etv, NULL);
1003         diff = ((int)etv.tv_sec *1000 + (int)etv.tv_usec/1000)
1004                 -((int)stv.tv_sec *1000 + (int)stv.tv_usec/1000);
1005         DBG("registering time diff %ld(%d.%d)",diff, diff/1000, diff%1000); // time check
1006         return 0;
1007 }
1008
1009 static int __cal_server_alarm_callback(char *id, char *time, char *tick, char *unit, char *type)
1010 {
1011         _cal_server_reminder_add_callback_data("id", id);
1012         _cal_server_reminder_add_callback_data("time", time);
1013         _cal_server_reminder_add_callback_data("tick", tick);
1014         _cal_server_reminder_add_callback_data("unit", unit);
1015         _cal_server_reminder_add_callback_data("type", type);
1016
1017         return CALENDAR_ERROR_NONE;
1018 }
1019
1020 static int __cal_server_alarm_noti_callback(int alarm_id, GList *normal_list, GList *allday_list)
1021 {
1022         char buf_id[128] = {0};
1023         char buf_time[128] = {0};
1024         char buf_tick[128] = {0};
1025         char buf_unit[128] = {0};
1026         char buf_type[128] = {0};
1027         GList *l = NULL;
1028
1029         l = g_list_first(normal_list);
1030         if (NULL == l) DBG("normal list is NULL");
1031         while (l)
1032         {
1033                 struct _normal_data_s *nd = (struct _normal_data_s *)l->data;
1034                 snprintf(buf_id, sizeof(buf_id), "%d", nd->id);
1035                 snprintf(buf_time, sizeof(buf_time), "%lld", nd->alarm_utime);
1036                 snprintf(buf_tick, sizeof(buf_tick), "%d", nd->tick);
1037                 snprintf(buf_unit, sizeof(buf_unit), "%d", nd->unit);
1038                 snprintf(buf_type, sizeof(buf_type), "%d", nd->record_type);
1039
1040                 __cal_server_alarm_callback(buf_id, buf_time, buf_tick, buf_unit, buf_type);
1041                 _cal_server_reminder_publish();
1042                 l = g_list_next(l);
1043         }
1044
1045         l = NULL;
1046         l = g_list_first(allday_list);
1047         if (NULL == l) DBG("allday list is NULL");
1048         while (l)
1049         {
1050                 struct _allday_data_s *ad = (struct _allday_data_s *)l->data;
1051                 snprintf(buf_id, sizeof(buf_id), "%d",  ad->id);
1052                 snprintf(buf_time, sizeof(buf_time), "%d", ad->alarm_datetime);
1053                 snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
1054                 snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
1055                 snprintf(buf_type, sizeof(buf_type), "%d", ad->record_type);
1056
1057                 __cal_server_alarm_callback(buf_id, buf_time, buf_tick, buf_unit, buf_type);
1058                 _cal_server_reminder_publish();
1059                 l = g_list_next(l);
1060         }
1061         return 0;
1062 }
1063
1064 static int _alert_cb(alarm_id_t alarm_id, void *data)
1065 {
1066         GList *normal_list = NULL;
1067         GList *allday_list = NULL;
1068
1069         __cal_server_alarm_get_list_with_alarmmgr_id(alarm_id, &normal_list, &allday_list);
1070         __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
1071         __cal_server_alarm_noti_with_appsvc(alarm_id, normal_list, allday_list);
1072         __cal_server_alarm_noti_callback(alarm_id, normal_list, allday_list);
1073
1074         if (normal_list)
1075         {
1076                 g_list_free_full(normal_list, free);
1077                 normal_list = NULL;
1078         }
1079         if (allday_list)
1080         {
1081                 g_list_free_full(allday_list, free);
1082                 allday_list = NULL;
1083         }
1084
1085         __cal_server_alarm_register_with_alarmmgr(_cal_time_get_now());
1086         return 0;
1087 }
1088
1089 ////////////////////////////////////////////////////////////////////
1090 static void __cal_server_alarm_timechange_cb(keynode_t *node, void *data)
1091 {
1092         time_t t;
1093         if (node) {
1094                 t = vconf_keynode_get_int(node);
1095         }
1096         else
1097         {
1098                 vconf_get_int(VCONFKEY_SYSTEM_TIMECHANGE, (int *)&t);
1099         }
1100
1101         DBG("systme changed time(%ld)", t);
1102         __cal_server_alarm_register_with_alarmmgr((long long int)t);
1103 }
1104
1105 int __cal_server_alarm_set_timechange(void)
1106 {
1107         int ret;
1108
1109         ret = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIMECHANGE,
1110                         __cal_server_alarm_timechange_cb, NULL);
1111         if (ret < 0)
1112         {
1113                 ERR("vconf_ignore_key_changed() failed");
1114                 return ret;
1115         }
1116         return CALENDAR_ERROR_NONE;
1117 }
1118
1119 static void __changed_cb(const char* view_uri, void* data)
1120 {
1121         __cal_server_alarm_register_with_alarmmgr(_cal_time_get_now());
1122 }
1123
1124 static int __cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
1125 {
1126         _cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
1127         _cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
1128         return 0;
1129 }
1130
1131 int _cal_server_alarm(void)
1132 {
1133         int ret;
1134
1135         __cal_server_alarm_set_timechange();
1136         __cal_server_alarm_set_inotify(__changed_cb);
1137
1138         ret = alarmmgr_init("calendar-service");
1139         retvm_if(ret < 0, ret, "alarmmgr_init() failed");
1140
1141         ret = alarmmgr_set_cb(_alert_cb, NULL);
1142         retvm_if(ret < 0, ret, "alarmmgr_set_cb() failed");
1143
1144         __cal_server_alarm_register_with_alarmmgr(_cal_time_get_now());
1145
1146         return CALENDAR_ERROR_NONE;
1147 }
1148