df7f45d60324b2078b6e8a674dfd30a2635355f4
[platform/core/pim/calendar-service.git] / server / cal_server_dbus.c
1 /*
2  * Calendar Service
3  *
4  * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdlib.h>
21 #include <gio/gio.h>
22
23 #include "calendar.h"
24 #include "cal_internal.h"
25 #include "cal_typedef.h"
26 #include "cal_handle.h"
27 #include "cal_dbus_helper.h"
28 #include "cal_dbus.h"
29 #include "cal_db.h"
30 #include "cal_db_util.h"
31 #include "cal_server_dbus.h"
32 #include "cal_utils.h"
33 #include "cal_server_ondemand.h"
34
35 static calDbus *dbus_object = NULL;
36 static GMutex cal_server_dbus_sender;
37 static GList *cal_sender_list; /* global list to care resource handle for each sender bus */
38
39 typedef struct _cal_sender {
40         gchar *name;
41 } cal_sender_s;
42
43 calDbus* cal_dbus_get_object(void)
44 {
45         return dbus_object;
46 }
47
48 static bool _has_sender(const char *name, GList **out_cursor)
49 {
50         bool has_sender = false;
51
52         GList *cursor = NULL;
53         cursor = cal_sender_list;
54         while (cursor) {
55                 cal_sender_s *sender = (cal_sender_s *)cursor->data;
56                 if (NULL == sender) {
57                         ERR("sender is NULL");
58                         cursor = g_list_next(cursor);
59                         continue;
60                 }
61                 if (CAL_STRING_EQUAL == g_strcmp0(sender->name, name)) {
62                         DBG("found sender[%s]", name);
63                         has_sender = true;
64                         if (out_cursor)
65                                 *out_cursor = cursor;
66                         break;
67                 }
68                 cursor = g_list_next(cursor);
69         }
70         return has_sender;
71 }
72
73 static int _append_sender(const char *name)
74 {
75         RETV_IF(NULL == name, CALENDAR_ERROR_INVALID_PARAMETER);
76
77         cal_sender_s *sender = NULL;
78         sender = calloc(1, sizeof(cal_sender_s));
79         if (NULL == sender) {
80                 ERR("calloc() Fail");
81                 return CALENDAR_ERROR_OUT_OF_MEMORY;
82         }
83         sender->name = cal_strdup(name);
84         DBG("[SENDER] Append sender[%s]", sender->name);
85         cal_sender_list = g_list_append(cal_sender_list, sender);
86         return CALENDAR_ERROR_NONE;
87 }
88
89 static gboolean _handle_register_resource(calDbus *object,
90                 GDBusMethodInvocation *invocation)
91 {
92         CAL_FN_CALL();
93
94         int ret = 0;
95         const char *sender_name = NULL;
96         sender_name = g_dbus_method_invocation_get_sender(invocation);
97
98         g_mutex_lock(&cal_server_dbus_sender);
99         if (true == _has_sender(sender_name, NULL)) {
100                 ERR("Already has sender");
101                 g_mutex_unlock(&cal_server_dbus_sender);
102                 return TRUE;
103         }
104         ret = _append_sender(sender_name);
105         if (CALENDAR_ERROR_NONE != ret) {
106                 ERR("_append_sender() Fail");
107                 g_mutex_unlock(&cal_server_dbus_sender);
108                 return TRUE;
109         }
110         DBG("append sender");
111         g_mutex_unlock(&cal_server_dbus_sender);
112
113         cal_dbus_complete_register_resource(object, invocation, ret);
114
115         return TRUE;
116 }
117
118 static gboolean _handle_unregister_resource(calDbus *object,
119                 GDBusMethodInvocation *invocation)
120 {
121         CAL_FN_CALL();
122
123         int ret = 0;
124         const char *sender_name = NULL;
125         sender_name = g_dbus_method_invocation_get_sender(invocation);
126
127         GList *cursor = NULL;
128         g_mutex_lock(&cal_server_dbus_sender);
129         if (true == _has_sender(sender_name, &cursor)) {
130                 DBG("[SENDER] delete sender[%s]", sender_name);
131                 cal_sender_s *sender = (cal_sender_s *)cursor->data;
132                 free(sender->name);
133                 sender->name = NULL;
134                 cal_sender_list = g_list_delete_link(cal_sender_list, cursor);
135         }
136
137         if (0 == g_list_length(cal_sender_list)) {
138                 DBG("sender list is 0");
139                 g_list_free_full(cal_sender_list, free);
140                 cal_sender_list = NULL;
141         }
142         g_mutex_unlock(&cal_server_dbus_sender);
143
144         cal_dbus_complete_unregister_resource(object, invocation, ret);
145
146         return TRUE;
147 }
148
149 static gboolean _handle_insert_record(calDbus *object, GDBusMethodInvocation *invocation,
150                 GVariant *arg_handle, GVariant *arg_record)
151 {
152         int ret = 0;
153         calendar_record_h record = NULL;
154         ret = cal_dbus_utils_gvariant_to_record(arg_record, &record);
155
156         int id = 0;
157         ret = cal_db_insert_record(record, &id);
158
159         int version = 0;
160         version = cal_db_util_get_transaction_ver();
161         cal_dbus_complete_insert_record(object, invocation, id, version, ret);
162         calendar_record_destroy(record, true);
163
164         cal_server_ondemand_start();
165         return TRUE;
166 }
167
168 static gboolean _handle_update_record(calDbus *object, GDBusMethodInvocation *invocation,
169                 GVariant *arg_handle, GVariant *arg_record)
170 {
171         int ret = 0;
172         calendar_record_h record = NULL;
173         ret = cal_dbus_utils_gvariant_to_record(arg_record, &record);
174
175         ret = cal_db_update_record(record);
176
177         int version = 0;
178         version = cal_db_util_get_transaction_ver();
179         cal_dbus_complete_update_record(object, invocation, version, ret);
180         calendar_record_destroy(record, true);
181
182         cal_server_ondemand_start();
183         return TRUE;
184 }
185
186 static gboolean _handle_delete_record(calDbus *object, GDBusMethodInvocation *invocation,
187                 GVariant *arg_handle, char *view_uri, int id)
188 {
189         int ret = 0;
190         ret = cal_db_delete_record(view_uri, id);
191
192         int version = 0;
193         version = cal_db_util_get_transaction_ver();
194         cal_dbus_complete_delete_record(object, invocation, version, ret);
195
196         cal_server_ondemand_start();
197         return TRUE;
198 }
199
200 static gboolean _handle_replace_record(calDbus *object, GDBusMethodInvocation *invocation,
201                 GVariant *arg_handle, GVariant *arg_record, int id)
202 {
203         int ret = 0;
204         calendar_record_h record = NULL;
205         ret = cal_dbus_utils_gvariant_to_record(arg_record, &record);
206
207         ret = cal_db_replace_record(record, id);
208
209         int version = 0;
210         version = cal_db_util_get_transaction_ver();
211         cal_dbus_complete_replace_record(object, invocation, version, ret);
212         calendar_record_destroy(record, true);
213
214         cal_server_ondemand_start();
215         return TRUE;
216 }
217
218 static gboolean _handle_insert_records(calDbus *object, GDBusMethodInvocation *invocation,
219                 GVariant *arg_handle, GVariant *arg_list)
220 {
221         int ret = 0;
222         calendar_list_h list = NULL;
223         ret = cal_dbus_utils_gvariant_to_list(arg_list, &list);
224
225         int *ids = NULL;
226         int count = 0;
227         ret = cal_db_insert_records(list, &ids, &count);
228         calendar_list_destroy(list, true);
229
230         int version = 0;
231         version = cal_db_util_get_transaction_ver();
232         GVariant *arg_ids = cal_dbus_utils_ids_to_gvariant(ids, count);
233         cal_dbus_complete_insert_records(object, invocation, arg_ids, count, version, ret);
234
235         free(ids);
236         g_variant_unref(arg_ids);
237
238         cal_server_ondemand_start();
239         return TRUE;
240 }
241
242 static gboolean _handle_update_records(calDbus *object, GDBusMethodInvocation *invocation,
243                 GVariant *arg_handle, GVariant *arg_list)
244 {
245         int ret = 0;
246         calendar_list_h list = NULL;
247         ret = cal_dbus_utils_gvariant_to_list(arg_list, &list);
248
249         ret = cal_db_update_records(list);
250         calendar_list_destroy(list, true);
251
252         int version = 0;
253         version = cal_db_util_get_transaction_ver();
254         cal_dbus_complete_update_records(object, invocation, version, ret);
255
256         cal_server_ondemand_start();
257         return TRUE;
258 }
259
260 static gboolean _handle_delete_records(calDbus *object, GDBusMethodInvocation *invocation,
261                 GVariant *arg_handle, char *view_uri, GVariant *arg_ids, int count)
262 {
263         int ret = 0;
264         int *ids = NULL;
265         ret = cal_dbus_utils_gvariant_to_ids(arg_ids, count, &ids);
266
267         ret = cal_db_delete_records(view_uri, ids, count);
268
269         int version = 0;
270         version = cal_db_util_get_transaction_ver();
271         cal_dbus_complete_delete_records(object, invocation, version, ret);
272         free(ids);
273
274         cal_server_ondemand_start();
275         return TRUE;
276 }
277
278 static gboolean _handle_replace_records(calDbus *object, GDBusMethodInvocation *invocation,
279                 GVariant *arg_handle, GVariant *arg_list, GVariant *arg_ids, int count)
280 {
281         int ret = 0;
282         calendar_list_h list = NULL;
283         int *ids = NULL;
284         ret = cal_dbus_utils_gvariant_to_list(arg_list, &list);
285         ret = cal_dbus_utils_gvariant_to_ids(arg_ids, count, &ids);
286
287         ret = cal_db_replace_records(list, ids, count);
288         free(ids);
289         calendar_list_destroy(list, true);
290
291         int version = 0;
292         version = cal_db_util_get_transaction_ver();
293         cal_dbus_complete_replace_records(object, invocation, version, ret);
294
295         cal_server_ondemand_start();
296         return TRUE;
297 }
298
299 static gboolean _handle_get_record(calDbus *object, GDBusMethodInvocation *invocation,
300                 GVariant *arg_handle, char *view_uri, int id)
301 {
302         int ret = 0;
303         calendar_record_h record = NULL;
304         ret = cal_db_get_record(view_uri, id, &record);
305
306         GVariant *arg_record = cal_dbus_utils_record_to_gvariant(record);
307         cal_dbus_complete_get_record(object, invocation, arg_record, ret);
308         g_variant_unref(arg_record);
309         calendar_record_destroy(record, true);
310
311         cal_server_ondemand_start();
312         return TRUE;
313 }
314
315 static gboolean _handle_get_all_records(calDbus *object, GDBusMethodInvocation *invocation,
316                 GVariant *arg_handle, char *view_uri, int offset, int limit)
317 {
318         CAL_FN_CALL();
319
320         int ret = 0;
321         calendar_list_h list = NULL;
322         ret = cal_db_get_all_records(view_uri, offset, limit, &list);
323
324         GVariant *arg_list = cal_dbus_utils_list_to_gvariant(list);
325         cal_dbus_complete_get_all_records(object, invocation, arg_list, ret);
326         calendar_list_destroy(list, true);
327         g_variant_unref(arg_list);
328
329         cal_server_ondemand_start();
330         return TRUE;
331 }
332
333 static gboolean _handle_get_records_with_query(calDbus *object, GDBusMethodInvocation *invocation,
334                 GVariant *arg_handle, GVariant *arg_query, int offset, int limit)
335 {
336         int ret = 0;
337         calendar_query_h query = NULL;
338         ret = cal_dbus_utils_gvariant_to_query(arg_query, &query);
339
340         calendar_list_h list = NULL;
341         ret = cal_db_get_records_with_query(query, offset, limit, &list);
342
343         GVariant *arg_list = cal_dbus_utils_list_to_gvariant(list);
344         cal_dbus_complete_get_records_with_query(object, invocation, arg_list, ret);
345         g_variant_unref(arg_list);
346         calendar_list_destroy(list, true);
347
348         cal_server_ondemand_start();
349         return TRUE;
350 }
351
352 static gboolean _handle_get_count(calDbus *object, GDBusMethodInvocation *invocation,
353                 GVariant *arg_handle, char *view_uri)
354 {
355         int ret = 0;
356         int count = 0;
357         ret = cal_db_get_count(view_uri, &count);
358
359         cal_dbus_complete_get_count(object, invocation, count, ret);
360
361         cal_server_ondemand_start();
362         return TRUE;
363 }
364
365 static gboolean _handle_get_count_with_query(calDbus *object, GDBusMethodInvocation *invocation,
366                 GVariant *arg_handle, GVariant *arg_query)
367 {
368         int ret = 0;
369         calendar_query_h query = NULL;
370         ret = cal_dbus_utils_gvariant_to_query(arg_query, &query);
371
372         int count = 0;
373         ret = cal_db_get_count_with_query(query, &count);
374         cal_dbus_complete_get_count_with_query(object, invocation, count, ret);
375
376         cal_server_ondemand_start();
377         return TRUE;
378 }
379
380 static gboolean _handle_get_current_version(calDbus *object, GDBusMethodInvocation *invocation,
381                 GVariant *arg_handle)
382 {
383         int ret = 0;
384         int version = 0;
385         ret = cal_db_get_current_version(&version);
386
387         cal_dbus_complete_get_current_version(object, invocation, version, ret);
388
389         cal_server_ondemand_start();
390         return TRUE;
391 }
392
393 static gboolean _handle_check_permission_write(calDbus *object, GDBusMethodInvocation *invocation)
394 {
395         cal_dbus_complete_check_permission_write(object, invocation);
396         cal_server_ondemand_start();
397         return TRUE;
398 }
399
400 static gboolean _handle_check_permission_read(calDbus *object, GDBusMethodInvocation *invocation)
401 {
402         cal_dbus_complete_check_permission_read(object, invocation);
403         cal_server_ondemand_start();
404         return TRUE;
405 }
406
407 static gboolean _handle_get_changes_by_version(calDbus *object, GDBusMethodInvocation *invocation,
408                 GVariant *arg_handle, char *view_uri, int book_id, int in_version)
409 {
410         int ret = 0;
411         calendar_list_h list = NULL;
412         int out_version = 0;
413         ret = cal_db_get_changes_by_version(view_uri, book_id, in_version, &list, &out_version);
414
415         GVariant *arg_list = cal_dbus_utils_list_to_gvariant(list);
416         cal_dbus_complete_get_changes_by_version(object, invocation, arg_list, out_version, ret);
417         calendar_list_destroy(list, true);
418         g_variant_unref(arg_list);
419
420         cal_server_ondemand_start();
421         return TRUE;
422 }
423
424 static gboolean _handle_get_changes_exception_by_version(calDbus *object,
425                 GDBusMethodInvocation *invocation,
426                 GVariant *arg_handle,
427                 char *view_uri,
428                 int original_id,
429                 int version)
430 {
431         int ret = 0;
432         calendar_list_h list = NULL;
433         ret = cal_db_get_changes_exception_by_version(view_uri, original_id, version, &list);
434
435         GVariant *arg_list = cal_dbus_utils_list_to_gvariant(list);
436         cal_dbus_complete_get_changes_exception_by_version(object, invocation, arg_list, ret);
437         calendar_list_destroy(list, true);
438         g_variant_unref(arg_list);
439
440         cal_server_ondemand_start();
441         return TRUE;
442 }
443
444 static gboolean _handle_clean_after_sync(calDbus *object, GDBusMethodInvocation *invocation,
445                 GVariant *arg_handle, int book_id, int version)
446 {
447         int ret = 0;
448         ret = cal_db_clean_after_sync(book_id, version);
449
450         cal_dbus_complete_clean_after_sync(object, invocation, ret);
451
452         cal_server_ondemand_start();
453         return TRUE;
454 }
455
456 static gboolean _handle_insert_vcalendars(calDbus *object, GDBusMethodInvocation *invocation,
457                 GVariant *arg_handle, char *stream)
458 {
459         int ret = 0;
460         int *ids = NULL;
461         int count = 0;
462         ret = cal_db_insert_vcalendars(stream, &ids, &count);
463
464         GVariant *arg_ids = cal_dbus_utils_ids_to_gvariant(ids, count);
465
466         int version = 0;
467         version = cal_db_util_get_transaction_ver();
468         cal_dbus_complete_insert_vcalendars(object, invocation, arg_ids, count, version, ret);
469         free(ids);
470         g_variant_unref(arg_ids);
471
472         cal_server_ondemand_start();
473         return TRUE;
474 }
475
476 static gboolean _handle_replace_vcalendars(calDbus *object, GDBusMethodInvocation *invocation,
477                 GVariant *arg_handle, char *stream, GVariant *arg_ids, int count)
478 {
479         int ret = 0;
480         int *ids = NULL;
481         ret = cal_dbus_utils_gvariant_to_ids(arg_ids, count, &ids);
482
483         ret = cal_db_replace_vcalendars(stream, ids, count);
484
485         int version = 0;
486         version = cal_db_util_get_transaction_ver();
487         cal_dbus_complete_replace_vcalendars(object, invocation, ret, version);
488         free(ids);
489
490         cal_server_ondemand_start();
491         return TRUE;
492 }
493
494 static int _cal_server_dbus_find_sender(const char *owner_name, cal_sender_s **out_sender)
495 {
496         GList *cursor = NULL;
497
498         RETV_IF(NULL == owner_name, CALENDAR_ERROR_INVALID_PARAMETER);
499         RETV_IF(NULL == out_sender, CALENDAR_ERROR_INVALID_PARAMETER);
500
501         cursor = cal_sender_list;
502         while (cursor) {
503                 cal_sender_s *sender = (cal_sender_s *)cursor->data;
504                 if (NULL == sender) {
505                         ERR("sender is NULL");
506                         return CALENDAR_ERROR_NO_DATA;
507                 }
508
509                 if (CAL_STRING_EQUAL == g_strcmp0(sender->name, owner_name)) {
510                         *out_sender = sender;
511                         break;
512                 }
513                 cursor = g_list_next(cursor);
514         }
515
516         return CALENDAR_ERROR_NONE;
517 }
518
519 static void _delete_sender(cal_sender_s *sender)
520 {
521         RET_IF(NULL == sender);
522
523         GList *cursor = cal_sender_list;
524         while (cursor) {
525                 if (cursor->data == sender) {
526                         DBG("[SENDER] Delete sender[%s]", sender->name);
527                         free(sender->name);
528                         sender->name = NULL;
529                         cal_sender_list = g_list_delete_link(cal_sender_list, cursor);
530                         break;
531                 }
532                 cursor = g_list_next(cursor);
533         }
534 }
535
536 static void _cal_server_dbus_name_owner_changed_cb(GDBusConnection *connection,
537                 const gchar *sender_name,
538                 const gchar *object_path,
539                 const gchar *interface_name,
540                 const gchar *signal_name,
541                 GVariant *parameters,
542                 gpointer user_data)
543 {
544         CAL_FN_CALL();
545
546         int ret = 0;
547         gchar *name = NULL;
548         gchar *old_owner = NULL;
549         gchar *new_owner = NULL;
550
551         g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
552         DBG("name[%s] old_owner[%s] new_owner[%s]", name, old_owner, new_owner);
553
554         if (0 != strlen(new_owner)) {
555                 DBG("new_owner[%s]", new_owner);
556                 return;
557         }
558         g_mutex_lock(&cal_server_dbus_sender);
559         /* empty new_owner means server-kill */
560         cal_sender_s *sender = NULL;
561         ret = _cal_server_dbus_find_sender(old_owner, &sender);
562         if (CALENDAR_ERROR_NONE != ret) {
563                 ERR("_cal_server_dbus_find_sender() Fail(%d)", ret);
564                 g_mutex_unlock(&cal_server_dbus_sender);
565                 return;
566         }
567
568         if (sender) { /* found bus name in our bus list */
569                 DBG("owner[%s] stopped", old_owner);
570                 _delete_sender(sender);
571         }
572         g_mutex_unlock(&cal_server_dbus_sender);
573 }
574
575 static int _cal_server_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
576 {
577         CAL_FN_CALL();
578
579         unsigned int id = 0;
580         id = g_dbus_connection_signal_subscribe(conn,
581                         "org.freedesktop.DBus", /* bus name */
582                         "org.freedesktop.DBus", /* interface */
583                         "NameOwnerChanged", /* member */
584                         "/org/freedesktop/DBus", /* path */
585                         NULL, /* arg0 */
586                         G_DBUS_SIGNAL_FLAGS_NONE,
587                         _cal_server_dbus_name_owner_changed_cb,
588                         NULL,
589                         NULL);
590         if (0 == id) {
591                 ERR("g_dbus_connection_signal_subscribe() Fail");
592                 return CALENDAR_ERROR_IPC;
593         }
594         return CALENDAR_ERROR_NONE;
595 }
596
597 static void _dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
598 {
599         gboolean ret = 0;
600         GError *error = NULL;
601
602         dbus_object = cal_dbus_skeleton_new();
603         if (NULL == dbus_object) {
604                 ERR("cal_dbus_skeleton_new() Fail");
605                 return;
606         }
607
608         g_signal_connect(dbus_object, "handle-register-resource",
609                         G_CALLBACK(_handle_register_resource), NULL);
610         g_signal_connect(dbus_object, "handle-unregister-resource",
611                         G_CALLBACK(_handle_unregister_resource), NULL);
612         g_signal_connect(dbus_object, "handle-insert-record",
613                         G_CALLBACK(_handle_insert_record), NULL);
614         g_signal_connect(dbus_object, "handle-update-record",
615                         G_CALLBACK(_handle_update_record), NULL);
616         g_signal_connect(dbus_object, "handle-delete-record",
617                         G_CALLBACK(_handle_delete_record), NULL);
618         g_signal_connect(dbus_object, "handle-replace-record",
619                         G_CALLBACK(_handle_replace_record), NULL);
620         g_signal_connect(dbus_object, "handle-insert-records",
621                         G_CALLBACK(_handle_insert_records), NULL);
622         g_signal_connect(dbus_object, "handle-update-records",
623                         G_CALLBACK(_handle_update_records), NULL);
624         g_signal_connect(dbus_object, "handle-delete-records",
625                         G_CALLBACK(_handle_delete_records), NULL);
626         g_signal_connect(dbus_object, "handle-replace-records",
627                         G_CALLBACK(_handle_replace_records), NULL);
628         g_signal_connect(dbus_object, "handle-get-record",
629                         G_CALLBACK(_handle_get_record), NULL);
630         g_signal_connect(dbus_object, "handle-get-all-records",
631                         G_CALLBACK(_handle_get_all_records), NULL);
632         g_signal_connect(dbus_object, "handle-get-records-with-query",
633                         G_CALLBACK(_handle_get_records_with_query), NULL);
634         g_signal_connect(dbus_object, "handle-get-count",
635                         G_CALLBACK(_handle_get_count), NULL);
636         g_signal_connect(dbus_object, "handle-get-count-with-query",
637                         G_CALLBACK(_handle_get_count_with_query), NULL);
638         g_signal_connect(dbus_object, "handle-get-current-version",
639                         G_CALLBACK(_handle_get_current_version), NULL);
640         g_signal_connect(dbus_object, "handle-check-permission-write",
641                         G_CALLBACK(_handle_check_permission_write), NULL);
642         g_signal_connect(dbus_object, "handle-check-permission-read",
643                         G_CALLBACK(_handle_check_permission_read), NULL);
644         g_signal_connect(dbus_object, "handle-get-changes-by-version",
645                         G_CALLBACK(_handle_get_changes_by_version), NULL);
646         g_signal_connect(dbus_object, "handle-get-changes-exception-by-version",
647                         G_CALLBACK(_handle_get_changes_exception_by_version), NULL);
648         g_signal_connect(dbus_object, "handle-clean-after-sync",
649                         G_CALLBACK(_handle_clean_after_sync), NULL);
650         g_signal_connect(dbus_object, "handle-insert-vcalendars",
651                         G_CALLBACK(_handle_insert_vcalendars), NULL);
652         g_signal_connect(dbus_object, "handle-replace-vcalendars",
653                         G_CALLBACK(_handle_replace_vcalendars), NULL);
654
655         ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(dbus_object),
656                         conn, CAL_DBUS_OBJPATH, &error);
657         if (FALSE == ret) {
658                 ERR("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
659                 g_error_free(error);
660                 return;
661         }
662
663         ret = _cal_server_dbus_subscribe_name_owner_changed(conn);
664         if (CALENDAR_ERROR_NONE != ret) {
665                 ERR("_cal_server_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
666                 return;
667         }
668 }
669
670 static void _dbus_on_name_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
671 {
672         DBG("Acquired the name %s", name);
673 }
674
675 static void _dbus_on_name_lost(GDBusConnection *conn, const gchar *name, gpointer user_data)
676 {
677         DBG("Lost the name %s", name);
678 }
679
680 unsigned int cal_server_dbus_init(void)
681 {
682         guint id = 0;
683         id = g_bus_own_name(G_BUS_TYPE_SESSION,
684                         CAL_DBUS_INTERFACE,
685                         G_BUS_NAME_OWNER_FLAGS_REPLACE,
686                         _dbus_on_bus_acquired,
687                         _dbus_on_name_acquired,
688                         _dbus_on_name_lost,
689                         NULL,
690                         NULL);
691         if (0 == id) {
692                 ERR("g_bus_own_name() Fail");
693                 return 0;
694         }
695         return id;
696 }
697
698 void cal_server_dbus_deinit(unsigned int id)
699 {
700         g_bus_unown_name(id);
701 }
702
703 int cal_dbus_emit_signal(const char *dest, const char *signal_name, GVariant *value)
704 {
705         CAL_FN_CALL();
706
707         gboolean ret;
708         GError *error = NULL;
709
710         DBG("signal_name[%s]", signal_name);
711         DBG("data[%s]", g_variant_print(value, FALSE));
712
713         calDbusSkeleton *skeleton = NULL;
714         skeleton = CAL_DBUS_SKELETON(cal_dbus_get_object());
715         if (NULL == skeleton) {
716                 ERR("cal_dbus_get_object() Fail");
717                 return CALENDAR_ERROR_IPC;
718         }
719
720         GDBusConnection *conn = NULL;
721         conn = g_dbus_interface_skeleton_get_connection(G_DBUS_INTERFACE_SKELETON(skeleton));
722         if (NULL == conn) {
723                 ERR("g_dbus_interface_skeleton_get_connection() Fail");
724                 return CALENDAR_ERROR_IPC;
725         }
726
727         ret = g_dbus_connection_emit_signal(conn,
728                         dest,
729                         CAL_DBUS_OBJPATH,
730                         CAL_DBUS_INTERFACE,
731                         signal_name,
732                         value,
733                         &error);
734
735         if (FALSE == ret) {
736                 ERR("g_dbus_connection_emit_signal() Fail");
737                 if (error) {
738                         ERR("error[%s]", error->message);
739                         g_error_free(error);
740                 }
741                 return CALENDAR_ERROR_IPC;
742         }
743
744         if (FALSE == g_dbus_connection_flush_sync(conn, NULL, &error)) {
745                 ERR("g_dbus_connection_flush_sync() Fail");
746                 if (error) {
747                         ERR("error[%s]", error->message);
748                         g_error_free(error);
749                 }
750                 return CALENDAR_ERROR_IPC;
751         }
752
753         return CALENDAR_ERROR_NONE;
754 }
755
756 int cal_dbus_publish_reminder(int stream_size, char *stream)
757 {
758         CAL_FN_CALL();
759
760         GVariant *value = NULL;
761         value = cal_dbus_utils_stream_to_gvariant(stream_size, stream);
762         cal_dbus_emit_signal(NULL, CAL_NOTI_REMINDER_CAHNGED, value);
763
764         return CALENDAR_ERROR_NONE;
765 }