baabca21e6a54691174d9a4e2042a9ca2c8e9552
[platform/core/appfw/alarm-manager.git] / lib / alarm-lib.c
1 /*
2  * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define _GNU_SOURCE
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <errno.h>
20 #include <unistd.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <sys/time.h>
24 #include <string.h>
25 #include <glib.h>
26 #include <fcntl.h>
27
28 #include "alarm.h"
29 #include "alarm-internal.h"
30 #include <bundle.h>
31 #include <appsvc.h>
32 #include <aul.h>
33 #include <gio/gio.h>
34 #include <pkgmgr-info.h>
35 #include <notification.h>
36 #include <tzplatform_config.h>
37
38 #ifndef EXPORT_API
39 #define EXPORT_API __attribute__ ((visibility("default")))
40 #endif
41
42 static char g_appid[MAX_APP_ID_LEN];
43 static int flag_appid_checked;
44
45 static alarm_context_t alarm_context;
46
47 static bool b_initialized;
48 static bool sub_initialized;
49
50 static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;
51
52 static void __handle_expiry_method_call(GDBusConnection *conn,
53         const gchar *name, const gchar *path, const gchar *interface,
54         const gchar *method, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data);
55
56 static int __alarm_validate_date(alarm_date_t *date, int *error_code);
57 static bool __alarm_validate_time(alarm_date_t *date, int *error_code);
58 static int __sub_init(void);
59 static int __alarmmgr_init_appsvc(void);
60
61 typedef struct _alarm_cb_info_t {
62         alarm_id_t alarm_id;
63         alarm_cb_t cb_func;
64         void *priv_data;
65         struct _alarm_cb_info_t *next;
66 } alarm_cb_info_t;
67
68 struct alarm_async_param_t {
69         enum async_param_type type;
70         GVariant *v;
71         alarm_set_time_cb_t result_cb;
72         void *user_param;
73 };
74
75 static alarm_cb_info_t *alarmcb_head;
76
77 guint registration_id;
78
79 static GDBusNodeInfo *introspection_data;
80
81 static const gchar introspection_xml[] =
82         "<node name='/org/tizen/alarm/client'>"
83         "  <interface name='org.tizen.alarm.client'>"
84         "    <method name='alarm_expired'>"
85         "      <arg type='i' name='alarm_id' direction='in'/>"
86         "      <arg type='i' name='msec' direction='in'/>"
87         "      <arg type='s' name='service_name' direction='in'/>"
88         "    </method>"
89         "  </interface>"
90         "</node>";
91
92 static const GDBusInterfaceVTable interface_vtable = {
93         __handle_expiry_method_call,
94         NULL,
95         NULL
96 };
97
98 void _initialize_alarm_info(alarm_info_t *alarm_info, int alarm_type,
99                 time_t trigger_at_time, time_t interval, bool precision)
100 {
101         struct timeval current_time;
102         struct tm duetime_tm;
103
104         gettimeofday(&current_time, NULL);
105
106         memset(alarm_info, 0, sizeof(alarm_info_t));
107
108         alarm_info->mode.repeat = ALARM_REPEAT_MODE_ONCE;
109         alarm_info->alarm_type = alarm_type;
110
111         if (current_time.tv_usec > 500 * 1000) {
112                 /* When the millisecond part of the current_time is bigger than 500ms,
113                  * the duetime increases by extra 1sec. */
114                 current_time.tv_sec += (trigger_at_time + 1);
115         } else {
116                 current_time.tv_sec += trigger_at_time;
117         }
118         alarm_info->reserved_info = current_time.tv_sec;
119
120         tzset(); /* Processes the TZ environment variable, and Set timezone, daylight, and tzname. */
121         localtime_r(&current_time.tv_sec, &duetime_tm);
122
123         alarm_info->start.year = duetime_tm.tm_year + 1900;
124         alarm_info->start.month = duetime_tm.tm_mon + 1;
125         alarm_info->start.day = duetime_tm.tm_mday;
126
127         alarm_info->end.year = 0;
128         alarm_info->end.month = 0;
129         alarm_info->end.day = 0;
130
131         alarm_info->start.hour = duetime_tm.tm_hour;
132         alarm_info->start.min = duetime_tm.tm_min;
133         alarm_info->start.sec = duetime_tm.tm_sec;
134
135         if (interval <= 0) {
136                 alarm_info->mode.repeat = ALARM_REPEAT_MODE_ONCE;
137                 alarm_info->mode.u_interval.interval = 0;
138         } else {
139                 alarm_info->mode.repeat = ALARM_REPEAT_MODE_REPEAT;
140                 alarm_info->mode.u_interval.interval = interval;
141         }
142
143         alarm_info->msec = precision ? (int)current_time.tv_usec / 1000 : 0;
144
145         LOGD("trigger_at_time(%ld), start(%d-%d-%d, %02d:%02d:%02d),\
146                         repeat(%d), interval(%ld), type(%d)",
147                         trigger_at_time, alarm_info->start.day, alarm_info->start.month,
148                         alarm_info->start.year, alarm_info->start.hour,
149                         alarm_info->start.min, alarm_info->start.sec,
150                         alarm_info->mode.repeat, alarm_info->mode.u_interval.interval,
151                         alarm_info->alarm_type);
152 }
153
154 static void __add_resultcb(alarm_id_t alarm_id, alarm_cb_t cb_func, void *data)
155 {
156         alarm_cb_info_t *info;
157
158         info = (alarm_cb_info_t *) malloc(sizeof(alarm_cb_info_t));
159         if (info == NULL)
160                 return;
161         info->alarm_id = alarm_id;
162         info->cb_func = cb_func;
163         info->priv_data = data;
164
165         info->next = alarmcb_head;
166         alarmcb_head = info;
167 }
168
169 static alarm_cb_info_t *__find_resultcb(alarm_id_t alarm_id)
170 {
171         alarm_cb_info_t *tmp;
172
173         tmp = alarmcb_head;
174         while (tmp) {
175                 if (tmp->alarm_id == alarm_id) {
176                         LOGD("matched alarm id =  %d", alarm_id);
177                         return tmp;
178                 }
179                 tmp = tmp->next;
180         }
181         return NULL;
182 }
183
184 static void __remove_resultcb(alarm_cb_info_t *info)
185 {
186         alarm_cb_info_t *tmp;
187
188         if (alarmcb_head == NULL || info == NULL)
189                 return;
190
191         if (alarmcb_head == info) {
192                 alarmcb_head = info->next;
193                 free(info);
194                 return;
195         }
196
197         tmp = alarmcb_head;
198         while (tmp) {
199                 if (tmp->next == info) {
200                         tmp->next = info->next;
201                         free(info);
202                         return;
203                 }
204                 tmp = tmp->next;
205         }
206 }
207
208 static gboolean __handle_millisec_accuracy(gpointer data)
209 {
210         if (data == NULL) {
211                 alarm_context.alarm_handler(alarm_context.handler_id,
212                                 alarm_context.user_param);
213         } else {
214                 alarm_cb_info_t *info = (alarm_cb_info_t *)data;
215                 info->cb_func(info->alarm_id, info->priv_data);
216         }
217         return FALSE;
218 }
219
220 static void __handle_expiry_method_call(GDBusConnection *conn,
221                 const gchar *name, const gchar *path, const gchar *interface,
222                 const gchar *method, GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
223 {
224         struct timeval current_time;
225
226         if (method && strcmp(method, "alarm_expired") == 0) {
227                 gchar *package_name = NULL;
228                 alarm_id_t alarm_id = 0;
229                 alarm_cb_info_t *info = NULL;
230                 int msec;
231
232                 g_variant_get(param, "(ii&s)", &alarm_id, &msec, &package_name);
233                 LOGD("[alarm-lib] : Alarm expired for [%s] : Alarm id [%d]", package_name, alarm_id);
234
235                 if (msec > 0) {
236                         gettimeofday(&current_time, NULL);
237                         msec =  msec - (int)current_time.tv_usec / 1000;
238                 }
239
240                 if (alarm_context.alarm_handler != NULL) {
241                         if (msec > 0) {
242                                 alarm_context.handler_id = alarm_id;
243                                 g_timeout_add_full(G_PRIORITY_HIGH, (guint)msec,
244                                                 __handle_millisec_accuracy, NULL, NULL);
245                         } else {
246                                 alarm_context.alarm_handler(alarm_id,
247                                                 alarm_context.user_param);
248                         }
249                 }
250
251                 info = __find_resultcb(alarm_id);
252                 if (info && info->cb_func) {
253                         if (msec > 0) {
254                                 g_timeout_add_full(G_PRIORITY_HIGH, (guint)msec,
255                                                 __handle_millisec_accuracy, info, NULL);
256                         } else {
257                                 LOGW("[alarm-lib] Call expired callback");
258                                 info->cb_func(alarm_id, info->priv_data);
259                         }
260                 }
261         }
262         g_dbus_method_invocation_return_value(invocation, NULL);
263 }
264
265 static int __alarm_validate_date(alarm_date_t *date, int *error_code)
266 {
267         if (date->year == 0 && date->month == 0 && date->day == 0)
268                 return true;
269
270         int year = date->year;
271         int month = date->month;
272         int day = date->day;
273
274         if (month < 1 || month > 12) {
275                 if (error_code)
276                         *error_code = ERR_ALARM_INVALID_DATE;
277                 return false;
278         }
279
280         if ((month == 1 || month == 3 || month == 5 || month == 7 || month == 8
281                                 || month == 10 || month == 12)
282                         && (day < 1 || day > 31)) {
283                 if (error_code)
284                         *error_code = ERR_ALARM_INVALID_DATE;
285                 return false;
286         }
287
288         if ((month == 4 || month == 6 || month == 9 || month == 11)
289                         && (day < 1 || day > 30)) {
290                 if (error_code)
291                         *error_code = ERR_ALARM_INVALID_DATE;
292                 return false;
293         }
294
295         if (month == 2) {
296                 if ((year % 100 != 0 && year % 4 == 0) || (year % 400 == 0)) {
297                         if (day < 1 || day > 29) {
298                                 if (error_code)
299                                         *error_code = ERR_ALARM_INVALID_DATE;
300                                 return false;
301                         }
302                 } else {
303                         if (day < 1 || day > 28) {
304                                 if (error_code)
305                                         *error_code = ERR_ALARM_INVALID_DATE;
306                                 return false;
307                         }
308                 }
309
310         }
311
312         return true;
313 }
314
315 static bool __alarm_validate_time(alarm_date_t *date, int *error_code)
316 {
317         if (date->hour < 0 || date->hour > 23) {
318                 if (error_code)
319                         *error_code = ERR_ALARM_INVALID_TIME;
320                 return false;
321         }
322
323         if (date->min < 0 || date->min > 59) {
324                 if (error_code)
325                         *error_code = ERR_ALARM_INVALID_TIME;
326                 return false;
327         }
328
329         return true;
330 }
331
332 static int __alarm_context_init()
333 {
334         if (sub_initialized)
335                 return ALARMMGR_RESULT_SUCCESS;
336
337         alarm_context.proxy = g_dbus_proxy_new_sync(alarm_context.connection,
338                         G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION,
339                         NULL,
340                         "org.tizen.alarm.manager",
341                         "/org/tizen/alarm/manager",
342                         "org.tizen.alarm.manager",
343                         NULL,
344                         NULL);
345
346         if (alarm_context.proxy == NULL) {
347                 LOGE("Creating a proxy is failed.");
348                 g_object_unref(alarm_context.connection);
349                 return ERR_ALARM_SYSTEM_FAIL;
350         }
351
352         sub_initialized = true;
353
354         return ALARMMGR_RESULT_SUCCESS;
355 }
356
357 static void __bus_get_for_async_api(GObject *source_object, GAsyncResult *res,
358                 gpointer user_data)
359 {
360         GError *error = NULL;
361         struct alarm_async_param_t *param = (struct alarm_async_param_t *)user_data;
362
363         pthread_mutex_lock(&init_lock);
364
365         alarm_context.connection = g_bus_get_finish(res, &error);
366         if (!alarm_context.connection) {
367                 LOGE("dbus error message: %s", error->message);
368                 g_error_free(error);
369                 g_variant_unref(param->v);
370                 g_free(param);
371                 pthread_mutex_unlock(&init_lock);
372                 return;
373         }
374
375         if (__alarm_context_init() != ALARMMGR_RESULT_SUCCESS) {
376                 g_variant_unref(param->v);
377                 g_free(param);
378                 pthread_mutex_unlock(&init_lock);
379                 return;
380         }
381
382         if (param->type == SET_SYSTIME_WITH_PROPAGATION_DELAY) {
383                 struct timespec new_time;
384                 struct timespec req_time;
385                 gint64 new_sec, new_nsec, req_sec, req_nsec;
386                 g_variant_get(param->v, "(xxxx)", &new_sec, &new_nsec,
387                                 &req_sec, &req_nsec);
388                 new_time.tv_sec = (time_t)new_sec;
389                 new_time.tv_nsec = (long)new_nsec;
390                 req_time.tv_sec = (time_t)req_sec;
391                 req_time.tv_nsec = (long)new_nsec;
392
393                 _send_alarm_set_time_with_propagation_delay_async(alarm_context,
394                                         new_time, req_time,     param->result_cb, param->user_param);
395         } else if (param->type == SET_SYSTIME) {
396                 gint64 new_time;
397                 g_variant_get(param->v, "x", &new_time);
398                 _send_alarm_set_time_async(alarm_context, (time_t)new_time,
399                                         param->result_cb, param->user_param);
400         }
401
402         g_variant_unref(param->v);
403         g_free(param);
404         pthread_mutex_unlock(&init_lock);
405 }
406
407 static int __sub_init()
408 {
409         GError *error = NULL;
410         int ret = 0;
411
412         pthread_mutex_lock(&init_lock);
413
414         if (sub_initialized) {
415                 pthread_mutex_unlock(&init_lock);
416                 return ALARMMGR_RESULT_SUCCESS;
417         }
418
419 #if !(GLIB_CHECK_VERSION(2, 32, 0))
420         g_thread_init(NULL);
421 #endif
422 #if !(GLIB_CHECK_VERSION(2, 36, 0))
423         g_type_init();
424 #endif
425
426         alarm_context.connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
427         if (alarm_context.connection == NULL) {
428                 LOGE("g_bus_get_sync() is failed. error: %s", error->message);
429                 g_error_free(error);
430                 pthread_mutex_unlock(&init_lock);
431                 return ERR_ALARM_SYSTEM_FAIL;
432         }
433
434         ret = __alarm_context_init();
435         pthread_mutex_unlock(&init_lock);
436
437         return ret;
438 }
439
440 static int __compare_api_version(int *result, uid_t uid)
441 {
442         int ret = 0;
443         pkgmgrinfo_pkginfo_h pkginfo = NULL;
444         char pkgid[MAX_PKG_ID_LEN] = {0, };
445         char *pkg_version;
446
447         if (aul_app_get_pkgid_bypid_for_uid(getpid(), pkgid, sizeof(pkgid), uid) != AUL_R_OK) {
448                 LOGE("aul_app_get_pkgid_bypid() is failed. PID %d may not be app.", getpid());
449         } else {
450                 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo);
451                 if (ret != PMINFO_R_OK) {
452                         LOGE("Failed to get pkginfo\n");
453                 } else {
454                         ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo, &pkg_version);
455                         if (ret != PMINFO_R_OK)
456                                 LOGE("Failed to check api version [%d]\n", ret);
457
458                         *result = strverscmp(pkg_version, "2.4");
459                         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
460                 }
461         }
462         return ret;
463 }
464
465 static void __adjust_current_milliseconds(alarm_info_t *alarm_info)
466 {
467         struct timeval current_time;
468         struct tm start_tm;
469         time_t start;
470
471         gettimeofday(&current_time, NULL);
472         if (current_time.tv_usec > 500 * 1000) {
473                 /* When the millisecond part of the current_time is bigger than 500ms,
474                  * the duetime increases by extra 1sec. */
475
476                 start_tm.tm_year = alarm_info->start.year - 1900;
477                 start_tm.tm_mon = alarm_info->start.month - 1;
478                 start_tm.tm_mday = alarm_info->start.day;
479                 start_tm.tm_hour = alarm_info->start.hour;
480                 start_tm.tm_min = alarm_info->start.min;
481                 start_tm.tm_sec = alarm_info->start.sec;
482                 start_tm.tm_isdst = -1;
483
484                 start = timegm(&start_tm);
485
486                 if (current_time.tv_sec == start) {
487                         start += 1;
488
489                         localtime_r(&start, &start_tm);
490                         alarm_info->start.year = start_tm.tm_year + 1900;
491                         alarm_info->start.month = start_tm.tm_mon + 1;
492                         alarm_info->start.day = start_tm.tm_mday;
493                         alarm_info->start.hour = start_tm.tm_hour;
494                         alarm_info->start.min = start_tm.tm_min;
495                         alarm_info->start.sec = start_tm.tm_sec;
496
497                         LOGW("adjusted start(%d-%d-%d, %02d:%02d:%02d),",
498                                         alarm_info->start.day, alarm_info->start.month, alarm_info->start.year,
499                                         alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec);
500                 }
501         }
502 }
503
504 static void __check_appid(void)
505 {
506         if (flag_appid_checked == 0) {
507                 if (aul_app_get_appid_bypid(getpid(), g_appid, sizeof(g_appid)) != AUL_R_OK) {
508                         LOGE("PID[%d] may not be app. Please call alarmmgr_init(caller name) in advance.", getpid());
509                 } else {
510                         LOGD("Get appid only once. appid[%s]", g_appid);
511                         flag_appid_checked = 1;
512                 }
513         }
514 }
515
516 EXPORT_API int alarmmgr_init(const char *appid)
517 {
518         SECURE_LOGD("Enter");
519         char service_name[MAX_SERVICE_NAME_LEN] = { 0 };
520         char service_name_mod[MAX_SERVICE_NAME_LEN] = { 0 };
521         int ret;
522         int len = 0;
523         guint owner_id = 0;
524         int i = 0;
525         int j = 0;
526         bool is_user = false;
527
528         if (appid == NULL) {
529                 LOGE("alarm is null");
530                 return ERR_ALARM_INVALID_PARAM;
531         }
532
533         if (strlen(appid) >= MAX_PKG_NAME_LEN) {
534                 LOGE("length of appid is invalid");
535                 return ERR_ALARM_INVALID_PARAM;
536         }
537
538         if (b_initialized) {
539                 SECURE_LOGD("alarm was already initialized. app_service_name=%s",
540                                 alarm_context.app_service_name);
541                 return ALARMMGR_RESULT_SUCCESS;
542         }
543
544         ret = __sub_init();
545         if (ret < 0)
546                 return ret;
547
548         memset(service_name_mod, 'a', MAX_SERVICE_NAME_LEN - 1);
549
550         len = strlen("ALARM.");
551         strncpy(service_name, "ALARM.", sizeof(service_name) - 1);
552         strncpy(service_name + len, appid, sizeof(service_name) - len - 1);
553
554         for (i = 0; i <= strlen(service_name); i++) {
555                 if (service_name[i] == '.') {
556                         service_name_mod[j] = service_name[i];
557                         j++;
558                 } else {
559                         service_name_mod[j] = service_name[i];
560                 }
561                 j++;
562         }
563
564         if (getuid() >= REGULAR_UID_MIN) {
565                 is_user = true;
566                 alarm_context.session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
567         }
568
569         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
570         if (introspection_data == NULL) {
571                 LOGE("g_dbus_node_info_new_for_xml() is failed.");
572                 goto error;
573         }
574
575         registration_id = g_dbus_connection_register_object(is_user ?
576                         alarm_context.session_conn : alarm_context.connection,
577                         "/org/tizen/alarm/client",
578                         introspection_data->interfaces[0],
579                         &interface_vtable, NULL, NULL, NULL);
580         if (registration_id == 0) {
581                 LOGE("Registering the callback is failed.");
582                 goto error;
583         }
584
585         owner_id = g_bus_own_name_on_connection(is_user ?
586                         alarm_context.session_conn : alarm_context.connection,
587                         service_name_mod,
588                         G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL);
589         if (owner_id == 0) {
590                 LOGE("Acquiring the own name is failed. %s", service_name_mod);
591                 goto error;
592         }
593
594         alarm_context.app_service_name = strdup(service_name);
595         alarm_context.app_service_name_mod = strdup(service_name_mod);
596
597         b_initialized = true;
598
599         SECURE_LOGD("Leave");
600         return ALARMMGR_RESULT_SUCCESS;
601
602 error:
603         if (introspection_data) {
604                 g_dbus_node_info_unref(introspection_data);
605                 introspection_data = NULL;
606         }
607
608         if (registration_id != 0) {
609                 g_dbus_connection_unregister_object(alarm_context.connection, registration_id);
610                 registration_id = 0;
611         }
612
613         g_object_unref(alarm_context.proxy);
614         alarm_context.proxy = NULL;
615
616         g_object_unref(alarm_context.connection);
617         alarm_context.connection = NULL;
618
619         sub_initialized = false;
620         return ERR_ALARM_INVALID_PARAM;
621 }
622
623 EXPORT_API void alarmmgr_fini()
624 {
625         SECURE_LOGD("Enter");
626         bool is_user = false;
627
628         if (getuid() >= REGULAR_UID_MIN)
629                 is_user = true;
630
631         if (introspection_data) {
632                 g_dbus_node_info_unref(introspection_data);
633                 introspection_data = NULL;
634         }
635
636         if (registration_id != 0) {
637                 g_dbus_connection_unregister_object(is_user ?
638                                 alarm_context.session_conn : alarm_context.connection,
639                                 registration_id);
640                 registration_id = 0;
641         }
642
643         if (alarm_context.proxy) {
644                 g_object_unref(alarm_context.proxy);
645                 alarm_context.proxy = NULL;
646         }
647
648         if (alarm_context.connection) {
649                 g_object_unref(alarm_context.connection);
650                 alarm_context.connection = NULL;
651         }
652
653         if (alarm_context.session_conn) {
654                 g_object_unref(alarm_context.session_conn);
655                 alarm_context.session_conn = NULL;
656         }
657
658         if (alarm_context.app_service_name)
659                 free(alarm_context.app_service_name);
660         if (alarm_context.app_service_name_mod)
661                 free(alarm_context.app_service_name_mod);
662
663
664         b_initialized = false;
665         sub_initialized = false;
666
667         SECURE_LOGD("Leave");
668 }
669
670 EXPORT_API int alarmmgr_set_cb(alarm_cb_t handler, void *user_param)
671 {
672         SECURE_LOGD("Enter");
673
674         if (handler == NULL) {
675                 LOGE("callback is NULL.");
676                 return ERR_ALARM_INVALID_PARAM;
677         }
678         alarm_context.alarm_handler = handler;
679         alarm_context.user_param = user_param;
680
681         SECURE_LOGD("Leave");
682         return ALARMMGR_RESULT_SUCCESS;
683 }
684
685 EXPORT_API alarm_entry_t *alarmmgr_create_alarm(void)
686 {
687         alarm_info_t *alarm = (alarm_info_t *)malloc(sizeof(alarm_info_t));
688
689         if (alarm == NULL) {
690                 LOGE("alarm is null");
691                 return NULL;
692         }
693
694         alarm->start.year = 0;
695         alarm->start.month = 0;
696         alarm->start.day = 0;
697         alarm->start.hour = 0;
698         alarm->start.min = 0;
699         alarm->start.sec = 0;
700
701         alarm->msec = 0;
702
703         alarm->end.year = 0;
704         alarm->end.month = 0;
705         alarm->end.day = 0;
706         alarm->end.hour = 0;
707         alarm->end.min = 0;
708         alarm->end.sec = 0;
709
710         alarm->mode.repeat = ALARM_REPEAT_MODE_ONCE;
711         alarm->mode.u_interval.interval = 0;
712
713         alarm->alarm_type = ALARM_TYPE_DEFAULT;
714
715         alarm->reserved_info = 0;
716
717         return (alarm_entry_t *) alarm;
718 }
719
720 EXPORT_API int alarmmgr_free_alarm(alarm_entry_t *alarm)
721 {
722         if (alarm == NULL) {
723                 LOGE("alarm is null");
724                 return ERR_ALARM_INVALID_PARAM;
725         }
726
727         free(alarm);
728
729         return ALARMMGR_RESULT_SUCCESS;
730 }
731
732 EXPORT_API int alarmmgr_set_time(alarm_entry_t *alarm, alarm_date_t time)
733 {
734         alarm_info_t *alarm_info;
735         int error_code;
736
737         if (alarm == NULL) {
738                 LOGE("alarm is null");
739                 return ERR_ALARM_INVALID_PARAM;
740         }
741
742         alarm_info = (alarm_info_t *)alarm;
743         if (!__alarm_validate_date(&time, &error_code)) {
744                 LOGE("start date error\n");
745                 return error_code;
746         }
747
748         if (!__alarm_validate_time(&time, &error_code)) {
749                 LOGE("start time error\n");
750                 return error_code;
751         }
752
753         memcpy(&alarm_info->start, &time, sizeof(alarm_date_t));
754
755         return ALARMMGR_RESULT_SUCCESS;
756 }
757
758 EXPORT_API int alarmmgr_get_time(const alarm_entry_t *alarm,
759                 alarm_date_t *time)
760 {
761         alarm_info_t *alarm_info = (alarm_info_t *)alarm;
762
763         if (alarm == NULL) {
764                 LOGE("alarm is null");
765                 return ERR_ALARM_INVALID_PARAM;
766         }
767
768         if (time != NULL)
769                 memcpy(time, &alarm_info->start, sizeof(alarm_date_t));
770
771         return ALARMMGR_RESULT_SUCCESS;
772 }
773
774 EXPORT_API int alarmmgr_set_repeat_mode(alarm_entry_t *alarm,
775                 alarm_repeat_mode_t repeat, int interval)
776 {
777         alarm_info_t *alarm_info = (alarm_info_t *)alarm;
778
779         if (repeat >= ALARM_REPEAT_MODE_MAX) {
780                 LOGE("repeat value is invalid");
781                 return ERR_ALARM_INVALID_PARAM;
782         }
783
784         alarm_info->mode.repeat = repeat;
785
786         if (repeat == ALARM_REPEAT_MODE_REPEAT
787                         || repeat == ALARM_REPEAT_MODE_WEEKLY) {
788                 if (interval <= 0)
789                         return ERR_ALARM_INVALID_PARAM;
790                 alarm_info->mode.u_interval.interval = interval;
791         }
792
793         return ALARMMGR_RESULT_SUCCESS;
794 }
795
796 EXPORT_API int alarmmgr_get_repeat_mode(const alarm_entry_t *alarm,
797                 alarm_repeat_mode_t *repeat, int *interval)
798 {
799         alarm_info_t *alarm_info = (alarm_info_t *)alarm;
800
801         if (alarm == NULL) {
802                 LOGE("alarm is null");
803                 return ERR_ALARM_INVALID_PARAM;
804         }
805
806         if (repeat != NULL)
807                 *repeat = alarm_info->mode.repeat;
808         if (interval != NULL)
809                 *interval = alarm_info->mode.u_interval.interval;
810
811         return ALARMMGR_RESULT_SUCCESS;
812 }
813
814 EXPORT_API int alarmmgr_set_type(alarm_entry_t *alarm, int alarm_type)
815 {
816         alarm_info_t *alarm_info;
817
818         if (alarm == NULL) {
819                 LOGE("alarm is null");
820                 return ERR_ALARM_INVALID_PARAM;
821         }
822
823         alarm_info = (alarm_info_t *)alarm;
824         alarm_info->alarm_type = alarm_type;
825         alarm_info->alarm_type &= (~ALARM_TYPE_RELATIVE);
826
827         return ALARMMGR_RESULT_SUCCESS;
828 }
829
830 EXPORT_API int alarmmgr_get_type(const alarm_entry_t *alarm, int *alarm_type)
831 {
832         alarm_info_t *alarm_info = (alarm_info_t *)alarm;
833
834         if (alarm == NULL) {
835                 LOGE("alarm is null");
836                 return ERR_ALARM_INVALID_PARAM;
837         }
838
839         if (alarm_type != NULL)
840                 *alarm_type = alarm_info->alarm_type;
841
842         return ALARMMGR_RESULT_SUCCESS;
843 }
844
845 static int __alarmmgr_init_appsvc(void)
846 {
847         if (b_initialized) {
848                 LOGW("alarm was already initialized.");
849                 return ALARMMGR_RESULT_SUCCESS;
850         }
851
852         int ret = __sub_init();
853         if (ret < 0)
854                 return ret;
855
856         b_initialized = true;
857         return ALARMMGR_RESULT_SUCCESS;
858 }
859
860 EXPORT_API void *alarmmgr_get_alarm_appsvc_info(alarm_id_t alarm_id, int *return_code)
861 {
862         int ret = 0;
863
864         ret = __sub_init();
865         if (ret < 0) {
866                 if (return_code)
867                         *return_code = ret;
868
869                 return NULL;
870         }
871
872         LOGD("[alarm-lib]:alarmmgr_get_alarm_appsvc_info() is called.");
873
874         if (alarm_id <= 0) {
875                 LOGE("alarm_id is Invalid[%d]", alarm_id);
876                 if (return_code)
877                         *return_code = ERR_ALARM_INVALID_ID;
878
879                 return NULL;
880         }
881
882         return _send_alarm_get_appsvc_info(alarm_context, alarm_id, return_code);
883 }
884
885 EXPORT_API int alarmmgr_get_alarm_noti_info(alarm_id_t alarm_id, notification_h *noti)
886 {
887         int ret = 0;
888
889         ret = __sub_init();
890         if (ret < 0)
891                 return ret;
892
893         LOGD("[alarm-lib]:alarmmgr_get_alarm_appsvc_info() is called.");
894
895         if (alarm_id <= 0) {
896                 LOGE("alarm_id is Invalid[%d]", alarm_id);
897                 return ERR_ALARM_INVALID_ID;
898         }
899
900         *noti = _send_alarm_get_noti_info(alarm_context, alarm_id, &ret);
901
902         return ret;
903 }
904
905 EXPORT_API int alarmmgr_set_rtc_time(alarm_date_t *time)
906 {
907
908         int ret = 0;
909         int error_code = 0;
910
911         if (!time) {
912                 LOGE("Invalid parameter time\n");
913                 return ERR_ALARM_INVALID_PARAM;
914         }
915
916         ret = __sub_init();
917         if (ret < 0)
918                 return ret;
919
920         LOGD("[alarm-lib]:alarmmgr_set_rtc_time() is called\n");
921
922         if (!__alarm_validate_date(time, &error_code)) {
923                 LOGE("RTC date error\n");
924                 return error_code;
925         }
926
927         if (!__alarm_validate_time(time, &error_code)) {
928                 LOGE("RTC time error\n");
929                 return error_code;
930         }
931
932         time->year -= 1900;
933         time->month -= 1;
934
935         if (!_send_alarm_set_rtc_time(alarm_context, time, &error_code))
936                 return error_code;
937
938         return ALARMMGR_RESULT_SUCCESS;
939 }
940
941 EXPORT_API int alarmmgr_add_alarm_appsvc_with_localtime(alarm_entry_t *alarm, void *bundle_data, alarm_id_t *alarm_id)
942 {
943         alarm_info_t *alarm_info = NULL;
944         alarm_mode_t *mode;
945         const char *operation = NULL;
946         int error_code = 0;
947         const char *appid = NULL;
948         bundle *b;
949
950         LOGD("[alarm-lib]:alarm_create() is called\n");
951
952         alarm_info = (alarm_info_t *)alarm;
953         if (alarm_info == NULL || alarm_id == NULL) {
954                 LOGE("Invalid parameter\n");
955                 return ERR_ALARM_INVALID_PARAM;
956         }
957
958         __adjust_current_milliseconds(alarm_info);
959
960         b = (bundle *)bundle_data;
961         if (b == NULL) {
962                 LOGE("Invalid parameter bundle\n");
963                 return ERR_ALARM_INVALID_PARAM;
964         }
965
966         operation = appsvc_get_operation(b);
967         if (operation == NULL)
968                 appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT);
969
970         if (__alarmmgr_init_appsvc() < 0) {
971                 LOGE("Unable to initialize dbus!!!\n");
972                 return ERR_ALARM_SYSTEM_FAIL;
973         }
974
975         appid = appsvc_get_appid(b);
976         if ((appid == NULL && (alarm_info->alarm_type & ALARM_TYPE_NOLAUNCH)) ||
977                         (appid == NULL && operation && !strcmp(operation, APPSVC_OPERATION_DEFAULT))) {
978                 LOGE("appid is ivalid");
979                 return ERR_ALARM_INVALID_PARAM;
980         }
981
982         mode = &alarm_info->mode;
983
984         LOGW("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)",
985                         alarm_info->start.day, alarm_info->start.month, alarm_info->start.year,
986                         alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec,
987                         alarm_info->end.year, alarm_info->end.month, alarm_info->end.day,
988                         alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type);
989
990         /* TODO: This should be changed to > ALARM_REPEAT_MODE_MAX ? */
991         if (mode->repeat >= ALARM_REPEAT_MODE_MAX)
992                 return ERR_ALARM_INVALID_PARAM;
993
994         if (!__alarm_validate_date(&alarm_info->start, &error_code)) {
995                 LOGE("start date error\n");
996                 return error_code;
997         }
998
999         if (!__alarm_validate_time(&alarm_info->start, &error_code)) {
1000                 LOGE("start time error\n");
1001                 return error_code;
1002         }
1003
1004         if (!__alarm_validate_date(&alarm_info->end, &error_code)) {
1005                 LOGE("end date error\n");
1006                 return error_code;
1007         }
1008
1009         if (!_send_alarm_create_appsvc(alarm_context, alarm_info, alarm_id, b, &error_code))
1010                 return error_code;
1011
1012         return ALARMMGR_RESULT_SUCCESS;
1013 }
1014
1015 EXPORT_API int alarmmgr_add_alarm_with_localtime(alarm_entry_t *alarm,
1016                 const char *destination,
1017                 alarm_id_t *alarm_id)
1018 {
1019         char dst_service_name[MAX_SERVICE_NAME_LEN] = { 0 };
1020         char dst_service_name_mod[MAX_SERVICE_NAME_LEN] = { 0 };
1021         alarm_info_t *alarm_info = NULL;
1022         alarm_mode_t *mode;
1023         int ret;
1024         int error_code;
1025         int i = 0;
1026         int j = 0;
1027
1028         LOGD("[alarm-lib]:alarm_create() is called\n");
1029
1030         if (alarm == NULL) {
1031                 LOGE("alarm is null");
1032                 return ERR_ALARM_INVALID_PARAM;
1033         }
1034
1035         alarm_info = (alarm_info_t *) alarm;
1036         if (alarm_info == NULL || alarm_id == NULL) {
1037                 LOGE("Invalid parameter bundle\n");
1038                 return ERR_ALARM_INVALID_PARAM;
1039         }
1040
1041         __adjust_current_milliseconds(alarm_info);
1042
1043         mode = &alarm_info->mode;
1044
1045         ret = __sub_init();
1046         if (ret < 0)
1047                 return ret;
1048
1049         LOGD("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)",
1050                         alarm_info->start.day, alarm_info->start.month, alarm_info->start.year,
1051                         alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec,
1052                         alarm_info->end.year, alarm_info->end.month, alarm_info->end.day,
1053                         alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type);
1054
1055         /* TODO: This should be changed to > ALARM_REPEAT_MODE_MAX ? */
1056         if (mode->repeat >= ALARM_REPEAT_MODE_MAX) {
1057                 LOGE("repeat is Invalid");
1058                 return ERR_ALARM_INVALID_PARAM;
1059         }
1060
1061         if (destination && strlen(destination) >= MAX_PKG_NAME_LEN) {
1062                 LOGE("[alarm-lib]: destination name is too long!\n");
1063                 return ERR_ALARM_INVALID_PARAM;
1064         }
1065
1066
1067         if (!__alarm_validate_date(&alarm_info->start, &error_code)) {
1068                 LOGE("start date error\n");
1069                 return error_code;
1070         }
1071
1072         if (!__alarm_validate_time(&alarm_info->start, &error_code)) {
1073                 LOGE("start time error\n");
1074                 return error_code;
1075         }
1076
1077         if (!__alarm_validate_date(&alarm_info->end, &error_code)) {
1078                 LOGE("end date error\n");
1079                 return error_code;
1080         }
1081
1082         if (destination != NULL) {
1083                 memset(dst_service_name, 0, strlen(destination) + strlen("ALARM.") + 2);
1084                 snprintf(dst_service_name, MAX_SERVICE_NAME_LEN, "ALARM.%s", destination);
1085                 memset(dst_service_name_mod, 'a', MAX_SERVICE_NAME_LEN-1);
1086
1087                 for (i = 0; i <= strlen(dst_service_name); i++) {
1088                         if (dst_service_name[i] == '.') {
1089                                 dst_service_name_mod[j] = dst_service_name[i];
1090                                 j++;
1091                         } else {
1092                                 dst_service_name_mod[j] = dst_service_name[i];
1093                         }
1094                         j++;
1095                 }
1096
1097                 if (!_send_alarm_create(alarm_context, alarm_info, alarm_id, dst_service_name, dst_service_name_mod, &error_code))
1098                         return error_code;
1099         } else {
1100                 if (!_send_alarm_create(alarm_context, alarm_info, alarm_id, "null", "null", &error_code))
1101                         return error_code;
1102         }
1103
1104         return ALARMMGR_RESULT_SUCCESS;
1105 }
1106
1107 EXPORT_API int alarmmgr_add_alarm_noti_with_localtime(alarm_entry_t *alarm, notification_h noti, alarm_id_t *alarm_id)
1108 {
1109         alarm_info_t *alarm_info = NULL;
1110         int error_code = 0;
1111         alarm_info = (alarm_info_t *)alarm;
1112         alarm_mode_t *mode;
1113
1114         if (alarm_info == NULL || alarm_id == NULL) {
1115                 LOGE("Invalid parameter\n");
1116                 return ERR_ALARM_INVALID_PARAM;
1117         }
1118
1119         __adjust_current_milliseconds(alarm_info);
1120
1121         if (__alarmmgr_init_appsvc() < 0) {
1122                 LOGE("Unable to initialize dbus!!!\n");
1123                 return ERR_ALARM_SYSTEM_FAIL;
1124         }
1125
1126         alarm_info = (alarm_info_t *)alarm;
1127         if (alarm_info == NULL || alarm_id == NULL) {
1128                 LOGE("Invalid parameter\n");
1129                 return ERR_ALARM_INVALID_PARAM;
1130         }
1131
1132         mode = &alarm_info->mode;
1133
1134         LOGW("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)",
1135                         alarm_info->start.day, alarm_info->start.month, alarm_info->start.year,
1136                         alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec,
1137                         alarm_info->end.year, alarm_info->end.month, alarm_info->end.day,
1138                         alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type);
1139
1140         /* TODO: This should be changed to > ALARM_REPEAT_MODE_MAX ? */
1141         if (mode->repeat >= ALARM_REPEAT_MODE_MAX)
1142                 return ERR_ALARM_INVALID_PARAM;
1143
1144         if (!__alarm_validate_date(&alarm_info->start, &error_code)) {
1145                 LOGE("start date error\n");
1146                 return error_code;
1147         }
1148
1149         if (!__alarm_validate_time(&alarm_info->start, &error_code)) {
1150                 LOGE("start time error\n");
1151                 return error_code;
1152         }
1153
1154         if (!__alarm_validate_date(&alarm_info->end, &error_code)) {
1155                 LOGE("end date error\n");
1156                 return error_code;
1157         }
1158
1159         if (!_send_alarm_create_noti(alarm_context, alarm_info, alarm_id, noti, &error_code))
1160                 return error_code;
1161
1162         return ALARMMGR_RESULT_SUCCESS;
1163 }
1164
1165 EXPORT_API int alarmmgr_add_alarm_appsvc(int alarm_type, time_t trigger_at_time,
1166                 time_t interval, void *bundle_data,
1167                 alarm_id_t *alarm_id)
1168 {
1169         int error_code = 0;
1170         int result = 0;
1171         alarm_info_t alarm_info;
1172         const char *operation = NULL;
1173         const char *appid = NULL;
1174         bundle *b;
1175
1176         LOGD("[alarm-lib]:alarm_create() is called\n");
1177
1178         b = (bundle *)bundle_data;
1179         if (b == NULL) {
1180                 LOGE("Invalid parameter bundle\n");
1181                 return ERR_ALARM_INVALID_PARAM;
1182         }
1183
1184         operation = appsvc_get_operation(b);
1185         if (operation == NULL)
1186                 appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT);
1187
1188         appid = appsvc_get_appid(b);
1189
1190         if ((appid == NULL && (alarm_type & ALARM_TYPE_NOLAUNCH)) ||
1191                         (appid == NULL && operation && !strcmp(operation, APPSVC_OPERATION_DEFAULT))) {
1192                 LOGE("Invalid parameter\n");
1193                 return ERR_ALARM_INVALID_PARAM;
1194         }
1195
1196         if (__alarmmgr_init_appsvc() < 0) {
1197                 LOGE("Unable to initialize dbus!!!\n");
1198                 return ERR_ALARM_SYSTEM_FAIL;
1199         }
1200
1201         if (alarm_id == NULL) {
1202                 LOGE("alarm_id is null");
1203                 return ERR_ALARM_INVALID_PARAM;
1204         }
1205
1206         if (trigger_at_time < 0) {
1207                 LOGE("trigger_at_time is invalid[%ld]", trigger_at_time);
1208                 return ERR_ALARM_INVALID_PARAM;
1209         }
1210
1211         _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval,
1212                         false);
1213
1214         alarm_info.alarm_type |= ALARM_TYPE_RELATIVE;
1215         LOGD("alarm_info.type : %d", alarm_info.alarm_type);
1216
1217         if (__compare_api_version(&result, getuid()) < 0)
1218                 return ERR_ALARM_SYSTEM_FAIL;
1219         if (result < 0) {
1220                 if (alarm_info.alarm_type & ALARM_TYPE_INEXACT)
1221                         alarm_info.alarm_type ^= ALARM_TYPE_INEXACT;
1222         }
1223
1224         if ((alarm_type & ALARM_TYPE_INEXACT) &&
1225                         alarm_info.mode.u_interval.interval < MIN_INEXACT_INTERVAL)
1226                 alarm_info.mode.u_interval.interval = MIN_INEXACT_INTERVAL;
1227
1228         if (!_send_alarm_create_appsvc(alarm_context, &alarm_info, alarm_id, b, &error_code))
1229                 return error_code;
1230
1231
1232         LOGD("alarm_id : %d", *alarm_id);
1233
1234         return ALARMMGR_RESULT_SUCCESS;
1235 }
1236
1237 EXPORT_API int alarmmgr_add_alarm_noti(int alarm_type, time_t trigger_at_time,
1238                 time_t interval, notification_h noti,
1239                 alarm_id_t *alarm_id)
1240 {
1241         int error_code = 0;
1242         alarm_info_t alarm_info;
1243
1244         if (__alarmmgr_init_appsvc() < 0) {
1245                 LOGE("Unable to initialize dbus!!!\n");
1246                 return ERR_ALARM_SYSTEM_FAIL;
1247         }
1248
1249         if (alarm_id == NULL) {
1250                 LOGE("alarm_id is null");
1251                 return ERR_ALARM_INVALID_PARAM;
1252         }
1253
1254         if (trigger_at_time < 0) {
1255                 LOGE("trigger_at_time is invalid[%ld]", trigger_at_time);
1256                 return ERR_ALARM_INVALID_PARAM;
1257         }
1258
1259         _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval,
1260                         false);
1261
1262         alarm_info.alarm_type |= ALARM_TYPE_RELATIVE;
1263         LOGD("alarm_info.type : %d", alarm_info.alarm_type);
1264
1265         if ((alarm_info.alarm_type & ALARM_TYPE_INEXACT) &&
1266                         alarm_info.mode.u_interval.interval < MIN_INEXACT_INTERVAL)
1267                 alarm_info.mode.u_interval.interval = MIN_INEXACT_INTERVAL;
1268
1269         if (!_send_alarm_create_noti(alarm_context, &alarm_info, alarm_id, noti, &error_code))
1270                 return error_code;
1271
1272         return ALARMMGR_RESULT_SUCCESS;
1273 }
1274
1275 static int _alarmmgr_add_alarm(int alarm_type,
1276                 time_t trigger_at_time,
1277                 time_t interval, const char *destination,
1278                 alarm_id_t *alarm_id, bool precision)
1279 {
1280         char dst_service_name[MAX_SERVICE_NAME_LEN] = { 0 };
1281         char dst_service_name_mod[MAX_SERVICE_NAME_LEN] = { 0 };
1282         int i = 0;
1283         int j = 0;
1284         int error_code;
1285         alarm_info_t alarm_info;
1286         int ret;
1287
1288         ret = __sub_init();
1289         if (ret < 0)
1290                 return ret;
1291
1292         if (alarm_id == NULL) {
1293                 LOGE("[alarm-lib]: alarm_id is null");
1294                 return ERR_ALARM_INVALID_PARAM;
1295         }
1296
1297         if (trigger_at_time < 0)
1298                 LOGE("trigger_at_time is invalid[%ld]", trigger_at_time);
1299                 return ERR_ALARM_INVALID_PARAM;
1300
1301         if (destination && strlen(destination) >= MAX_PKG_NAME_LEN) {
1302                 LOGE("[alarm-lib]: destination name is too long!\n");
1303                 return ERR_ALARM_INVALID_PARAM;
1304         }
1305
1306         _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval,
1307                         precision);
1308
1309         alarm_info.alarm_type |= ALARM_TYPE_RELATIVE;
1310
1311         LOGD("alarm_info.type : %d", alarm_info.alarm_type);
1312
1313         if (destination != NULL) {
1314                 memset(dst_service_name, 0,
1315                                 strlen(destination) + strlen("ALARM.") + 2);
1316                 snprintf(dst_service_name, MAX_SERVICE_NAME_LEN, "ALARM.%s",
1317                                 destination);
1318                 memset(dst_service_name_mod, 'a', MAX_SERVICE_NAME_LEN - 1);
1319
1320                 j = 0;
1321                 for (i = 0; i <= strlen(dst_service_name); i++) {
1322                         if (dst_service_name[i] == '.') {
1323                                 dst_service_name_mod[j] = dst_service_name[i];
1324                                 j++;
1325                         } else {
1326                                 dst_service_name_mod[j] = dst_service_name[i];
1327                         }
1328                         j++;
1329                 }
1330
1331                 if (!_send_alarm_create(alarm_context, &alarm_info,
1332                                         alarm_id, dst_service_name,
1333                                         dst_service_name_mod,
1334                                         &error_code))
1335                         return error_code;
1336         } else {
1337                 if (!_send_alarm_create(alarm_context, &alarm_info, alarm_id,
1338                                         "null", "null", &error_code))
1339                         return error_code;
1340         }
1341
1342         return ALARMMGR_RESULT_SUCCESS;
1343 }
1344
1345 EXPORT_API int alarmmgr_add_alarm(int alarm_type, time_t trigger_at_time,
1346                 time_t interval, const char *destination,
1347                 alarm_id_t *alarm_id)
1348 {
1349         return _alarmmgr_add_alarm(alarm_type, trigger_at_time, interval,
1350                         destination, alarm_id, false);
1351 }
1352
1353 EXPORT_API int alarmmgr_add_alarm_precision(int alarm_type,
1354                 time_t trigger_at_time,
1355                 time_t interval, const char *destination,
1356                 alarm_id_t *alarm_id)
1357 {
1358         return _alarmmgr_add_alarm(alarm_type, trigger_at_time, interval,
1359                         destination, alarm_id, true);
1360 }
1361
1362 static int _alarmmgr_add_alarm_withcb(int alarm_type, time_t trigger_at_time,
1363                 time_t interval, alarm_cb_t handler, void *user_param,
1364                 alarm_id_t *alarm_id, bool precision)
1365 {
1366         int error_code = 0;
1367         alarm_info_t alarm_info;
1368         int ret = 0;
1369
1370         __check_appid();
1371         ret = alarmmgr_init(g_appid);
1372         if (ret < 0)
1373                 return ret;
1374
1375         LOGD("[alarm-lib]:alarmmgr_add_alarm_withcb() is called");
1376
1377         if (alarm_id == NULL) {
1378                 LOGE("alarm_id is null ");
1379                 return ERR_ALARM_INVALID_PARAM;
1380         }
1381
1382         if (trigger_at_time < 0) {
1383                 LOGE("trigger_at_time is invalid[%ld]", trigger_at_time);
1384                 return ERR_ALARM_INVALID_PARAM;
1385         }
1386
1387         _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval,
1388                         precision);
1389
1390         alarm_info.alarm_type |= ALARM_TYPE_RELATIVE;
1391         alarm_info.alarm_type |= ALARM_TYPE_WITHCB;
1392
1393         LOGD("alarm_info.type : %d", alarm_info.alarm_type);
1394
1395         if (!_send_alarm_create(alarm_context, &alarm_info, alarm_id, "null", "null", &error_code))
1396                 return error_code;
1397
1398         __add_resultcb(*alarm_id, handler, user_param);
1399
1400         return ALARMMGR_RESULT_SUCCESS;
1401 }
1402
1403 EXPORT_API int alarmmgr_add_alarm_withcb(int alarm_type, time_t trigger_at_time,
1404                 time_t interval, alarm_cb_t handler, void *user_param, alarm_id_t *alarm_id)
1405 {
1406         return _alarmmgr_add_alarm_withcb(alarm_type, trigger_at_time, interval,
1407                         handler, user_param, alarm_id, false);
1408 }
1409
1410 EXPORT_API int alarmmgr_add_alarm_withcb_precision(int alarm_type, time_t trigger_at_time,
1411                                   time_t interval, alarm_cb_t handler, void *user_param, alarm_id_t *alarm_id)
1412 {
1413         return _alarmmgr_add_alarm_withcb(alarm_type, trigger_at_time, interval,
1414                         handler, user_param, alarm_id, true);
1415 }
1416
1417 EXPORT_API int alarmmgr_remove_alarm(alarm_id_t alarm_id)
1418 {
1419         int error_code;
1420         int ret;
1421         alarm_cb_info_t *info;
1422
1423         ret = __sub_init();
1424         if (ret < 0)
1425                 return ret;
1426
1427         LOGD("[alarm-lib]:alarm_delete(%d) is called\n", alarm_id);
1428
1429         if (alarm_id <= 0) {
1430                 LOGE("[alarm-lib]:alarm_id is invalid[%d]\n", alarm_id);
1431                 return ERR_ALARM_INVALID_ID;
1432         }
1433
1434         if (!_send_alarm_delete(alarm_context, alarm_id, &error_code))
1435                 return error_code;
1436
1437         info = __find_resultcb(alarm_id);
1438         __remove_resultcb(info);
1439
1440         return ALARMMGR_RESULT_SUCCESS;
1441 }
1442
1443 EXPORT_API int alarmmgr_remove_all(void)
1444 {
1445         int error_code;
1446         int return_code = ALARMMGR_RESULT_SUCCESS;
1447         int ret = __sub_init();
1448         if (ret < 0)
1449                 return ret;
1450
1451         if (!_send_alarm_delete_all(alarm_context, &error_code))
1452                 return error_code;
1453
1454         return return_code;
1455 }
1456
1457 EXPORT_API int alarmmgr_enum_alarm_ids(alarm_enum_fn_t fn, void *user_param)
1458 {
1459         SECURE_LOGD("Enter");
1460         int return_code = 0;
1461         int maxnum_of_ids = 0;
1462         int num_of_ids = 0;
1463         alarm_id_t alarm_id;
1464         int ret = 0;
1465         GVariantIter *iter = NULL;
1466
1467         if (fn == NULL) {
1468                 LOGE("fn is null.");
1469                 return ERR_ALARM_INVALID_PARAM;
1470         }
1471
1472         ret = __sub_init();
1473         if (ret < 0) {
1474                 LOGE("__sub_init() is failed.");
1475                 return ret;
1476         }
1477
1478         if (!_send_alarm_get_number_of_ids(alarm_context, &maxnum_of_ids, &return_code))
1479                 return return_code;
1480
1481         LOGD("maxnum_of_ids[%d]", maxnum_of_ids);
1482
1483         if (!_send_alarm_get_list_of_ids(alarm_context, maxnum_of_ids, &iter, &num_of_ids, &return_code))
1484                 return return_code;
1485
1486         while (g_variant_iter_loop(iter, "i", &alarm_id)) {
1487                 LOGD("alarm_id (%d)", alarm_id);
1488                 (*fn)(alarm_id, user_param);
1489         }
1490         g_variant_iter_free(iter);
1491
1492         return ALARMMGR_RESULT_SUCCESS;
1493 }
1494
1495 EXPORT_API int alarmmgr_get_info(alarm_id_t alarm_id, alarm_entry_t *alarm)
1496 {
1497         int error_code;
1498         alarm_info_t *alarm_info = (alarm_info_t *) alarm;
1499         int ret;
1500
1501         ret = __sub_init();
1502         if (ret < 0)
1503                 return ret;
1504
1505         LOGD("[alarm-lib]:alarm_get_info() is called\n");
1506
1507         if (alarm_id < 0 || alarm_info == NULL) {
1508                 LOGE("[alarm-lib]:alarm_info is null or alar_id is invalid[%d].", alarm_id);
1509                 return ERR_ALARM_INVALID_PARAM;
1510         }
1511
1512         if (!_send_alarm_get_info(alarm_context, alarm_id, alarm_info, &error_code))
1513                 return error_code;
1514
1515         return ALARMMGR_RESULT_SUCCESS;
1516 }
1517
1518 int alarmmgr_get_number_of_ids(int *num_of_ids)
1519 {
1520         int error_code;
1521         LOGD("[alarm-lib]: alarm_get_number_of_ids() is called.");
1522
1523         if (num_of_ids == NULL) {
1524                 LOGE("[alarm-lib]:num_of_ids.");
1525                 return ERR_ALARM_INVALID_PARAM;
1526         }
1527
1528         LOGD("call alarm_get_number_of_ids\n");
1529         if (!_send_alarm_get_number_of_ids(alarm_context, num_of_ids, &error_code))
1530                 return error_code;
1531
1532         return ALARMMGR_RESULT_SUCCESS;
1533 }
1534
1535 EXPORT_API int alarmmgr_get_next_duetime(alarm_id_t alarm_id, time_t *duetime)
1536 {
1537         int error_code;
1538         int ret;
1539
1540         ret = __sub_init();
1541         if (ret < 0)
1542                 return ret;
1543
1544         LOGD("[alarm-lib]:alarmmgr_get_next_duetime() is called.");
1545
1546         if (duetime == NULL) {
1547                 LOGE("[alarm-lib]:duetime is null.");
1548                 return ERR_ALARM_INVALID_PARAM;
1549         }
1550
1551         if (!_send_alarm_get_next_duetime(alarm_context, alarm_id, duetime, &error_code))
1552                 return error_code;
1553
1554         return ALARMMGR_RESULT_SUCCESS;
1555 }
1556
1557 EXPORT_API int alarmmgr_get_all_info(char **db_path)
1558 {
1559         int error_code;
1560         LOGD("[alarm-lib]:alarmmgr_get_all_info() is called.");
1561
1562         if (db_path == NULL) {
1563                 LOGE("[alarm-lib]:db_path is null.");
1564                 return ERR_ALARM_INVALID_PARAM;
1565         }
1566
1567         if (!_send_alarm_get_all_info(alarm_context, db_path, &error_code))
1568                 return error_code;
1569
1570         LOGD("[alarm-lib]: successfully save info in %s.", *db_path);
1571         return ALARMMGR_RESULT_SUCCESS;
1572 }
1573
1574 EXPORT_API int alarmmgr_add_periodic_alarm_withcb(int interval, periodic_method_e method,
1575                 alarm_cb_t handler, void *user_param, alarm_id_t *alarm_id)
1576 {
1577         int error_code = 0;
1578         int ret = 0;
1579
1580         __check_appid();
1581         ret = alarmmgr_init(g_appid);
1582         if (ret < 0)
1583                 return ret;
1584
1585         if (alarm_id == NULL) {
1586                 LOGE("[alarm-lib]:alarm_id is null.");
1587                 return ERR_ALARM_INVALID_PARAM;
1588         }
1589
1590         if (!_send_alarm_create_periodic(alarm_context, interval, 0,
1591                                 (int)method, alarm_id,
1592                                 &error_code))
1593                 return error_code;
1594
1595         __add_resultcb(*alarm_id, handler, user_param);
1596
1597         return ALARMMGR_RESULT_SUCCESS;
1598 }
1599
1600 EXPORT_API int alarmmgr_add_reference_periodic_alarm_withcb(int interval,
1601                 alarm_cb_t handler, void *user_param, alarm_id_t *alarm_id)
1602 {
1603         int error_code = 0;
1604         int ret = 0;
1605
1606         __check_appid();
1607         ret = alarmmgr_init(g_appid);
1608         if (ret < 0)
1609                 return ret;
1610
1611         if (alarm_id == NULL) {
1612                 LOGE("[alarm-lib]:alarm_id is null.");
1613                 return ERR_ALARM_INVALID_PARAM;
1614         }
1615
1616         if (!_send_alarm_create_periodic(alarm_context, interval, 1, 0,
1617                                 alarm_id, &error_code))
1618                 return error_code;
1619
1620         __add_resultcb(*alarm_id, handler, user_param);
1621
1622         return ALARMMGR_RESULT_SUCCESS;
1623 }
1624
1625 EXPORT_API int alarmmgr_set_systime(int new_time)
1626 {
1627         return alarmmgr_set_systime64((time_t)new_time);
1628 }
1629
1630 EXPORT_API int alarmmgr_set_systime64(time_t new_time)
1631 {
1632         int error_code;
1633         LOGD("[alarm-lib]:alarmmgr_set_systime(%ld) is called.", new_time);
1634
1635         if (__sub_init() < 0)
1636                 return ERR_ALARM_SYSTEM_FAIL;
1637
1638         if (!_send_alarm_set_time(alarm_context, new_time, &error_code)) {
1639                 LOGE("Failed to set time. error: %d", error_code);
1640                 return error_code;
1641         }
1642
1643         LOGD("[alarm-lib]: successfully set the time(%ld) by pid(%d).", new_time, getpid());
1644         return ALARMMGR_RESULT_SUCCESS;
1645 }
1646
1647 EXPORT_API int alarmmgr_set_systime_async(int new_time, alarm_set_time_cb_t result_cb, void *user_param)
1648 {
1649         return alarmmgr_set_systime64_async((time_t)new_time, result_cb, user_param);
1650 }
1651
1652 EXPORT_API int alarmmgr_set_systime64_async(time_t new_time, alarm_set_time_cb_t result_cb, void *user_param)
1653 {
1654         struct alarm_async_param_t *param;
1655
1656         LOGD("[alarm-lib]:alarmmgr_set_systime(%ld) is called.", new_time);
1657
1658         if (sub_initialized) {
1659                 if (!_send_alarm_set_time_async(alarm_context, new_time,
1660                                         result_cb, user_param))
1661                         return ERR_ALARM_SYSTEM_FAIL;
1662         } else {
1663 #if !(GLIB_CHECK_VERSION(2, 32, 0))
1664                 g_thread_init(NULL);
1665 #endif
1666 #if !(GLIB_CHECK_VERSION(2, 36, 0))
1667                 g_type_init();
1668 #endif
1669                 param = g_try_new0(struct alarm_async_param_t, 1);
1670                 if (param == NULL) {
1671                         LOGE("Failed to alloc param");
1672                         return ERR_ALARM_SYSTEM_FAIL;
1673                 }
1674                 param->type = SET_SYSTIME;
1675                 param->v = g_variant_new("i", new_time);
1676                 param->result_cb = result_cb;
1677                 param->user_param = user_param;
1678                 g_bus_get(G_BUS_TYPE_SYSTEM, NULL, __bus_get_for_async_api, param);
1679         }
1680
1681         return ALARMMGR_RESULT_SUCCESS;
1682 }
1683
1684 EXPORT_API int alarmmgr_set_systime_with_propagation_delay(struct timespec new_time, struct timespec req_time)
1685 {
1686         int error_code;
1687         LOGD("[alarm-lib] New: %ld(sec) %09ld(nsec), Requested: %ld(sec) %09ld(nsec)",
1688                         new_time.tv_sec, new_time.tv_nsec, req_time.tv_sec, req_time.tv_nsec);
1689
1690         if (__sub_init() < 0)
1691                 return ERR_ALARM_SYSTEM_FAIL;
1692
1693         if (!_send_alarm_set_time_with_propagation_delay(alarm_context, new_time, req_time, &error_code)) {
1694                 LOGE("Failed to set time with propagation delay. error: %d", error_code);
1695                 return error_code;
1696         }
1697
1698         LOGD("[alarm-lib]: successfully set the time by pid(%d).", getpid());
1699         return ALARMMGR_RESULT_SUCCESS;
1700 }
1701
1702 EXPORT_API int alarmmgr_set_systime_with_propagation_delay_async(struct timespec new_time, struct timespec req_time, alarm_set_time_cb_t result_cb, void *user_param)
1703 {
1704         struct alarm_async_param_t *param;
1705
1706         LOGD("[alarm-lib] New: %ld(sec) %09ld(nsec), Requested: %ld(sec) %09ld(nsec)",
1707                 new_time.tv_sec, new_time.tv_nsec, req_time.tv_sec, req_time.tv_nsec);
1708
1709         if (sub_initialized) {
1710                 if (!_send_alarm_set_time_with_propagation_delay_async(alarm_context,
1711                                         new_time, req_time, result_cb, user_param))
1712                         return ERR_ALARM_SYSTEM_FAIL;
1713         } else {
1714 #if !(GLIB_CHECK_VERSION(2, 32, 0))
1715                 g_thread_init(NULL);
1716 #endif
1717 #if !(GLIB_CHECK_VERSION(2, 36, 0))
1718                 g_type_init();
1719 #endif
1720                 param = g_try_new0(struct alarm_async_param_t, 1);
1721                 if (param == NULL) {
1722                         LOGE("Failed to alloc param");
1723                         return ERR_ALARM_SYSTEM_FAIL;
1724                 }
1725                 param->type = SET_SYSTIME_WITH_PROPAGATION_DELAY;
1726                 param->v = g_variant_new("(xxxx)",
1727                                 (gint64)new_time.tv_sec, (gint64)new_time.tv_nsec,
1728                                 (gint64)req_time.tv_sec, (gint64)req_time.tv_nsec);
1729                 param->result_cb = result_cb;
1730                 param->user_param = user_param;
1731                 g_bus_get(G_BUS_TYPE_SYSTEM, NULL, __bus_get_for_async_api, param);
1732         }
1733
1734         return ALARMMGR_RESULT_SUCCESS;
1735 }
1736
1737 EXPORT_API int alarmmgr_set_timezone(char *tzpath_str)
1738 {
1739         int error_code;
1740         LOGD("[alarm-lib]:alarmmgr_set_timezone() is called.");
1741
1742         if (tzpath_str == NULL) {
1743                 LOGE("[alarm-lib]:tzpath_str is NULL\n");
1744                 return ERR_ALARM_INVALID_PARAM;
1745         }
1746
1747         if (__sub_init() < 0)
1748                 return ERR_ALARM_SYSTEM_FAIL;
1749
1750         if (!_send_alarm_set_timezone(alarm_context, tzpath_str, &error_code))
1751                 return error_code;
1752
1753         LOGD("[alarm-lib]: successfully set the timezone(%s) by pid(%d)", tzpath_str, getpid());
1754         return ALARMMGR_RESULT_SUCCESS;
1755 }
1756
1757 EXPORT_API int alarmmgr_set_global(const alarm_id_t alarm_id,
1758                 bool global)
1759 {
1760         int error_code;
1761         LOGD("[alarm-lib]:alarmmgr_set_global(%d) is called.", alarm_id);
1762
1763         if (__sub_init() < 0)
1764                 return ERR_ALARM_SYSTEM_FAIL;
1765
1766         if (!_send_alarm_set_global(alarm_context, alarm_id, global, &error_code))
1767                 return error_code;
1768
1769         return ALARMMGR_RESULT_SUCCESS;
1770 }
1771
1772
1773 EXPORT_API int alarmmgr_get_global(const alarm_id_t alarm_id,
1774                 bool *global)
1775 {
1776         int error_code;
1777
1778         if (__sub_init() < 0)
1779                 return ERR_ALARM_SYSTEM_FAIL;
1780
1781         if (global == NULL) {
1782                 LOGE("[alarm-lib]:global is NULL\n");
1783                 return ERR_ALARM_INVALID_PARAM;
1784         }
1785
1786         if (!_send_alarm_get_global(alarm_context, alarm_id, global, &error_code))
1787                 return error_code;
1788
1789         return ALARMMGR_RESULT_SUCCESS;
1790 }
1791
1792 EXPORT_API int alarmmgr_update_alarm(alarm_id_t alarm_id,
1793                 alarm_entry_t *alarm, int update_flag)
1794 {
1795         alarm_info_t *alarm_info;
1796         int ret;
1797
1798         LOGD("[alarm-lib]:alarmmgr_update_alarm() is called\n");
1799
1800         if (alarm == NULL) {
1801                 LOGE("[alarm-lib]:alarm is NULL\n");
1802                 return ERR_ALARM_INVALID_PARAM;
1803         }
1804
1805         alarm_info = (alarm_info_t *) alarm;
1806         if (alarm_info == NULL || alarm_id <= 0) {
1807                 LOGE("[alarm-lib]:alarm is NULL or invalid alarm_id[%d]\n", alarm_id);
1808                 return ERR_ALARM_INVALID_PARAM;
1809         }
1810
1811         int error_code;
1812
1813         ret = __sub_init();
1814         if (ret < 0)
1815                 return ret;
1816
1817         LOGD("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)",
1818                         alarm_info->start.day, alarm_info->start.month, alarm_info->start.year,
1819                         alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec,
1820                         alarm_info->end.year, alarm_info->end.month, alarm_info->end.day,
1821                         alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type);
1822
1823         if (update_flag == ALARM_UPDATE_FLAG_TIME) {
1824                 if (!__alarm_validate_date(&alarm_info->start, &error_code)) {
1825                         LOGE("start date error\n");
1826                         return error_code;
1827                 }
1828
1829                 if (!__alarm_validate_time(&alarm_info->start, &error_code)) {
1830                         LOGE("start time error\n");
1831                         return error_code;
1832                 }
1833
1834                 if (!__alarm_validate_date(&alarm_info->end, &error_code)) {
1835                         LOGE("end date error\n");
1836                         return error_code;
1837                 }
1838         }
1839
1840         if (!_send_alarm_update(alarm_context, alarm_id, alarm_info, update_flag, &error_code))
1841                 return error_code;
1842
1843         return ALARMMGR_RESULT_SUCCESS;
1844 }