2 * Copyright 2016 Samsung Electronics Co., Ltd
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <sys/smack.h>
22 #include <badge_setting_service.h>
23 #include <badge_internal.h>
24 #include <tzplatform_config.h>
26 #include "service_common.h"
27 #include "badge_service.h"
30 #define PROVIDER_BADGE_INTERFACE_NAME "org.tizen.data_provider_badge_service"
31 static GHashTable *_monitoring_hash = NULL;
33 static void _on_name_appeared(GDBusConnection *connection,
35 const gchar *name_owner,
38 DbgPrint("name appeared : %s", name);
41 static void _on_name_vanished(GDBusConnection *connection,
45 DbgPrint("name vanished : %s", name);
46 monitoring_info_s *info = (monitoring_info_s *)user_data;
48 DbgPrint("name vanished uid : %d", info->uid);
49 g_bus_unwatch_name(info->watcher_id);
53 static void _badge_dbus_method_call_handler(GDBusConnection *conn,
54 const gchar *sender, const gchar *object_path,
55 const gchar *iface_name, const gchar *method_name,
56 GVariant *parameters, GDBusMethodInvocation *invocation,
59 DbgPrint("badge method_name: %s", method_name);
61 GVariant *reply_body = NULL;
62 int ret = BADGE_ERROR_INVALID_PARAMETER;
63 uid_t uid = get_sender_uid(sender);
65 if (g_strcmp0(method_name, "badge_service_register") == 0)
66 ret = service_register(parameters, &reply_body, sender,
67 _on_name_appeared, _on_name_vanished, &_monitoring_hash, uid);
68 else if (g_strcmp0(method_name, "get_badge_existing") == 0)
69 ret = badge_get_badge_existing(parameters, &reply_body, uid);
70 else if (g_strcmp0(method_name, "get_list") == 0)
71 ret = badge_get_badge_list(parameters, &reply_body, uid);
72 else if (g_strcmp0(method_name, "insert_badge") == 0)
73 ret = badge_insert(parameters, &reply_body, uid);
74 else if (g_strcmp0(method_name, "delete_badge") == 0)
75 ret = badge_delete(parameters, &reply_body, uid);
76 else if (g_strcmp0(method_name, "set_badge_count") == 0)
77 ret = badge_set_badge_count(parameters, &reply_body, uid);
78 else if (g_strcmp0(method_name, "get_badge_count") == 0)
79 ret = badge_get_badge_count(parameters, &reply_body, uid);
80 else if (g_strcmp0(method_name, "set_disp_option") == 0)
81 ret = badge_set_display_option(parameters, &reply_body, uid);
82 else if (g_strcmp0(method_name, "get_disp_option") == 0)
83 ret = badge_get_display_option(parameters, &reply_body, uid);
84 else if (g_strcmp0(method_name, "set_noti_property") == 0)
85 ret = badge_set_setting_property(parameters, &reply_body, uid);
86 else if (g_strcmp0(method_name, "get_noti_property") == 0)
87 ret = badge_get_setting_property(parameters, &reply_body, uid);
89 if (ret == BADGE_ERROR_NONE) {
90 DbgPrint("badge service success : %d", ret);
91 g_dbus_method_invocation_return_value(
92 invocation, reply_body);
94 DbgPrint("badge service fail : %d", ret);
95 g_dbus_method_invocation_return_error(
99 "badge service error");
103 static const GDBusInterfaceVTable _badge_interface_vtable = {
104 _badge_dbus_method_call_handler,
109 int badge_register_dbus_interface()
111 static gchar introspection_xml[] =
113 " <interface name='org.tizen.data_provider_badge_service'>"
114 " <method name='badge_service_register'>"
115 " <arg type='i' name='uid' direction='in'/>"
117 " <method name='get_badge_existing'>"
118 " <arg type='s' name='pkgname' direction='in'/>"
119 " <arg type='i' name='uid' direction='in'/>"
120 " <arg type='i' name='exist' direction='out'/>"
122 " <method name='get_list'>"
123 " <arg type='i' name='uid' direction='in'/>"
124 " <arg type='a(v)' name='badge_list' direction='out'/>"
126 " <method name='insert_badge'>"
127 " <arg type='s' name='pkgname' direction='in'/>"
128 " <arg type='s' name='writable_pkg' direction='in'/>"
129 " <arg type='s' name='caller' direction='in'/>"
130 " <arg type='i' name='uid' direction='in'/>"
133 " <method name='delete_badge'>"
134 " <arg type='s' name='pkgname' direction='in'/>"
135 " <arg type='s' name='caller' direction='in'/>"
136 " <arg type='i' name='uid' direction='in'/>"
139 " <method name='set_badge_count'>"
140 " <arg type='s' name='pkgname' direction='in'/>"
141 " <arg type='s' name='caller' direction='in'/>"
142 " <arg type='i' name='count' direction='in'/>"
143 " <arg type='i' name='uid' direction='in'/>"
146 " <method name='get_badge_count'>"
147 " <arg type='s' name='pkgname' direction='in'/>"
148 " <arg type='i' name='uid' direction='in'/>"
149 " <arg type='i' name='count' direction='out'/>"
152 " <method name='set_disp_option'>"
153 " <arg type='s' name='pkgname' direction='in'/>"
154 " <arg type='s' name='caller' direction='in'/>"
155 " <arg type='i' name='is_display' direction='in'/>"
156 " <arg type='i' name='uid' direction='in'/>"
159 " <method name='get_disp_option'>"
160 " <arg type='s' name='pkgname' direction='in'/>"
161 " <arg type='i' name='uid' direction='in'/>"
162 " <arg type='i' name='is_display' direction='out'/>"
165 " <method name='set_noti_property'>"
166 " <arg type='s' name='pkgname' direction='in'/>"
167 " <arg type='s' name='property' direction='in'/>"
168 " <arg type='s' name='value' direction='in'/>"
169 " <arg type='i' name='uid' direction='in'/>"
172 " <method name='get_noti_property'>"
173 " <arg type='s' name='pkgname' direction='in'/>"
174 " <arg type='s' name='property' direction='in'/>"
175 " <arg type='i' name='uid' direction='in'/>"
176 " <arg type='s' name='value' direction='out'/>"
181 return service_common_register_dbus_interface(introspection_xml, _badge_interface_vtable);
184 static int _validate_and_set_param_uid_with_uid(uid_t uid, uid_t *param_uid)
186 int ret = BADGE_ERROR_NONE;
188 if (uid > NORMAL_UID_BASE && uid != *param_uid) {
189 ErrPrint("invalid sender uid : %d, param_uid : %d", uid, *param_uid);
190 return BADGE_ERROR_INVALID_PARAMETER;
191 } else if (uid <= NORMAL_UID_BASE) {
192 if (*param_uid <= NORMAL_UID_BASE) {
193 if (*param_uid != uid)
194 return BADGE_ERROR_INVALID_PARAMETER;
195 *param_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
201 static void _release_badge_info(gpointer data)
203 badge_info_s *badge = (badge_info_s *)data;
211 /* get_badge_existing */
212 int badge_get_badge_existing(GVariant *parameters, GVariant **reply_body, uid_t uid)
214 int ret = BADGE_ERROR_NONE;
215 char *pkgname = NULL;
219 g_variant_get(parameters, "(&si)", &pkgname, ¶m_uid);
220 DbgPrint("badge_get_badge_existing %s", pkgname);
222 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
223 if (ret != BADGE_ERROR_NONE)
227 ret = badge_db_is_existing(pkgname, &existing, param_uid);
229 return BADGE_ERROR_INVALID_PARAMETER;
231 if (ret != BADGE_ERROR_NONE) {
232 ErrPrint("failed to get badge existing :%d\n", ret);
236 *reply_body = g_variant_new("(i)", existing);
237 if (*reply_body == NULL) {
238 ErrPrint("cannot make gvariant to noti");
239 return BADGE_ERROR_OUT_OF_MEMORY;
241 DbgPrint("badge_get_badge_existing service done");
246 int badge_get_badge_list(GVariant *parameters, GVariant **reply_body, uid_t uid)
248 GList *badge_list = NULL;
249 GList *iter_list = NULL;
250 GVariant *body = NULL;
252 GVariantBuilder *builder;
256 g_variant_get(parameters, "(i)", ¶m_uid);
258 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
259 if (ret != BADGE_ERROR_NONE)
262 ret = badge_db_get_list(&badge_list, param_uid);
263 if (ret != BADGE_ERROR_NONE) {
264 ErrPrint("badge get list fail : %d", ret);
268 builder = g_variant_builder_new(G_VARIANT_TYPE("a(v)"));
269 iter_list = g_list_first(badge_list);
270 for (; iter_list != NULL; iter_list = iter_list->next) {
271 badge = iter_list->data;
272 body = g_variant_new("(si)", badge->pkg, badge->badge_count);
273 g_variant_builder_add(builder, "(v)", body);
275 g_list_free_full(badge_list, (GDestroyNotify)_release_badge_info);
277 *reply_body = g_variant_new("(a(v))", builder);
278 g_variant_builder_unref(builder);
280 if (*reply_body == NULL) {
281 ErrPrint("cannot make reply_body");
282 return BADGE_ERROR_OUT_OF_MEMORY;
285 DbgPrint("badge_get_badge_list done !!");
286 return BADGE_ERROR_NONE;
290 int badge_insert(GVariant *parameters, GVariant **reply_body, uid_t uid)
292 int ret = BADGE_ERROR_NONE;
293 char *pkgname = NULL;
294 char *writable_pkg = NULL;
296 GVariant *body = NULL;
297 GList *monitoring_list = NULL;
300 g_variant_get(parameters, "(&s&s&si)", &pkgname, &writable_pkg, &caller, ¶m_uid);
302 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
303 if (ret != BADGE_ERROR_NONE)
306 if (pkgname != NULL && writable_pkg != NULL && caller != NULL)
307 ret = badge_db_insert(pkgname, writable_pkg, caller, param_uid);
309 return BADGE_ERROR_INVALID_PARAMETER;
311 if (ret != BADGE_ERROR_NONE) {
312 ErrPrint("failed to insert badge :%d\n", ret);
316 body = g_variant_new("(si)", pkgname, param_uid);
318 ErrPrint("cannot make gvariant to noti");
319 return BADGE_ERROR_OUT_OF_MEMORY;
322 monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
323 ret = send_notify(body, "insert_badge_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
324 g_variant_unref(body);
326 if (ret != BADGE_ERROR_NONE) {
327 ErrPrint("failed to send notify:%d\n", ret);
331 *reply_body = g_variant_new("()");
332 if (*reply_body == NULL) {
333 ErrPrint("cannot make gvariant to noti");
334 return BADGE_ERROR_OUT_OF_MEMORY;
341 int badge_delete(GVariant *parameters, GVariant **reply_body, uid_t uid)
343 int ret = BADGE_ERROR_NONE;
344 char *pkgname = NULL;
346 GVariant *body = NULL;
347 GList *monitoring_list = NULL;
350 g_variant_get(parameters, "(&s&si)", &pkgname, &caller, ¶m_uid);
352 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
353 if (ret != BADGE_ERROR_NONE)
356 if (pkgname != NULL && caller != NULL) {
357 ret = badge_db_delete(pkgname, caller, param_uid);
359 return BADGE_ERROR_INVALID_PARAMETER;
362 if (ret != BADGE_ERROR_NONE) {
363 ErrPrint("failed to delete badge :%d\n", ret);
367 body = g_variant_new("(si)", pkgname, param_uid);
369 ErrPrint("cannot make gvariant to noti");
370 return BADGE_ERROR_OUT_OF_MEMORY;
373 monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
374 ret = send_notify(body, "delete_badge_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
375 g_variant_unref(body);
377 if (ret != BADGE_ERROR_NONE) {
378 ErrPrint("failed to send notify:%d\n", ret);
382 *reply_body = g_variant_new("()");
383 if (*reply_body == NULL) {
384 ErrPrint("cannot make gvariant to noti");
385 return BADGE_ERROR_OUT_OF_MEMORY;
390 /* set_badge_count */
391 int badge_set_badge_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
393 int ret = BADGE_ERROR_NONE;
394 char *pkgname = NULL;
396 unsigned int count = 0;
397 GVariant *body = NULL;
398 GList *monitoring_list = NULL;
401 g_variant_get(parameters, "(&s&sii)", &pkgname, &caller, &count, ¶m_uid);
403 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
404 if (ret != BADGE_ERROR_NONE)
407 if (pkgname != NULL && caller != NULL)
408 ret = badge_db_set_count(pkgname, caller, count, param_uid);
410 return BADGE_ERROR_INVALID_PARAMETER;
412 if (ret != BADGE_ERROR_NONE) {
413 ErrPrint("failed to set badge :%d\n", ret);
417 body = g_variant_new("(sii)", pkgname, count, param_uid);
419 ErrPrint("cannot make gvariant to noti");
420 return BADGE_ERROR_OUT_OF_MEMORY;
423 monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
424 ret = send_notify(body, "set_badge_count_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
425 g_variant_unref(body);
427 if (ret != BADGE_ERROR_NONE) {
428 ErrPrint("failed to send notify:%d\n", ret);
431 DbgPrint("send badge count notify done ret : %d", ret);
433 *reply_body = g_variant_new("()");
434 if (*reply_body == NULL) {
435 ErrPrint("cannot make gvariant to noti");
436 return BADGE_ERROR_OUT_OF_MEMORY;
441 /* get_badge_count */
442 int badge_get_badge_count(GVariant *parameters, GVariant **reply_body, uid_t uid)
444 int ret = BADGE_ERROR_NONE;
445 char *pkgname = NULL;
446 unsigned int count = 0;
449 g_variant_get(parameters, "(&si)", &pkgname, ¶m_uid);
451 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
452 if (ret != BADGE_ERROR_NONE)
456 ret = badge_db_get_count(pkgname, &count, param_uid);
458 return BADGE_ERROR_INVALID_PARAMETER;
460 if (ret != BADGE_ERROR_NONE) {
461 ErrPrint("failed to get badge count :%d\n", ret);
465 *reply_body = g_variant_new("(i)", count);
466 if (*reply_body == NULL) {
467 ErrPrint("cannot make gvariant to noti");
468 return BADGE_ERROR_OUT_OF_MEMORY;
470 DbgPrint("badge_get_badge_count service done");
474 /* set_disp_option */
475 int badge_set_display_option(GVariant *parameters, GVariant **reply_body, uid_t uid)
477 int ret = BADGE_ERROR_NONE;
478 char *pkgname = NULL;
480 unsigned int is_display = 0;
481 GVariant *body = NULL;
482 GList *monitoring_list = NULL;
485 g_variant_get(parameters, "(&s&sii)", &pkgname, &caller, &is_display, ¶m_uid);
487 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
488 if (ret != BADGE_ERROR_NONE)
491 DbgPrint("set disp option : %s, %s, %d", pkgname, caller, is_display);
493 if (pkgname != NULL && caller != NULL)
494 ret = badge_db_set_display_option(pkgname, is_display, param_uid);
496 return BADGE_ERROR_INVALID_PARAMETER;
498 if (ret != BADGE_ERROR_NONE) {
499 ErrPrint("failed to set display option :%d\n", ret);
503 body = g_variant_new("(sii)", pkgname, is_display, param_uid);
505 ErrPrint("cannot make gvariant to noti");
506 return BADGE_ERROR_OUT_OF_MEMORY;
509 monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
510 ret = send_notify(body, "set_disp_option_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
511 g_variant_unref(body);
513 if (ret != BADGE_ERROR_NONE) {
514 ErrPrint("failed to send notify:%d\n", ret);
518 *reply_body = g_variant_new("()");
519 if (*reply_body == NULL) {
520 ErrPrint("cannot make gvariant to noti");
521 return BADGE_ERROR_OUT_OF_MEMORY;
523 DbgPrint("set disp option done %d", ret);
527 /* get_disp_option */
528 int badge_get_display_option(GVariant *parameters, GVariant **reply_body, uid_t uid)
530 int ret = BADGE_ERROR_NONE;
531 char *pkgname = NULL;
532 unsigned int is_display = 0;
535 g_variant_get(parameters, "(&si)", &pkgname, ¶m_uid);
537 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
538 if (ret != BADGE_ERROR_NONE)
541 DbgPrint("get disp option : %s", pkgname);
544 ret = badge_db_get_display_option(pkgname, &is_display, param_uid);
546 return BADGE_ERROR_INVALID_PARAMETER;
548 if (ret != BADGE_ERROR_NONE) {
549 ErrPrint("failed to get display option :%d\n", ret);
553 *reply_body = g_variant_new("(i)", is_display);
554 if (*reply_body == NULL) {
555 ErrPrint("cannot make gvariant to noti");
556 return BADGE_ERROR_OUT_OF_MEMORY;
561 /* set_noti_property */
562 int badge_set_setting_property(GVariant *parameters, GVariant **reply_body, uid_t uid)
566 char *pkgname = NULL;
567 char *property = NULL;
569 GVariant *body = NULL;
570 GList *monitoring_list = NULL;
573 g_variant_get(parameters, "(&s&s&si)", &pkgname, &property, &value, ¶m_uid);
575 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
576 if (ret != BADGE_ERROR_NONE)
579 if (pkgname != NULL && property != NULL && value != NULL)
580 ret = badge_setting_db_set(pkgname, property, value, param_uid);
582 return BADGE_ERROR_INVALID_PARAMETER;
584 if (ret != BADGE_ERROR_NONE) {
585 ErrPrint("failed to setting db set :%d\n", ret);
589 if (ret == BADGE_ERROR_NONE) {
590 if (strcmp(property, "OPT_BADGE") == 0) {
591 if (strcmp(value, "ON") == 0)
596 body = g_variant_new("(si)", pkgname, is_display);
598 ErrPrint("cannot make gvariant to noti");
599 return BADGE_ERROR_OUT_OF_MEMORY;
602 monitoring_list = (GList *)g_hash_table_lookup(_monitoring_hash, GUINT_TO_POINTER(param_uid));
603 ret = send_notify(body, "set_disp_option_notify", monitoring_list, PROVIDER_BADGE_INTERFACE_NAME);
604 g_variant_unref(body);
605 if (ret != BADGE_ERROR_NONE) {
606 ErrPrint("failed to send notify:%d\n", ret);
611 ErrPrint("failed to set noti property:%d\n", ret);
614 *reply_body = g_variant_new("()");
615 if (*reply_body == NULL) {
616 ErrPrint("cannot make gvariant to noti");
617 return BADGE_ERROR_OUT_OF_MEMORY;
622 /* get_noti_property */
623 int badge_get_setting_property(GVariant *parameters, GVariant **reply_body, uid_t uid)
626 char *pkgname = NULL;
627 char *property = NULL;
631 g_variant_get(parameters, "(&s&si)", &pkgname, &property, ¶m_uid);
633 ret = _validate_and_set_param_uid_with_uid(uid, ¶m_uid);
634 if (ret != BADGE_ERROR_NONE)
637 if (pkgname != NULL && property != NULL)
638 ret = badge_setting_db_get(pkgname, property, &value, param_uid);
640 return BADGE_ERROR_INVALID_PARAMETER;
642 if (ret != BADGE_ERROR_NONE) {
643 ErrPrint("failed to setting db get :%d\n", ret);
647 *reply_body = g_variant_new("(s)", value);
648 if (*reply_body == NULL) {
649 ErrPrint("cannot make gvariant to noti");
650 return BADGE_ERROR_OUT_OF_MEMORY;
657 * Do not try to do anyother operation in these functions
659 HAPI int badge_service_init(void)
663 _monitoring_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_monitoring_list);
664 result = badge_db_init();
665 if (result != BADGE_ERROR_NONE) {
666 ErrPrint("badge db init fail %d", result);
670 result = badge_register_dbus_interface();
671 if (result != SERVICE_COMMON_ERROR_NONE) {
672 ErrPrint("badge register dbus fail %d", result);
673 return BADGE_ERROR_IO_ERROR;
676 return BADGE_ERROR_NONE;
679 HAPI int badge_service_fini(void)
681 return BADGE_ERROR_NONE;