Remove duplicated codes
[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 __check_validation(alarm_info_t *alarm_info, const char *function)
333 {
334         int error_code;
335
336         if (!__alarm_validate_date(&alarm_info->start, &error_code)) {
337                 LOGE("%s : start date error\n", function);
338                 return error_code;
339         }
340
341         if (!__alarm_validate_time(&alarm_info->start, &error_code)) {
342                 LOGE("%s : start time error\n", function);
343                 return error_code;
344         }
345
346         if (!__alarm_validate_date(&alarm_info->end, &error_code)) {
347                 LOGE("%s : end date error\n", function);
348                 return error_code;
349         }
350
351         return ALARMMGR_RESULT_SUCCESS;
352 }
353
354 static int __alarm_context_init()
355 {
356         if (sub_initialized)
357                 return ALARMMGR_RESULT_SUCCESS;
358
359         alarm_context.proxy = g_dbus_proxy_new_sync(alarm_context.connection,
360                         G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION,
361                         NULL,
362                         "org.tizen.alarm.manager",
363                         "/org/tizen/alarm/manager",
364                         "org.tizen.alarm.manager",
365                         NULL,
366                         NULL);
367
368         if (alarm_context.proxy == NULL) {
369                 LOGE("Creating a proxy is failed.");
370                 g_object_unref(alarm_context.connection);
371                 return ERR_ALARM_SYSTEM_FAIL;
372         }
373
374         sub_initialized = true;
375
376         return ALARMMGR_RESULT_SUCCESS;
377 }
378
379 static void __bus_get_for_async_api(GObject *source_object, GAsyncResult *res,
380                 gpointer user_data)
381 {
382         GError *error = NULL;
383         struct alarm_async_param_t *param = (struct alarm_async_param_t *)user_data;
384
385         pthread_mutex_lock(&init_lock);
386
387         alarm_context.connection = g_bus_get_finish(res, &error);
388         if (!alarm_context.connection) {
389                 LOGE("dbus error message: %s", error->message);
390                 g_error_free(error);
391                 g_variant_unref(param->v);
392                 g_free(param);
393                 pthread_mutex_unlock(&init_lock);
394                 return;
395         }
396
397         if (__alarm_context_init() != ALARMMGR_RESULT_SUCCESS) {
398                 g_variant_unref(param->v);
399                 g_free(param);
400                 pthread_mutex_unlock(&init_lock);
401                 return;
402         }
403
404         if (param->type == SET_SYSTIME_WITH_PROPAGATION_DELAY) {
405                 struct timespec new_time;
406                 struct timespec req_time;
407                 gint64 new_sec, new_nsec, req_sec, req_nsec;
408                 g_variant_get(param->v, "(xxxx)", &new_sec, &new_nsec,
409                                 &req_sec, &req_nsec);
410                 new_time.tv_sec = (time_t)new_sec;
411                 new_time.tv_nsec = (long)new_nsec;
412                 req_time.tv_sec = (time_t)req_sec;
413                 req_time.tv_nsec = (long)new_nsec;
414
415                 _send_alarm_set_time_with_propagation_delay_async(alarm_context,
416                                         new_time, req_time,     param->result_cb, param->user_param);
417         } else if (param->type == SET_SYSTIME) {
418                 gint64 new_time;
419                 g_variant_get(param->v, "x", &new_time);
420                 _send_alarm_set_time_async(alarm_context, (time_t)new_time,
421                                         param->result_cb, param->user_param);
422         }
423
424         g_variant_unref(param->v);
425         g_free(param);
426         pthread_mutex_unlock(&init_lock);
427 }
428
429 static int __sub_init()
430 {
431         GError *error = NULL;
432         int ret = 0;
433
434         pthread_mutex_lock(&init_lock);
435
436         if (sub_initialized) {
437                 pthread_mutex_unlock(&init_lock);
438                 return ALARMMGR_RESULT_SUCCESS;
439         }
440
441 #if !(GLIB_CHECK_VERSION(2, 32, 0))
442         g_thread_init(NULL);
443 #endif
444 #if !(GLIB_CHECK_VERSION(2, 36, 0))
445         g_type_init();
446 #endif
447
448         alarm_context.connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
449         if (alarm_context.connection == NULL) {
450                 LOGE("g_bus_get_sync() is failed. error: %s", error->message);
451                 g_error_free(error);
452                 pthread_mutex_unlock(&init_lock);
453                 return ERR_ALARM_SYSTEM_FAIL;
454         }
455
456         ret = __alarm_context_init();
457         pthread_mutex_unlock(&init_lock);
458
459         return ret;
460 }
461
462 static int __compare_api_version(int *result, uid_t uid)
463 {
464         int ret = 0;
465         pkgmgrinfo_pkginfo_h pkginfo = NULL;
466         char pkgid[MAX_PKG_ID_LEN] = {0, };
467         char *pkg_version;
468
469         if (aul_app_get_pkgid_bypid_for_uid(getpid(), pkgid, sizeof(pkgid), uid) != AUL_R_OK) {
470                 LOGE("aul_app_get_pkgid_bypid() is failed. PID %d may not be app.", getpid());
471         } else {
472                 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo);
473                 if (ret != PMINFO_R_OK) {
474                         LOGE("Failed to get pkginfo\n");
475                 } else {
476                         ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo, &pkg_version);
477                         if (ret != PMINFO_R_OK)
478                                 LOGE("Failed to check api version [%d]\n", ret);
479
480                         *result = strverscmp(pkg_version, "2.4");
481                         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
482                 }
483         }
484         return ret;
485 }
486
487 static void __adjust_current_milliseconds(alarm_info_t *alarm_info)
488 {
489         struct timeval current_time;
490         struct tm start_tm;
491         time_t start;
492
493         gettimeofday(&current_time, NULL);
494         if (current_time.tv_usec > 500 * 1000) {
495                 /* When the millisecond part of the current_time is bigger than 500ms,
496                  * the duetime increases by extra 1sec. */
497
498                 start_tm.tm_year = alarm_info->start.year - 1900;
499                 start_tm.tm_mon = alarm_info->start.month - 1;
500                 start_tm.tm_mday = alarm_info->start.day;
501                 start_tm.tm_hour = alarm_info->start.hour;
502                 start_tm.tm_min = alarm_info->start.min;
503                 start_tm.tm_sec = alarm_info->start.sec;
504                 start_tm.tm_isdst = -1;
505
506                 start = timegm(&start_tm);
507
508                 if (current_time.tv_sec == start) {
509                         start += 1;
510
511                         localtime_r(&start, &start_tm);
512                         alarm_info->start.year = start_tm.tm_year + 1900;
513                         alarm_info->start.month = start_tm.tm_mon + 1;
514                         alarm_info->start.day = start_tm.tm_mday;
515                         alarm_info->start.hour = start_tm.tm_hour;
516                         alarm_info->start.min = start_tm.tm_min;
517                         alarm_info->start.sec = start_tm.tm_sec;
518
519                         LOGW("adjusted start(%d-%d-%d, %02d:%02d:%02d),",
520                                         alarm_info->start.day, alarm_info->start.month, alarm_info->start.year,
521                                         alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec);
522                 }
523         }
524 }
525
526 static void __check_appid(void)
527 {
528         if (flag_appid_checked == 0) {
529                 if (aul_app_get_appid_bypid(getpid(), g_appid, sizeof(g_appid)) != AUL_R_OK) {
530                         LOGE("PID[%d] may not be app. Please call alarmmgr_init(caller name) in advance.", getpid());
531                 } else {
532                         LOGD("Get appid only once. appid[%s]", g_appid);
533                         flag_appid_checked = 1;
534                 }
535         }
536 }
537
538 EXPORT_API int alarmmgr_init(const char *appid)
539 {
540         SECURE_LOGD("Enter");
541         char service_name[MAX_SERVICE_NAME_LEN] = { 0 };
542         char service_name_mod[MAX_SERVICE_NAME_LEN] = { 0 };
543         int ret;
544         int len = 0;
545         guint owner_id = 0;
546         int i = 0;
547         int j = 0;
548         bool is_user = false;
549
550         if (appid == NULL) {
551                 LOGE("alarm is null");
552                 return ERR_ALARM_INVALID_PARAM;
553         }
554
555         if (strlen(appid) >= MAX_PKG_NAME_LEN) {
556                 LOGE("length of appid is invalid");
557                 return ERR_ALARM_INVALID_PARAM;
558         }
559
560         if (b_initialized) {
561                 SECURE_LOGD("alarm was already initialized. app_service_name=%s",
562                                 alarm_context.app_service_name);
563                 return ALARMMGR_RESULT_SUCCESS;
564         }
565
566         ret = __sub_init();
567         if (ret < 0)
568                 return ret;
569
570         memset(service_name_mod, 'a', MAX_SERVICE_NAME_LEN - 1);
571
572         len = strlen("ALARM.");
573         strncpy(service_name, "ALARM.", sizeof(service_name) - 1);
574         strncpy(service_name + len, appid, sizeof(service_name) - len - 1);
575
576         for (i = 0; i <= strlen(service_name); i++) {
577                 if (service_name[i] == '.') {
578                         service_name_mod[j] = service_name[i];
579                         j++;
580                 } else {
581                         service_name_mod[j] = service_name[i];
582                 }
583                 j++;
584         }
585
586         if (getuid() >= REGULAR_UID_MIN) {
587                 is_user = true;
588                 alarm_context.session_conn = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
589         }
590
591         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
592         if (introspection_data == NULL) {
593                 LOGE("g_dbus_node_info_new_for_xml() is failed.");
594                 goto error;
595         }
596
597         registration_id = g_dbus_connection_register_object(is_user ?
598                         alarm_context.session_conn : alarm_context.connection,
599                         "/org/tizen/alarm/client",
600                         introspection_data->interfaces[0],
601                         &interface_vtable, NULL, NULL, NULL);
602         if (registration_id == 0) {
603                 LOGE("Registering the callback is failed.");
604                 goto error;
605         }
606
607         owner_id = g_bus_own_name_on_connection(is_user ?
608                         alarm_context.session_conn : alarm_context.connection,
609                         service_name_mod,
610                         G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL);
611         if (owner_id == 0) {
612                 LOGE("Acquiring the own name is failed. %s", service_name_mod);
613                 goto error;
614         }
615
616         alarm_context.app_service_name = strdup(service_name);
617         alarm_context.app_service_name_mod = strdup(service_name_mod);
618
619         b_initialized = true;
620
621         SECURE_LOGD("Leave");
622         return ALARMMGR_RESULT_SUCCESS;
623
624 error:
625         if (introspection_data) {
626                 g_dbus_node_info_unref(introspection_data);
627                 introspection_data = NULL;
628         }
629
630         if (registration_id != 0) {
631                 g_dbus_connection_unregister_object(alarm_context.connection, registration_id);
632                 registration_id = 0;
633         }
634
635         g_object_unref(alarm_context.proxy);
636         alarm_context.proxy = NULL;
637
638         g_object_unref(alarm_context.connection);
639         alarm_context.connection = NULL;
640
641         sub_initialized = false;
642         return ERR_ALARM_INVALID_PARAM;
643 }
644
645 EXPORT_API void alarmmgr_fini()
646 {
647         SECURE_LOGD("Enter");
648         bool is_user = false;
649
650         if (getuid() >= REGULAR_UID_MIN)
651                 is_user = true;
652
653         if (introspection_data) {
654                 g_dbus_node_info_unref(introspection_data);
655                 introspection_data = NULL;
656         }
657
658         if (registration_id != 0) {
659                 g_dbus_connection_unregister_object(is_user ?
660                                 alarm_context.session_conn : alarm_context.connection,
661                                 registration_id);
662                 registration_id = 0;
663         }
664
665         if (alarm_context.proxy) {
666                 g_object_unref(alarm_context.proxy);
667                 alarm_context.proxy = NULL;
668         }
669
670         if (alarm_context.connection) {
671                 g_object_unref(alarm_context.connection);
672                 alarm_context.connection = NULL;
673         }
674
675         if (alarm_context.session_conn) {
676                 g_object_unref(alarm_context.session_conn);
677                 alarm_context.session_conn = NULL;
678         }
679
680         if (alarm_context.app_service_name)
681                 free(alarm_context.app_service_name);
682         if (alarm_context.app_service_name_mod)
683                 free(alarm_context.app_service_name_mod);
684
685
686         b_initialized = false;
687         sub_initialized = false;
688
689         SECURE_LOGD("Leave");
690 }
691
692 EXPORT_API int alarmmgr_set_cb(alarm_cb_t handler, void *user_param)
693 {
694         SECURE_LOGD("Enter");
695
696         if (handler == NULL) {
697                 LOGE("callback is NULL.");
698                 return ERR_ALARM_INVALID_PARAM;
699         }
700         alarm_context.alarm_handler = handler;
701         alarm_context.user_param = user_param;
702
703         SECURE_LOGD("Leave");
704         return ALARMMGR_RESULT_SUCCESS;
705 }
706
707 EXPORT_API alarm_entry_t *alarmmgr_create_alarm(void)
708 {
709         alarm_info_t *alarm = (alarm_info_t *)malloc(sizeof(alarm_info_t));
710
711         if (alarm == NULL) {
712                 LOGE("alarm is null");
713                 return NULL;
714         }
715
716         alarm->start.year = 0;
717         alarm->start.month = 0;
718         alarm->start.day = 0;
719         alarm->start.hour = 0;
720         alarm->start.min = 0;
721         alarm->start.sec = 0;
722
723         alarm->msec = 0;
724
725         alarm->end.year = 0;
726         alarm->end.month = 0;
727         alarm->end.day = 0;
728         alarm->end.hour = 0;
729         alarm->end.min = 0;
730         alarm->end.sec = 0;
731
732         alarm->mode.repeat = ALARM_REPEAT_MODE_ONCE;
733         alarm->mode.u_interval.interval = 0;
734
735         alarm->alarm_type = ALARM_TYPE_DEFAULT;
736
737         alarm->reserved_info = 0;
738
739         return (alarm_entry_t *) alarm;
740 }
741
742 EXPORT_API int alarmmgr_free_alarm(alarm_entry_t *alarm)
743 {
744         if (alarm == NULL) {
745                 LOGE("alarm is null");
746                 return ERR_ALARM_INVALID_PARAM;
747         }
748
749         free(alarm);
750
751         return ALARMMGR_RESULT_SUCCESS;
752 }
753
754 EXPORT_API int alarmmgr_set_time(alarm_entry_t *alarm, alarm_date_t time)
755 {
756         alarm_info_t *alarm_info;
757         int error_code;
758
759         if (alarm == NULL) {
760                 LOGE("alarm is null");
761                 return ERR_ALARM_INVALID_PARAM;
762         }
763
764         alarm_info = (alarm_info_t *)alarm;
765         if (!__alarm_validate_date(&time, &error_code)) {
766                 LOGE("start date error\n");
767                 return error_code;
768         }
769
770         if (!__alarm_validate_time(&time, &error_code)) {
771                 LOGE("start time error\n");
772                 return error_code;
773         }
774
775         memcpy(&alarm_info->start, &time, sizeof(alarm_date_t));
776
777         return ALARMMGR_RESULT_SUCCESS;
778 }
779
780 EXPORT_API int alarmmgr_get_time(const alarm_entry_t *alarm,
781                 alarm_date_t *time)
782 {
783         alarm_info_t *alarm_info = (alarm_info_t *)alarm;
784
785         if (alarm == NULL) {
786                 LOGE("alarm is null");
787                 return ERR_ALARM_INVALID_PARAM;
788         }
789
790         if (time != NULL)
791                 memcpy(time, &alarm_info->start, sizeof(alarm_date_t));
792
793         return ALARMMGR_RESULT_SUCCESS;
794 }
795
796 EXPORT_API int alarmmgr_set_repeat_mode(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 (repeat >= ALARM_REPEAT_MODE_MAX) {
802                 LOGE("repeat value is invalid");
803                 return ERR_ALARM_INVALID_PARAM;
804         }
805
806         alarm_info->mode.repeat = repeat;
807
808         if (repeat == ALARM_REPEAT_MODE_REPEAT
809                         || repeat == ALARM_REPEAT_MODE_WEEKLY) {
810                 if (interval <= 0)
811                         return ERR_ALARM_INVALID_PARAM;
812                 alarm_info->mode.u_interval.interval = interval;
813         }
814
815         return ALARMMGR_RESULT_SUCCESS;
816 }
817
818 EXPORT_API int alarmmgr_get_repeat_mode(const alarm_entry_t *alarm,
819                 alarm_repeat_mode_t *repeat, int *interval)
820 {
821         alarm_info_t *alarm_info = (alarm_info_t *)alarm;
822
823         if (alarm == NULL) {
824                 LOGE("alarm is null");
825                 return ERR_ALARM_INVALID_PARAM;
826         }
827
828         if (repeat != NULL)
829                 *repeat = alarm_info->mode.repeat;
830         if (interval != NULL)
831                 *interval = alarm_info->mode.u_interval.interval;
832
833         return ALARMMGR_RESULT_SUCCESS;
834 }
835
836 EXPORT_API int alarmmgr_set_type(alarm_entry_t *alarm, int alarm_type)
837 {
838         alarm_info_t *alarm_info;
839
840         if (alarm == NULL) {
841                 LOGE("alarm is null");
842                 return ERR_ALARM_INVALID_PARAM;
843         }
844
845         alarm_info = (alarm_info_t *)alarm;
846         alarm_info->alarm_type = alarm_type;
847         alarm_info->alarm_type &= (~ALARM_TYPE_RELATIVE);
848
849         return ALARMMGR_RESULT_SUCCESS;
850 }
851
852 EXPORT_API int alarmmgr_get_type(const alarm_entry_t *alarm, int *alarm_type)
853 {
854         alarm_info_t *alarm_info = (alarm_info_t *)alarm;
855
856         if (alarm == NULL) {
857                 LOGE("alarm is null");
858                 return ERR_ALARM_INVALID_PARAM;
859         }
860
861         if (alarm_type != NULL)
862                 *alarm_type = alarm_info->alarm_type;
863
864         return ALARMMGR_RESULT_SUCCESS;
865 }
866
867 static int __alarmmgr_init_appsvc(void)
868 {
869         if (b_initialized) {
870                 LOGW("alarm was already initialized.");
871                 return ALARMMGR_RESULT_SUCCESS;
872         }
873
874         int ret = __sub_init();
875         if (ret < 0)
876                 return ret;
877
878         b_initialized = true;
879         return ALARMMGR_RESULT_SUCCESS;
880 }
881
882 EXPORT_API void *alarmmgr_get_alarm_appsvc_info(alarm_id_t alarm_id, int *return_code)
883 {
884         int ret = 0;
885
886         ret = __sub_init();
887         if (ret < 0) {
888                 if (return_code)
889                         *return_code = ret;
890
891                 return NULL;
892         }
893
894         LOGD("[alarm-lib]:alarmmgr_get_alarm_appsvc_info() is called.");
895
896         if (alarm_id <= 0) {
897                 LOGE("alarm_id is Invalid[%d]", alarm_id);
898                 if (return_code)
899                         *return_code = ERR_ALARM_INVALID_ID;
900
901                 return NULL;
902         }
903
904         return _send_alarm_get_appsvc_info(alarm_context, alarm_id, return_code);
905 }
906
907 EXPORT_API int alarmmgr_get_alarm_noti_info(alarm_id_t alarm_id, notification_h *noti)
908 {
909         int ret = 0;
910
911         ret = __sub_init();
912         if (ret < 0)
913                 return ret;
914
915         LOGD("[alarm-lib]:alarmmgr_get_alarm_appsvc_info() is called.");
916
917         if (alarm_id <= 0) {
918                 LOGE("alarm_id is Invalid[%d]", alarm_id);
919                 return ERR_ALARM_INVALID_ID;
920         }
921
922         *noti = _send_alarm_get_noti_info(alarm_context, alarm_id, &ret);
923
924         return ret;
925 }
926
927 EXPORT_API int alarmmgr_set_rtc_time(alarm_date_t *time)
928 {
929
930         int ret = 0;
931         int error_code = 0;
932
933         if (!time) {
934                 LOGE("Invalid parameter time\n");
935                 return ERR_ALARM_INVALID_PARAM;
936         }
937
938         ret = __sub_init();
939         if (ret < 0)
940                 return ret;
941
942         LOGD("[alarm-lib]:alarmmgr_set_rtc_time() is called\n");
943
944         if (!__alarm_validate_date(time, &error_code)) {
945                 LOGE("RTC date error\n");
946                 return error_code;
947         }
948
949         if (!__alarm_validate_time(time, &error_code)) {
950                 LOGE("RTC time error\n");
951                 return error_code;
952         }
953
954         time->year -= 1900;
955         time->month -= 1;
956
957         if (!_send_alarm_set_rtc_time(alarm_context, time, &error_code))
958                 return error_code;
959
960         return ALARMMGR_RESULT_SUCCESS;
961 }
962
963 EXPORT_API int alarmmgr_add_alarm_appsvc_with_localtime(alarm_entry_t *alarm, void *bundle_data, alarm_id_t *alarm_id)
964 {
965         alarm_info_t *alarm_info = NULL;
966         alarm_mode_t *mode;
967         const char *operation = NULL;
968         int error_code = 0;
969         const char *appid = NULL;
970         bundle *b;
971
972         LOGD("[alarm-lib]:alarm_create() is called\n");
973
974         alarm_info = (alarm_info_t *)alarm;
975         if (alarm_info == NULL || alarm_id == NULL) {
976                 LOGE("Invalid parameter\n");
977                 return ERR_ALARM_INVALID_PARAM;
978         }
979
980         __adjust_current_milliseconds(alarm_info);
981
982         b = (bundle *)bundle_data;
983         if (b == NULL) {
984                 LOGE("Invalid parameter bundle\n");
985                 return ERR_ALARM_INVALID_PARAM;
986         }
987
988         operation = appsvc_get_operation(b);
989         if (operation == NULL)
990                 appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT);
991
992         if (__alarmmgr_init_appsvc() < 0) {
993                 LOGE("Unable to initialize dbus!!!\n");
994                 return ERR_ALARM_SYSTEM_FAIL;
995         }
996
997         appid = appsvc_get_appid(b);
998         if (appid == NULL) {
999                 if ((alarm_info->alarm_type & ALARM_TYPE_NOLAUNCH) ||
1000                                 (operation && !strcmp(operation, APPSVC_OPERATION_DEFAULT))) {
1001                         LOGE("appid is invalid");
1002                         return ERR_ALARM_INVALID_PARAM;
1003                 }
1004         }
1005
1006         mode = &alarm_info->mode;
1007
1008         LOGW("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)",
1009                         alarm_info->start.day, alarm_info->start.month, alarm_info->start.year,
1010                         alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec,
1011                         alarm_info->end.year, alarm_info->end.month, alarm_info->end.day,
1012                         alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type);
1013
1014         /* TODO: This should be changed to > ALARM_REPEAT_MODE_MAX ? */
1015         if (mode->repeat >= ALARM_REPEAT_MODE_MAX)
1016                 return ERR_ALARM_INVALID_PARAM;
1017
1018         error_code = __check_validation(alarm_info, __FUNCTION__);
1019         if (error_code != ALARMMGR_RESULT_SUCCESS)
1020                 return error_code;
1021
1022         if (!_send_alarm_create_appsvc(alarm_context, alarm_info, alarm_id, b, &error_code))
1023                 return error_code;
1024
1025         return ALARMMGR_RESULT_SUCCESS;
1026 }
1027
1028 EXPORT_API int alarmmgr_add_alarm_with_localtime(alarm_entry_t *alarm,
1029                 const char *destination,
1030                 alarm_id_t *alarm_id)
1031 {
1032         char dst_service_name[MAX_SERVICE_NAME_LEN] = { 0 };
1033         char dst_service_name_mod[MAX_SERVICE_NAME_LEN] = { 0 };
1034         alarm_info_t *alarm_info = NULL;
1035         alarm_mode_t *mode;
1036         int ret;
1037         int error_code;
1038         int i = 0;
1039         int j = 0;
1040
1041         LOGD("[alarm-lib]:alarm_create() is called\n");
1042
1043         if (alarm == NULL) {
1044                 LOGE("alarm is null");
1045                 return ERR_ALARM_INVALID_PARAM;
1046         }
1047
1048         alarm_info = (alarm_info_t *) alarm;
1049         if (alarm_info == NULL || alarm_id == NULL) {
1050                 LOGE("Invalid parameter bundle\n");
1051                 return ERR_ALARM_INVALID_PARAM;
1052         }
1053
1054         __adjust_current_milliseconds(alarm_info);
1055
1056         mode = &alarm_info->mode;
1057
1058         ret = __sub_init();
1059         if (ret < 0)
1060                 return ret;
1061
1062         LOGD("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)",
1063                         alarm_info->start.day, alarm_info->start.month, alarm_info->start.year,
1064                         alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec,
1065                         alarm_info->end.year, alarm_info->end.month, alarm_info->end.day,
1066                         alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type);
1067
1068         /* TODO: This should be changed to > ALARM_REPEAT_MODE_MAX ? */
1069         if (mode->repeat >= ALARM_REPEAT_MODE_MAX) {
1070                 LOGE("repeat is Invalid");
1071                 return ERR_ALARM_INVALID_PARAM;
1072         }
1073
1074         if (destination && strlen(destination) >= MAX_PKG_NAME_LEN) {
1075                 LOGE("[alarm-lib]: destination name is too long!\n");
1076                 return ERR_ALARM_INVALID_PARAM;
1077         }
1078
1079         error_code = __check_validation(alarm_info, __FUNCTION__);
1080         if (error_code != ALARMMGR_RESULT_SUCCESS)
1081                 return error_code;
1082
1083         if (destination != NULL) {
1084                 memset(dst_service_name, 0, strlen(destination) + strlen("ALARM.") + 2);
1085                 snprintf(dst_service_name, MAX_SERVICE_NAME_LEN, "ALARM.%s", destination);
1086                 memset(dst_service_name_mod, 'a', MAX_SERVICE_NAME_LEN-1);
1087
1088                 for (i = 0; i <= strlen(dst_service_name); i++) {
1089                         if (dst_service_name[i] == '.') {
1090                                 dst_service_name_mod[j] = dst_service_name[i];
1091                                 j++;
1092                         } else {
1093                                 dst_service_name_mod[j] = dst_service_name[i];
1094                         }
1095                         j++;
1096                 }
1097
1098                 if (!_send_alarm_create(alarm_context, alarm_info, alarm_id, dst_service_name, dst_service_name_mod, &error_code))
1099                         return error_code;
1100         } else {
1101                 if (!_send_alarm_create(alarm_context, alarm_info, alarm_id, "null", "null", &error_code))
1102                         return error_code;
1103         }
1104
1105         return ALARMMGR_RESULT_SUCCESS;
1106 }
1107
1108 EXPORT_API int alarmmgr_add_alarm_noti_with_localtime(alarm_entry_t *alarm, notification_h noti, alarm_id_t *alarm_id)
1109 {
1110         alarm_info_t *alarm_info = NULL;
1111         int error_code = 0;
1112         alarm_info = (alarm_info_t *)alarm;
1113         alarm_mode_t *mode;
1114
1115         if (alarm_info == NULL || alarm_id == NULL) {
1116                 LOGE("Invalid parameter\n");
1117                 return ERR_ALARM_INVALID_PARAM;
1118         }
1119
1120         __adjust_current_milliseconds(alarm_info);
1121
1122         if (__alarmmgr_init_appsvc() < 0) {
1123                 LOGE("Unable to initialize dbus!!!\n");
1124                 return ERR_ALARM_SYSTEM_FAIL;
1125         }
1126
1127         mode = &alarm_info->mode;
1128
1129         LOGW("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)",
1130                         alarm_info->start.day, alarm_info->start.month, alarm_info->start.year,
1131                         alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec,
1132                         alarm_info->end.year, alarm_info->end.month, alarm_info->end.day,
1133                         alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type);
1134
1135         /* TODO: This should be changed to > ALARM_REPEAT_MODE_MAX ? */
1136         if (mode->repeat >= ALARM_REPEAT_MODE_MAX)
1137                 return ERR_ALARM_INVALID_PARAM;
1138
1139         error_code = __check_validation(alarm_info, __FUNCTION__);
1140         if (error_code != ALARMMGR_RESULT_SUCCESS)
1141                 return error_code;
1142
1143         if (!_send_alarm_create_noti(alarm_context, alarm_info, alarm_id, noti, &error_code))
1144                 return error_code;
1145
1146         return ALARMMGR_RESULT_SUCCESS;
1147 }
1148
1149 EXPORT_API int alarmmgr_add_alarm_appsvc(int alarm_type, time_t trigger_at_time,
1150                 time_t interval, void *bundle_data,
1151                 alarm_id_t *alarm_id)
1152 {
1153         int error_code = 0;
1154         int result = 0;
1155         alarm_info_t alarm_info;
1156         const char *operation = NULL;
1157         const char *appid = NULL;
1158         bundle *b;
1159
1160         LOGD("[alarm-lib]:alarm_create() is called\n");
1161
1162         b = (bundle *)bundle_data;
1163         if (b == NULL) {
1164                 LOGE("Invalid parameter bundle\n");
1165                 return ERR_ALARM_INVALID_PARAM;
1166         }
1167
1168         operation = appsvc_get_operation(b);
1169         if (operation == NULL)
1170                 appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT);
1171
1172         appid = appsvc_get_appid(b);
1173
1174         if ((appid == NULL && (alarm_type & ALARM_TYPE_NOLAUNCH)) ||
1175                         (appid == NULL && operation && !strcmp(operation, APPSVC_OPERATION_DEFAULT))) {
1176                 LOGE("Invalid parameter\n");
1177                 return ERR_ALARM_INVALID_PARAM;
1178         }
1179
1180         if (__alarmmgr_init_appsvc() < 0) {
1181                 LOGE("Unable to initialize dbus!!!\n");
1182                 return ERR_ALARM_SYSTEM_FAIL;
1183         }
1184
1185         if (alarm_id == NULL) {
1186                 LOGE("alarm_id is null");
1187                 return ERR_ALARM_INVALID_PARAM;
1188         }
1189
1190         if (trigger_at_time < 0) {
1191                 LOGE("trigger_at_time is invalid[%ld]", trigger_at_time);
1192                 return ERR_ALARM_INVALID_PARAM;
1193         }
1194
1195         _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval,
1196                         false);
1197
1198         alarm_info.alarm_type |= ALARM_TYPE_RELATIVE;
1199         LOGD("alarm_info.type : %d", alarm_info.alarm_type);
1200
1201         if (__compare_api_version(&result, getuid()) < 0)
1202                 return ERR_ALARM_SYSTEM_FAIL;
1203         if (result < 0) {
1204                 if (alarm_info.alarm_type & ALARM_TYPE_INEXACT)
1205                         alarm_info.alarm_type ^= ALARM_TYPE_INEXACT;
1206         }
1207
1208         if ((alarm_type & ALARM_TYPE_INEXACT) &&
1209                         alarm_info.mode.u_interval.interval < MIN_INEXACT_INTERVAL)
1210                 alarm_info.mode.u_interval.interval = MIN_INEXACT_INTERVAL;
1211
1212         if (!_send_alarm_create_appsvc(alarm_context, &alarm_info, alarm_id, b, &error_code))
1213                 return error_code;
1214
1215
1216         LOGD("alarm_id : %d", *alarm_id);
1217
1218         return ALARMMGR_RESULT_SUCCESS;
1219 }
1220
1221 EXPORT_API int alarmmgr_add_alarm_noti(int alarm_type, time_t trigger_at_time,
1222                 time_t interval, notification_h noti,
1223                 alarm_id_t *alarm_id)
1224 {
1225         int error_code = 0;
1226         alarm_info_t alarm_info;
1227
1228         if (__alarmmgr_init_appsvc() < 0) {
1229                 LOGE("Unable to initialize dbus!!!\n");
1230                 return ERR_ALARM_SYSTEM_FAIL;
1231         }
1232
1233         if (alarm_id == NULL) {
1234                 LOGE("alarm_id is null");
1235                 return ERR_ALARM_INVALID_PARAM;
1236         }
1237
1238         if (trigger_at_time < 0) {
1239                 LOGE("trigger_at_time is invalid[%ld]", trigger_at_time);
1240                 return ERR_ALARM_INVALID_PARAM;
1241         }
1242
1243         _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval,
1244                         false);
1245
1246         alarm_info.alarm_type |= ALARM_TYPE_RELATIVE;
1247         LOGD("alarm_info.type : %d", alarm_info.alarm_type);
1248
1249         if ((alarm_info.alarm_type & ALARM_TYPE_INEXACT) &&
1250                         alarm_info.mode.u_interval.interval < MIN_INEXACT_INTERVAL)
1251                 alarm_info.mode.u_interval.interval = MIN_INEXACT_INTERVAL;
1252
1253         if (!_send_alarm_create_noti(alarm_context, &alarm_info, alarm_id, noti, &error_code))
1254                 return error_code;
1255
1256         return ALARMMGR_RESULT_SUCCESS;
1257 }
1258
1259 static int _alarmmgr_add_alarm(int alarm_type,
1260                 time_t trigger_at_time,
1261                 time_t interval, const char *destination,
1262                 alarm_id_t *alarm_id, bool precision)
1263 {
1264         char dst_service_name[MAX_SERVICE_NAME_LEN] = { 0 };
1265         char dst_service_name_mod[MAX_SERVICE_NAME_LEN] = { 0 };
1266         int i = 0;
1267         int j = 0;
1268         int error_code;
1269         alarm_info_t alarm_info;
1270         int ret;
1271
1272         ret = __sub_init();
1273         if (ret < 0)
1274                 return ret;
1275
1276         if (alarm_id == NULL) {
1277                 LOGE("[alarm-lib]: alarm_id is null");
1278                 return ERR_ALARM_INVALID_PARAM;
1279         }
1280
1281         if (trigger_at_time < 0)
1282                 LOGE("trigger_at_time is invalid[%ld]", trigger_at_time);
1283                 return ERR_ALARM_INVALID_PARAM;
1284
1285         if (destination && strlen(destination) >= MAX_PKG_NAME_LEN) {
1286                 LOGE("[alarm-lib]: destination name is too long!\n");
1287                 return ERR_ALARM_INVALID_PARAM;
1288         }
1289
1290         _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval,
1291                         precision);
1292
1293         alarm_info.alarm_type |= ALARM_TYPE_RELATIVE;
1294
1295         LOGD("alarm_info.type : %d", alarm_info.alarm_type);
1296
1297         if (destination != NULL) {
1298                 memset(dst_service_name, 0,
1299                                 strlen(destination) + strlen("ALARM.") + 2);
1300                 snprintf(dst_service_name, MAX_SERVICE_NAME_LEN, "ALARM.%s",
1301                                 destination);
1302                 memset(dst_service_name_mod, 'a', MAX_SERVICE_NAME_LEN - 1);
1303
1304                 j = 0;
1305                 for (i = 0; i <= strlen(dst_service_name); i++) {
1306                         if (dst_service_name[i] == '.') {
1307                                 dst_service_name_mod[j] = dst_service_name[i];
1308                                 j++;
1309                         } else {
1310                                 dst_service_name_mod[j] = dst_service_name[i];
1311                         }
1312                         j++;
1313                 }
1314
1315                 if (!_send_alarm_create(alarm_context, &alarm_info,
1316                                         alarm_id, dst_service_name,
1317                                         dst_service_name_mod,
1318                                         &error_code))
1319                         return error_code;
1320         } else {
1321                 if (!_send_alarm_create(alarm_context, &alarm_info, alarm_id,
1322                                         "null", "null", &error_code))
1323                         return error_code;
1324         }
1325
1326         return ALARMMGR_RESULT_SUCCESS;
1327 }
1328
1329 EXPORT_API int alarmmgr_add_alarm(int alarm_type, time_t trigger_at_time,
1330                 time_t interval, const char *destination,
1331                 alarm_id_t *alarm_id)
1332 {
1333         return _alarmmgr_add_alarm(alarm_type, trigger_at_time, interval,
1334                         destination, alarm_id, false);
1335 }
1336
1337 EXPORT_API int alarmmgr_add_alarm_precision(int alarm_type,
1338                 time_t trigger_at_time,
1339                 time_t interval, const char *destination,
1340                 alarm_id_t *alarm_id)
1341 {
1342         return _alarmmgr_add_alarm(alarm_type, trigger_at_time, interval,
1343                         destination, alarm_id, true);
1344 }
1345
1346 static int _alarmmgr_add_alarm_withcb(int alarm_type, time_t trigger_at_time,
1347                 time_t interval, alarm_cb_t handler, void *user_param,
1348                 alarm_id_t *alarm_id, bool precision)
1349 {
1350         int error_code = 0;
1351         alarm_info_t alarm_info;
1352         int ret = 0;
1353
1354         __check_appid();
1355         ret = alarmmgr_init(g_appid);
1356         if (ret < 0)
1357                 return ret;
1358
1359         LOGD("[alarm-lib]:alarmmgr_add_alarm_withcb() is called");
1360
1361         if (alarm_id == NULL) {
1362                 LOGE("alarm_id is null ");
1363                 return ERR_ALARM_INVALID_PARAM;
1364         }
1365
1366         if (trigger_at_time < 0) {
1367                 LOGE("trigger_at_time is invalid[%ld]", trigger_at_time);
1368                 return ERR_ALARM_INVALID_PARAM;
1369         }
1370
1371         _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval,
1372                         precision);
1373
1374         alarm_info.alarm_type |= ALARM_TYPE_RELATIVE;
1375         alarm_info.alarm_type |= ALARM_TYPE_WITHCB;
1376
1377         LOGD("alarm_info.type : %d", alarm_info.alarm_type);
1378
1379         if (!_send_alarm_create(alarm_context, &alarm_info, alarm_id, "null", "null", &error_code))
1380                 return error_code;
1381
1382         __add_resultcb(*alarm_id, handler, user_param);
1383
1384         return ALARMMGR_RESULT_SUCCESS;
1385 }
1386
1387 EXPORT_API int alarmmgr_add_alarm_withcb(int alarm_type, time_t trigger_at_time,
1388                 time_t interval, alarm_cb_t handler, void *user_param, alarm_id_t *alarm_id)
1389 {
1390         return _alarmmgr_add_alarm_withcb(alarm_type, trigger_at_time, interval,
1391                         handler, user_param, alarm_id, false);
1392 }
1393
1394 EXPORT_API int alarmmgr_add_alarm_withcb_precision(int alarm_type, time_t trigger_at_time,
1395                                   time_t interval, alarm_cb_t handler, void *user_param, alarm_id_t *alarm_id)
1396 {
1397         return _alarmmgr_add_alarm_withcb(alarm_type, trigger_at_time, interval,
1398                         handler, user_param, alarm_id, true);
1399 }
1400
1401 EXPORT_API int alarmmgr_remove_alarm(alarm_id_t alarm_id)
1402 {
1403         int error_code;
1404         int ret;
1405         alarm_cb_info_t *info;
1406
1407         ret = __sub_init();
1408         if (ret < 0)
1409                 return ret;
1410
1411         LOGD("[alarm-lib]:alarm_delete(%d) is called\n", alarm_id);
1412
1413         if (alarm_id <= 0) {
1414                 LOGE("[alarm-lib]:alarm_id is invalid[%d]\n", alarm_id);
1415                 return ERR_ALARM_INVALID_ID;
1416         }
1417
1418         if (!_send_alarm_delete(alarm_context, alarm_id, &error_code))
1419                 return error_code;
1420
1421         info = __find_resultcb(alarm_id);
1422         __remove_resultcb(info);
1423
1424         return ALARMMGR_RESULT_SUCCESS;
1425 }
1426
1427 EXPORT_API int alarmmgr_remove_all(void)
1428 {
1429         int error_code;
1430         int return_code = ALARMMGR_RESULT_SUCCESS;
1431         int ret = __sub_init();
1432         if (ret < 0)
1433                 return ret;
1434
1435         if (!_send_alarm_delete_all(alarm_context, &error_code))
1436                 return error_code;
1437
1438         return return_code;
1439 }
1440
1441 EXPORT_API int alarmmgr_enum_alarm_ids(alarm_enum_fn_t fn, void *user_param)
1442 {
1443         SECURE_LOGD("Enter");
1444         int return_code = 0;
1445         int maxnum_of_ids = 0;
1446         int num_of_ids = 0;
1447         alarm_id_t alarm_id;
1448         int ret = 0;
1449         GVariantIter *iter = NULL;
1450
1451         if (fn == NULL) {
1452                 LOGE("fn is null.");
1453                 return ERR_ALARM_INVALID_PARAM;
1454         }
1455
1456         ret = __sub_init();
1457         if (ret < 0) {
1458                 LOGE("__sub_init() is failed.");
1459                 return ret;
1460         }
1461
1462         if (!_send_alarm_get_number_of_ids(alarm_context, &maxnum_of_ids, &return_code))
1463                 return return_code;
1464
1465         LOGD("maxnum_of_ids[%d]", maxnum_of_ids);
1466
1467         if (!_send_alarm_get_list_of_ids(alarm_context, maxnum_of_ids, &iter, &num_of_ids, &return_code))
1468                 return return_code;
1469
1470         while (g_variant_iter_loop(iter, "i", &alarm_id)) {
1471                 LOGD("alarm_id (%d)", alarm_id);
1472                 (*fn)(alarm_id, user_param);
1473         }
1474         g_variant_iter_free(iter);
1475
1476         return ALARMMGR_RESULT_SUCCESS;
1477 }
1478
1479 EXPORT_API int alarmmgr_get_info(alarm_id_t alarm_id, alarm_entry_t *alarm)
1480 {
1481         int error_code;
1482         alarm_info_t *alarm_info = (alarm_info_t *) alarm;
1483         int ret;
1484
1485         ret = __sub_init();
1486         if (ret < 0)
1487                 return ret;
1488
1489         LOGD("[alarm-lib]:alarm_get_info() is called\n");
1490
1491         if (alarm_id < 0 || alarm_info == NULL) {
1492                 LOGE("[alarm-lib]:alarm_info is null or alar_id is invalid[%d].", alarm_id);
1493                 return ERR_ALARM_INVALID_PARAM;
1494         }
1495
1496         if (!_send_alarm_get_info(alarm_context, alarm_id, alarm_info, &error_code))
1497                 return error_code;
1498
1499         return ALARMMGR_RESULT_SUCCESS;
1500 }
1501
1502 int alarmmgr_get_number_of_ids(int *num_of_ids)
1503 {
1504         int error_code;
1505         LOGD("[alarm-lib]: alarm_get_number_of_ids() is called.");
1506
1507         if (num_of_ids == NULL) {
1508                 LOGE("[alarm-lib]:num_of_ids.");
1509                 return ERR_ALARM_INVALID_PARAM;
1510         }
1511
1512         LOGD("call alarm_get_number_of_ids\n");
1513         if (!_send_alarm_get_number_of_ids(alarm_context, num_of_ids, &error_code))
1514                 return error_code;
1515
1516         return ALARMMGR_RESULT_SUCCESS;
1517 }
1518
1519 EXPORT_API int alarmmgr_get_next_duetime(alarm_id_t alarm_id, time_t *duetime)
1520 {
1521         int error_code;
1522         int ret;
1523
1524         ret = __sub_init();
1525         if (ret < 0)
1526                 return ret;
1527
1528         LOGD("[alarm-lib]:alarmmgr_get_next_duetime() is called.");
1529
1530         if (duetime == NULL) {
1531                 LOGE("[alarm-lib]:duetime is null.");
1532                 return ERR_ALARM_INVALID_PARAM;
1533         }
1534
1535         if (!_send_alarm_get_next_duetime(alarm_context, alarm_id, duetime, &error_code))
1536                 return error_code;
1537
1538         return ALARMMGR_RESULT_SUCCESS;
1539 }
1540
1541 EXPORT_API int alarmmgr_get_all_info(char **db_path)
1542 {
1543         int error_code;
1544         LOGD("[alarm-lib]:alarmmgr_get_all_info() is called.");
1545
1546         if (db_path == NULL) {
1547                 LOGE("[alarm-lib]:db_path is null.");
1548                 return ERR_ALARM_INVALID_PARAM;
1549         }
1550
1551         if (!_send_alarm_get_all_info(alarm_context, db_path, &error_code))
1552                 return error_code;
1553
1554         LOGD("[alarm-lib]: successfully save info in %s.", *db_path);
1555         return ALARMMGR_RESULT_SUCCESS;
1556 }
1557
1558 EXPORT_API int alarmmgr_add_periodic_alarm_withcb(int interval, periodic_method_e method,
1559                 alarm_cb_t handler, void *user_param, alarm_id_t *alarm_id)
1560 {
1561         int error_code = 0;
1562         int ret = 0;
1563
1564         __check_appid();
1565         ret = alarmmgr_init(g_appid);
1566         if (ret < 0)
1567                 return ret;
1568
1569         if (alarm_id == NULL) {
1570                 LOGE("[alarm-lib]:alarm_id is null.");
1571                 return ERR_ALARM_INVALID_PARAM;
1572         }
1573
1574         if (!_send_alarm_create_periodic(alarm_context, interval, 0,
1575                                 (int)method, alarm_id,
1576                                 &error_code))
1577                 return error_code;
1578
1579         __add_resultcb(*alarm_id, handler, user_param);
1580
1581         return ALARMMGR_RESULT_SUCCESS;
1582 }
1583
1584 EXPORT_API int alarmmgr_add_reference_periodic_alarm_withcb(int interval,
1585                 alarm_cb_t handler, void *user_param, alarm_id_t *alarm_id)
1586 {
1587         int error_code = 0;
1588         int ret = 0;
1589
1590         __check_appid();
1591         ret = alarmmgr_init(g_appid);
1592         if (ret < 0)
1593                 return ret;
1594
1595         if (alarm_id == NULL) {
1596                 LOGE("[alarm-lib]:alarm_id is null.");
1597                 return ERR_ALARM_INVALID_PARAM;
1598         }
1599
1600         if (!_send_alarm_create_periodic(alarm_context, interval, 1, 0,
1601                                 alarm_id, &error_code))
1602                 return error_code;
1603
1604         __add_resultcb(*alarm_id, handler, user_param);
1605
1606         return ALARMMGR_RESULT_SUCCESS;
1607 }
1608
1609 EXPORT_API int alarmmgr_set_systime(int new_time)
1610 {
1611         return alarmmgr_set_systime64((time_t)new_time);
1612 }
1613
1614 EXPORT_API int alarmmgr_set_systime64(time_t new_time)
1615 {
1616         int error_code;
1617         LOGD("[alarm-lib]:alarmmgr_set_systime(%ld) is called.", new_time);
1618
1619         if (__sub_init() < 0)
1620                 return ERR_ALARM_SYSTEM_FAIL;
1621
1622         if (!_send_alarm_set_time(alarm_context, new_time, &error_code)) {
1623                 LOGE("Failed to set time. error: %d", error_code);
1624                 return error_code;
1625         }
1626
1627         LOGD("[alarm-lib]: successfully set the time(%ld) by pid(%d).", new_time, getpid());
1628         return ALARMMGR_RESULT_SUCCESS;
1629 }
1630
1631 EXPORT_API int alarmmgr_set_systime_async(int new_time, alarm_set_time_cb_t result_cb, void *user_param)
1632 {
1633         return alarmmgr_set_systime64_async((time_t)new_time, result_cb, user_param);
1634 }
1635
1636 EXPORT_API int alarmmgr_set_systime64_async(time_t new_time, alarm_set_time_cb_t result_cb, void *user_param)
1637 {
1638         struct alarm_async_param_t *param;
1639
1640         LOGD("[alarm-lib]:alarmmgr_set_systime(%ld) is called.", new_time);
1641
1642         if (sub_initialized) {
1643                 if (!_send_alarm_set_time_async(alarm_context, new_time,
1644                                         result_cb, user_param))
1645                         return ERR_ALARM_SYSTEM_FAIL;
1646         } else {
1647 #if !(GLIB_CHECK_VERSION(2, 32, 0))
1648                 g_thread_init(NULL);
1649 #endif
1650 #if !(GLIB_CHECK_VERSION(2, 36, 0))
1651                 g_type_init();
1652 #endif
1653                 param = g_try_new0(struct alarm_async_param_t, 1);
1654                 if (param == NULL) {
1655                         LOGE("Failed to alloc param");
1656                         return ERR_ALARM_SYSTEM_FAIL;
1657                 }
1658                 param->type = SET_SYSTIME;
1659                 param->v = g_variant_new("i", new_time);
1660                 param->result_cb = result_cb;
1661                 param->user_param = user_param;
1662                 g_bus_get(G_BUS_TYPE_SYSTEM, NULL, __bus_get_for_async_api, param);
1663         }
1664
1665         return ALARMMGR_RESULT_SUCCESS;
1666 }
1667
1668 EXPORT_API int alarmmgr_set_systime_with_propagation_delay(struct timespec new_time, struct timespec req_time)
1669 {
1670         int error_code;
1671         LOGD("[alarm-lib] New: %ld(sec) %09ld(nsec), Requested: %ld(sec) %09ld(nsec)",
1672                         new_time.tv_sec, new_time.tv_nsec, req_time.tv_sec, req_time.tv_nsec);
1673
1674         if (__sub_init() < 0)
1675                 return ERR_ALARM_SYSTEM_FAIL;
1676
1677         if (!_send_alarm_set_time_with_propagation_delay(alarm_context, new_time, req_time, &error_code)) {
1678                 LOGE("Failed to set time with propagation delay. error: %d", error_code);
1679                 return error_code;
1680         }
1681
1682         LOGD("[alarm-lib]: successfully set the time by pid(%d).", getpid());
1683         return ALARMMGR_RESULT_SUCCESS;
1684 }
1685
1686 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)
1687 {
1688         struct alarm_async_param_t *param;
1689
1690         LOGD("[alarm-lib] New: %ld(sec) %09ld(nsec), Requested: %ld(sec) %09ld(nsec)",
1691                 new_time.tv_sec, new_time.tv_nsec, req_time.tv_sec, req_time.tv_nsec);
1692
1693         if (sub_initialized) {
1694                 if (!_send_alarm_set_time_with_propagation_delay_async(alarm_context,
1695                                         new_time, req_time, result_cb, user_param))
1696                         return ERR_ALARM_SYSTEM_FAIL;
1697         } else {
1698 #if !(GLIB_CHECK_VERSION(2, 32, 0))
1699                 g_thread_init(NULL);
1700 #endif
1701 #if !(GLIB_CHECK_VERSION(2, 36, 0))
1702                 g_type_init();
1703 #endif
1704                 param = g_try_new0(struct alarm_async_param_t, 1);
1705                 if (param == NULL) {
1706                         LOGE("Failed to alloc param");
1707                         return ERR_ALARM_SYSTEM_FAIL;
1708                 }
1709                 param->type = SET_SYSTIME_WITH_PROPAGATION_DELAY;
1710                 param->v = g_variant_new("(xxxx)",
1711                                 (gint64)new_time.tv_sec, (gint64)new_time.tv_nsec,
1712                                 (gint64)req_time.tv_sec, (gint64)req_time.tv_nsec);
1713                 param->result_cb = result_cb;
1714                 param->user_param = user_param;
1715                 g_bus_get(G_BUS_TYPE_SYSTEM, NULL, __bus_get_for_async_api, param);
1716         }
1717
1718         return ALARMMGR_RESULT_SUCCESS;
1719 }
1720
1721 EXPORT_API int alarmmgr_set_timezone(char *tzpath_str)
1722 {
1723         int error_code;
1724         LOGD("[alarm-lib]:alarmmgr_set_timezone() is called.");
1725
1726         if (tzpath_str == NULL) {
1727                 LOGE("[alarm-lib]:tzpath_str is NULL\n");
1728                 return ERR_ALARM_INVALID_PARAM;
1729         }
1730
1731         if (__sub_init() < 0)
1732                 return ERR_ALARM_SYSTEM_FAIL;
1733
1734         if (!_send_alarm_set_timezone(alarm_context, tzpath_str, &error_code))
1735                 return error_code;
1736
1737         LOGD("[alarm-lib]: successfully set the timezone(%s) by pid(%d)", tzpath_str, getpid());
1738         return ALARMMGR_RESULT_SUCCESS;
1739 }
1740
1741 EXPORT_API int alarmmgr_set_global(const alarm_id_t alarm_id,
1742                 bool global)
1743 {
1744         int error_code;
1745         LOGD("[alarm-lib]:alarmmgr_set_global(%d) is called.", alarm_id);
1746
1747         if (__sub_init() < 0)
1748                 return ERR_ALARM_SYSTEM_FAIL;
1749
1750         if (!_send_alarm_set_global(alarm_context, alarm_id, global, &error_code))
1751                 return error_code;
1752
1753         return ALARMMGR_RESULT_SUCCESS;
1754 }
1755
1756
1757 EXPORT_API int alarmmgr_get_global(const alarm_id_t alarm_id,
1758                 bool *global)
1759 {
1760         int error_code;
1761
1762         if (__sub_init() < 0)
1763                 return ERR_ALARM_SYSTEM_FAIL;
1764
1765         if (global == NULL) {
1766                 LOGE("[alarm-lib]:global is NULL\n");
1767                 return ERR_ALARM_INVALID_PARAM;
1768         }
1769
1770         if (!_send_alarm_get_global(alarm_context, alarm_id, global, &error_code))
1771                 return error_code;
1772
1773         return ALARMMGR_RESULT_SUCCESS;
1774 }
1775
1776 EXPORT_API int alarmmgr_update_alarm(alarm_id_t alarm_id,
1777                 alarm_entry_t *alarm, int update_flag)
1778 {
1779         alarm_info_t *alarm_info;
1780         int ret;
1781
1782         LOGD("[alarm-lib]:alarmmgr_update_alarm() is called\n");
1783
1784         if (alarm == NULL) {
1785                 LOGE("[alarm-lib]:alarm is NULL\n");
1786                 return ERR_ALARM_INVALID_PARAM;
1787         }
1788
1789         alarm_info = (alarm_info_t *) alarm;
1790         if (alarm_info == NULL || alarm_id <= 0) {
1791                 LOGE("[alarm-lib]:alarm is NULL or invalid alarm_id[%d]\n", alarm_id);
1792                 return ERR_ALARM_INVALID_PARAM;
1793         }
1794
1795         int error_code;
1796
1797         ret = __sub_init();
1798         if (ret < 0)
1799                 return ret;
1800
1801         LOGD("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)",
1802                         alarm_info->start.day, alarm_info->start.month, alarm_info->start.year,
1803                         alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec,
1804                         alarm_info->end.year, alarm_info->end.month, alarm_info->end.day,
1805                         alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type);
1806
1807         if (update_flag == ALARM_UPDATE_FLAG_TIME) {
1808                 error_code = __check_validation(alarm_info, __FUNCTION__);
1809                 if (error_code != ALARMMGR_RESULT_SUCCESS)
1810                         return error_code;
1811         }
1812
1813         if (!_send_alarm_update(alarm_context, alarm_id, alarm_info, update_flag, &error_code))
1814                 return error_code;
1815
1816         return ALARMMGR_RESULT_SUCCESS;
1817 }