4 * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include "cal_internal.h"
25 #include "cal_typedef.h"
26 #include "cal_handle.h"
27 #include "cal_dbus_helper.h"
30 #include "cal_db_util.h"
31 #include "cal_server_dbus.h"
32 #include "cal_utils.h"
33 #include "cal_server_ondemand.h"
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 */
39 typedef struct _cal_sender {
43 calDbus* cal_dbus_get_object(void)
48 static bool _has_sender(const char *name, GList **out_cursor)
50 bool has_sender = false;
53 cursor = cal_sender_list;
55 cal_sender_s *sender = (cal_sender_s *)cursor->data;
57 WARN("sender is NULL");
58 cursor = g_list_next(cursor);
61 if (CAL_STRING_EQUAL == g_strcmp0(sender->name, name)) {
62 DBG("found sender[%s]", name);
68 cursor = g_list_next(cursor);
73 static int _append_sender(const char *name)
75 RETV_IF(NULL == name, CALENDAR_ERROR_INVALID_PARAMETER);
77 cal_sender_s *sender = NULL;
78 sender = calloc(1, sizeof(cal_sender_s));
82 return CALENDAR_ERROR_OUT_OF_MEMORY;
85 sender->name = cal_strdup(name);
86 DBG("[SENDER] Append sender[%s]", sender->name);
87 cal_sender_list = g_list_append(cal_sender_list, sender);
88 return CALENDAR_ERROR_NONE;
91 static gboolean _handle_register_resource(calDbus *object,
92 GDBusMethodInvocation *invocation)
97 const char *sender_name = NULL;
98 sender_name = g_dbus_method_invocation_get_sender(invocation);
100 g_mutex_lock(&cal_server_dbus_sender);
101 if (true == _has_sender(sender_name, NULL)) {
102 /* LCOV_EXCL_START */
103 ERR("Already has sender");
104 g_mutex_unlock(&cal_server_dbus_sender);
108 ret = _append_sender(sender_name);
109 if (CALENDAR_ERROR_NONE != ret) {
110 /* LCOV_EXCL_START */
111 ERR("_append_sender() Fail");
112 g_mutex_unlock(&cal_server_dbus_sender);
116 DBG("append sender");
117 g_mutex_unlock(&cal_server_dbus_sender);
119 cal_dbus_complete_register_resource(object, invocation, ret);
124 static gboolean _handle_unregister_resource(calDbus *object,
125 GDBusMethodInvocation *invocation)
130 const char *sender_name = NULL;
131 sender_name = g_dbus_method_invocation_get_sender(invocation);
133 GList *cursor = NULL;
134 g_mutex_lock(&cal_server_dbus_sender);
135 if (true == _has_sender(sender_name, &cursor)) {
136 DBG("[SENDER] delete sender[%s]", sender_name);
137 cal_sender_s *sender = (cal_sender_s *)cursor->data;
140 cal_sender_list = g_list_delete_link(cal_sender_list, cursor);
143 if (0 == g_list_length(cal_sender_list)) {
144 DBG("sender list is 0");
145 g_list_free_full(cal_sender_list, free);
146 cal_sender_list = NULL;
148 g_mutex_unlock(&cal_server_dbus_sender);
150 cal_dbus_complete_unregister_resource(object, invocation, ret);
155 static gboolean _handle_insert_record(calDbus *object, GDBusMethodInvocation *invocation,
156 GVariant *arg_handle, GVariant *arg_record)
159 calendar_record_h record = NULL;
160 ret = cal_dbus_utils_gvariant_to_record(arg_record, &record);
163 ret = cal_db_insert_record(record, &id);
166 version = cal_db_util_get_transaction_ver();
167 cal_dbus_complete_insert_record(object, invocation, id, version, ret);
168 calendar_record_destroy(record, true);
170 cal_server_ondemand_start();
174 static gboolean _handle_update_record(calDbus *object, GDBusMethodInvocation *invocation,
175 GVariant *arg_handle, GVariant *arg_record)
178 calendar_record_h record = NULL;
179 ret = cal_dbus_utils_gvariant_to_record(arg_record, &record);
181 ret = cal_db_update_record(record);
184 version = cal_db_util_get_transaction_ver();
185 cal_dbus_complete_update_record(object, invocation, version, ret);
186 calendar_record_destroy(record, true);
188 cal_server_ondemand_start();
192 static gboolean _handle_delete_record(calDbus *object, GDBusMethodInvocation *invocation,
193 GVariant *arg_handle, char *view_uri, int id)
196 ret = cal_db_delete_record(view_uri, id);
199 version = cal_db_util_get_transaction_ver();
200 cal_dbus_complete_delete_record(object, invocation, version, ret);
202 cal_server_ondemand_start();
206 static gboolean _handle_replace_record(calDbus *object, GDBusMethodInvocation *invocation,
207 GVariant *arg_handle, GVariant *arg_record, int id)
210 calendar_record_h record = NULL;
211 ret = cal_dbus_utils_gvariant_to_record(arg_record, &record);
213 ret = cal_db_replace_record(record, id);
216 version = cal_db_util_get_transaction_ver();
217 cal_dbus_complete_replace_record(object, invocation, version, ret);
218 calendar_record_destroy(record, true);
220 cal_server_ondemand_start();
224 static gboolean _handle_insert_records(calDbus *object, GDBusMethodInvocation *invocation,
225 GVariant *arg_handle, GVariant *arg_list)
228 calendar_list_h list = NULL;
229 ret = cal_dbus_utils_gvariant_to_list(arg_list, &list);
233 ret = cal_db_insert_records(list, &ids, &count);
234 calendar_list_destroy(list, true);
237 version = cal_db_util_get_transaction_ver();
238 GVariant *arg_ids = cal_dbus_utils_ids_to_gvariant(ids, count);
239 cal_dbus_complete_insert_records(object, invocation, arg_ids, count, version, ret);
242 g_variant_unref(arg_ids);
244 cal_server_ondemand_start();
248 static gboolean _handle_update_records(calDbus *object, GDBusMethodInvocation *invocation,
249 GVariant *arg_handle, GVariant *arg_list)
252 calendar_list_h list = NULL;
253 ret = cal_dbus_utils_gvariant_to_list(arg_list, &list);
255 ret = cal_db_update_records(list);
256 calendar_list_destroy(list, true);
259 version = cal_db_util_get_transaction_ver();
260 cal_dbus_complete_update_records(object, invocation, version, ret);
262 cal_server_ondemand_start();
266 static gboolean _handle_delete_records(calDbus *object, GDBusMethodInvocation *invocation,
267 GVariant *arg_handle, char *view_uri, GVariant *arg_ids, int count)
271 ret = cal_dbus_utils_gvariant_to_ids(arg_ids, count, &ids);
273 ret = cal_db_delete_records(view_uri, ids, count);
276 version = cal_db_util_get_transaction_ver();
277 cal_dbus_complete_delete_records(object, invocation, version, ret);
280 cal_server_ondemand_start();
284 static gboolean _handle_replace_records(calDbus *object, GDBusMethodInvocation *invocation,
285 GVariant *arg_handle, GVariant *arg_list, GVariant *arg_ids, int count)
288 calendar_list_h list = NULL;
290 ret = cal_dbus_utils_gvariant_to_list(arg_list, &list);
291 ret = cal_dbus_utils_gvariant_to_ids(arg_ids, count, &ids);
293 ret = cal_db_replace_records(list, ids, count);
295 calendar_list_destroy(list, true);
298 version = cal_db_util_get_transaction_ver();
299 cal_dbus_complete_replace_records(object, invocation, version, ret);
301 cal_server_ondemand_start();
305 static gboolean _handle_get_record(calDbus *object, GDBusMethodInvocation *invocation,
306 GVariant *arg_handle, char *view_uri, int id)
309 calendar_record_h record = NULL;
310 ret = cal_db_get_record(view_uri, id, &record);
312 GVariant *arg_record = cal_dbus_utils_record_to_gvariant(record);
313 cal_dbus_complete_get_record(object, invocation, arg_record, ret);
314 g_variant_unref(arg_record);
315 calendar_record_destroy(record, true);
317 cal_server_ondemand_start();
321 static gboolean _handle_get_all_records(calDbus *object, GDBusMethodInvocation *invocation,
322 GVariant *arg_handle, char *view_uri, int offset, int limit)
327 calendar_list_h list = NULL;
328 ret = cal_db_get_all_records(view_uri, offset, limit, &list);
330 GVariant *arg_list = cal_dbus_utils_list_to_gvariant(list);
331 cal_dbus_complete_get_all_records(object, invocation, arg_list, ret);
332 calendar_list_destroy(list, true);
333 g_variant_unref(arg_list);
335 cal_server_ondemand_start();
339 static gboolean _handle_get_records_with_query(calDbus *object, GDBusMethodInvocation *invocation,
340 GVariant *arg_handle, GVariant *arg_query, int offset, int limit)
343 calendar_query_h query = NULL;
344 ret = cal_dbus_utils_gvariant_to_query(arg_query, &query);
346 calendar_list_h list = NULL;
347 ret = cal_db_get_records_with_query(query, offset, limit, &list);
349 GVariant *arg_list = cal_dbus_utils_list_to_gvariant(list);
350 cal_dbus_complete_get_records_with_query(object, invocation, arg_list, ret);
351 g_variant_unref(arg_list);
352 calendar_list_destroy(list, true);
354 cal_server_ondemand_start();
358 static gboolean _handle_get_count(calDbus *object, GDBusMethodInvocation *invocation,
359 GVariant *arg_handle, char *view_uri)
363 ret = cal_db_get_count(view_uri, &count);
365 cal_dbus_complete_get_count(object, invocation, count, ret);
367 cal_server_ondemand_start();
371 static gboolean _handle_get_count_with_query(calDbus *object, GDBusMethodInvocation *invocation,
372 GVariant *arg_handle, GVariant *arg_query)
375 calendar_query_h query = NULL;
376 ret = cal_dbus_utils_gvariant_to_query(arg_query, &query);
379 ret = cal_db_get_count_with_query(query, &count);
380 cal_dbus_complete_get_count_with_query(object, invocation, count, ret);
382 cal_server_ondemand_start();
386 static gboolean _handle_get_current_version(calDbus *object, GDBusMethodInvocation *invocation,
387 GVariant *arg_handle)
391 ret = cal_db_get_current_version(&version);
393 cal_dbus_complete_get_current_version(object, invocation, version, ret);
395 cal_server_ondemand_start();
399 static gboolean _handle_check_permission_write(calDbus *object, GDBusMethodInvocation *invocation)
401 cal_dbus_complete_check_permission_write(object, invocation);
402 cal_server_ondemand_start();
406 static gboolean _handle_check_permission_read(calDbus *object, GDBusMethodInvocation *invocation)
408 cal_dbus_complete_check_permission_read(object, invocation);
409 cal_server_ondemand_start();
413 static gboolean _handle_get_changes_by_version(calDbus *object, GDBusMethodInvocation *invocation,
414 GVariant *arg_handle, char *view_uri, int book_id, int in_version)
417 calendar_list_h list = NULL;
419 ret = cal_db_get_changes_by_version(view_uri, book_id, in_version, &list, &out_version);
421 GVariant *arg_list = cal_dbus_utils_list_to_gvariant(list);
422 cal_dbus_complete_get_changes_by_version(object, invocation, arg_list, out_version, ret);
423 calendar_list_destroy(list, true);
424 g_variant_unref(arg_list);
426 cal_server_ondemand_start();
430 static gboolean _handle_get_changes_exception_by_version(calDbus *object,
431 GDBusMethodInvocation *invocation,
432 GVariant *arg_handle,
438 calendar_list_h list = NULL;
439 ret = cal_db_get_changes_exception_by_version(view_uri, original_id, version, &list);
441 GVariant *arg_list = cal_dbus_utils_list_to_gvariant(list);
442 cal_dbus_complete_get_changes_exception_by_version(object, invocation, arg_list, ret);
443 calendar_list_destroy(list, true);
444 g_variant_unref(arg_list);
446 cal_server_ondemand_start();
450 static gboolean _handle_clean_after_sync(calDbus *object, GDBusMethodInvocation *invocation,
451 GVariant *arg_handle, int book_id, int version)
454 ret = cal_db_clean_after_sync(book_id, version);
456 cal_dbus_complete_clean_after_sync(object, invocation, ret);
458 cal_server_ondemand_start();
462 static gboolean _handle_insert_vcalendars(calDbus *object, GDBusMethodInvocation *invocation,
463 GVariant *arg_handle, char *stream)
468 ret = cal_db_insert_vcalendars(stream, &ids, &count);
470 GVariant *arg_ids = cal_dbus_utils_ids_to_gvariant(ids, count);
473 version = cal_db_util_get_transaction_ver();
474 cal_dbus_complete_insert_vcalendars(object, invocation, arg_ids, count, version, ret);
476 g_variant_unref(arg_ids);
478 cal_server_ondemand_start();
482 static gboolean _handle_replace_vcalendars(calDbus *object, GDBusMethodInvocation *invocation,
483 GVariant *arg_handle, char *stream, GVariant *arg_ids, int count)
487 ret = cal_dbus_utils_gvariant_to_ids(arg_ids, count, &ids);
489 ret = cal_db_replace_vcalendars(stream, ids, count);
492 version = cal_db_util_get_transaction_ver();
493 cal_dbus_complete_replace_vcalendars(object, invocation, ret, version);
496 cal_server_ondemand_start();
500 static int _cal_server_dbus_find_sender(const char *owner_name, cal_sender_s **out_sender)
502 GList *cursor = NULL;
504 RETV_IF(NULL == owner_name, CALENDAR_ERROR_INVALID_PARAMETER);
505 RETV_IF(NULL == out_sender, CALENDAR_ERROR_INVALID_PARAMETER);
507 cursor = cal_sender_list;
509 cal_sender_s *sender = (cal_sender_s *)cursor->data;
510 if (NULL == sender) {
511 /* LCOV_EXCL_START */
512 ERR("sender is NULL");
513 return CALENDAR_ERROR_NO_DATA;
517 if (CAL_STRING_EQUAL == g_strcmp0(sender->name, owner_name)) {
518 *out_sender = sender;
521 cursor = g_list_next(cursor);
524 return CALENDAR_ERROR_NONE;
527 static void _delete_sender(cal_sender_s *sender)
529 RET_IF(NULL == sender);
531 GList *cursor = cal_sender_list;
533 if (cursor->data == sender) {
534 DBG("[SENDER] Delete sender[%s]", sender->name);
537 cal_sender_list = g_list_delete_link(cal_sender_list, cursor);
540 cursor = g_list_next(cursor);
544 static void _cal_server_dbus_name_owner_changed_cb(GDBusConnection *connection,
545 const gchar *sender_name,
546 const gchar *object_path,
547 const gchar *interface_name,
548 const gchar *signal_name,
549 GVariant *parameters,
556 gchar *old_owner = NULL;
557 gchar *new_owner = NULL;
559 g_variant_get(parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
560 DBG("name[%s] old_owner[%s] new_owner[%s]", name, old_owner, new_owner);
562 if (0 != strlen(new_owner)) {
563 DBG("new_owner[%s]", new_owner);
566 g_mutex_lock(&cal_server_dbus_sender);
567 /* empty new_owner means server-kill */
568 cal_sender_s *sender = NULL;
569 ret = _cal_server_dbus_find_sender(old_owner, &sender);
570 if (CALENDAR_ERROR_NONE != ret) {
571 /* LCOV_EXCL_START */
572 ERR("_cal_server_dbus_find_sender() Fail(%d)", ret);
573 g_mutex_unlock(&cal_server_dbus_sender);
578 if (sender) { /* found bus name in our bus list */
579 DBG("owner[%s] stopped", old_owner);
580 _delete_sender(sender);
582 g_mutex_unlock(&cal_server_dbus_sender);
585 static int _cal_server_dbus_subscribe_name_owner_changed(GDBusConnection *conn)
590 id = g_dbus_connection_signal_subscribe(conn,
591 "org.freedesktop.DBus", /* bus name */
592 "org.freedesktop.DBus", /* interface */
593 "NameOwnerChanged", /* member */
594 "/org/freedesktop/DBus", /* path */
596 G_DBUS_SIGNAL_FLAGS_NONE,
597 _cal_server_dbus_name_owner_changed_cb,
601 /* LCOV_EXCL_START */
602 ERR("g_dbus_connection_signal_subscribe() Fail");
603 return CALENDAR_ERROR_IPC;
606 return CALENDAR_ERROR_NONE;
609 static void _dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
612 GError *error = NULL;
614 dbus_object = cal_dbus_skeleton_new();
615 if (NULL == dbus_object) {
616 /* LCOV_EXCL_START */
617 ERR("cal_dbus_skeleton_new() Fail");
622 g_signal_connect(dbus_object, "handle-register-resource",
623 G_CALLBACK(_handle_register_resource), NULL);
624 g_signal_connect(dbus_object, "handle-unregister-resource",
625 G_CALLBACK(_handle_unregister_resource), NULL);
626 g_signal_connect(dbus_object, "handle-insert-record",
627 G_CALLBACK(_handle_insert_record), NULL);
628 g_signal_connect(dbus_object, "handle-update-record",
629 G_CALLBACK(_handle_update_record), NULL);
630 g_signal_connect(dbus_object, "handle-delete-record",
631 G_CALLBACK(_handle_delete_record), NULL);
632 g_signal_connect(dbus_object, "handle-replace-record",
633 G_CALLBACK(_handle_replace_record), NULL);
634 g_signal_connect(dbus_object, "handle-insert-records",
635 G_CALLBACK(_handle_insert_records), NULL);
636 g_signal_connect(dbus_object, "handle-update-records",
637 G_CALLBACK(_handle_update_records), NULL);
638 g_signal_connect(dbus_object, "handle-delete-records",
639 G_CALLBACK(_handle_delete_records), NULL);
640 g_signal_connect(dbus_object, "handle-replace-records",
641 G_CALLBACK(_handle_replace_records), NULL);
642 g_signal_connect(dbus_object, "handle-get-record",
643 G_CALLBACK(_handle_get_record), NULL);
644 g_signal_connect(dbus_object, "handle-get-all-records",
645 G_CALLBACK(_handle_get_all_records), NULL);
646 g_signal_connect(dbus_object, "handle-get-records-with-query",
647 G_CALLBACK(_handle_get_records_with_query), NULL);
648 g_signal_connect(dbus_object, "handle-get-count",
649 G_CALLBACK(_handle_get_count), NULL);
650 g_signal_connect(dbus_object, "handle-get-count-with-query",
651 G_CALLBACK(_handle_get_count_with_query), NULL);
652 g_signal_connect(dbus_object, "handle-get-current-version",
653 G_CALLBACK(_handle_get_current_version), NULL);
654 g_signal_connect(dbus_object, "handle-check-permission-write",
655 G_CALLBACK(_handle_check_permission_write), NULL);
656 g_signal_connect(dbus_object, "handle-check-permission-read",
657 G_CALLBACK(_handle_check_permission_read), NULL);
658 g_signal_connect(dbus_object, "handle-get-changes-by-version",
659 G_CALLBACK(_handle_get_changes_by_version), NULL);
660 g_signal_connect(dbus_object, "handle-get-changes-exception-by-version",
661 G_CALLBACK(_handle_get_changes_exception_by_version), NULL);
662 g_signal_connect(dbus_object, "handle-clean-after-sync",
663 G_CALLBACK(_handle_clean_after_sync), NULL);
664 g_signal_connect(dbus_object, "handle-insert-vcalendars",
665 G_CALLBACK(_handle_insert_vcalendars), NULL);
666 g_signal_connect(dbus_object, "handle-replace-vcalendars",
667 G_CALLBACK(_handle_replace_vcalendars), NULL);
669 ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(dbus_object),
670 conn, CAL_DBUS_OBJPATH, &error);
672 /* LCOV_EXCL_START */
673 ERR("g_dbus_interface_skeleton_export() Fail(%s)", error->message);
679 ret = _cal_server_dbus_subscribe_name_owner_changed(conn);
680 if (CALENDAR_ERROR_NONE != ret) {
681 /* LCOV_EXCL_START */
682 ERR("_cal_server_dbus_subscribe_name_owner_changed() Fail(%d)", ret);
688 static void _dbus_on_name_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
690 DBG("Acquired the name %s", name);
693 static void _dbus_on_name_lost(GDBusConnection *conn, const gchar *name, gpointer user_data)
695 DBG("Lost the name %s", name);
698 unsigned int cal_server_dbus_init(void)
701 id = g_bus_own_name(G_BUS_TYPE_SESSION,
703 G_BUS_NAME_OWNER_FLAGS_REPLACE,
704 _dbus_on_bus_acquired,
705 _dbus_on_name_acquired,
710 /* LCOV_EXCL_START */
711 ERR("g_bus_own_name() Fail");
718 void cal_server_dbus_deinit(unsigned int id)
720 g_bus_unown_name(id);
723 int cal_dbus_emit_signal(const char *dest, const char *signal_name, GVariant *value)
728 GError *error = NULL;
730 DBG("signal_name[%s]", signal_name);
731 DBG("data[%s]", g_variant_print(value, FALSE));
733 calDbusSkeleton *skeleton = NULL;
734 skeleton = CAL_DBUS_SKELETON(cal_dbus_get_object());
735 if (NULL == skeleton) {
736 /* LCOV_EXCL_START */
737 ERR("cal_dbus_get_object() Fail");
738 return CALENDAR_ERROR_IPC;
742 GDBusConnection *conn = NULL;
743 conn = g_dbus_interface_skeleton_get_connection(G_DBUS_INTERFACE_SKELETON(skeleton));
745 /* LCOV_EXCL_START */
746 ERR("g_dbus_interface_skeleton_get_connection() Fail");
747 return CALENDAR_ERROR_IPC;
751 ret = g_dbus_connection_emit_signal(conn,
760 /* LCOV_EXCL_START */
761 ERR("g_dbus_connection_emit_signal() Fail");
763 ERR("error[%s]", error->message);
766 return CALENDAR_ERROR_IPC;
770 if (FALSE == g_dbus_connection_flush_sync(conn, NULL, &error)) {
771 /* LCOV_EXCL_START */
772 ERR("g_dbus_connection_flush_sync() Fail");
774 ERR("error[%s]", error->message);
777 return CALENDAR_ERROR_IPC;
781 return CALENDAR_ERROR_NONE;
784 int cal_dbus_publish_reminder(int stream_size, char *stream)
788 GVariant *value = NULL;
789 value = cal_dbus_utils_stream_to_gvariant(stream_size, stream);
790 cal_dbus_emit_signal(NULL, CAL_NOTI_REMINDER_CAHNGED, value);
792 return CALENDAR_ERROR_NONE;