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.
21 #include <notification_setting.h>
22 #include <notification_setting_internal.h>
23 #include <notification_setting_service.h>
24 #include <notification_noti.h>
25 #include <badge_setting.h>
26 #include <badge_setting_service.h>
28 #include <package-manager.h>
29 #include <tzplatform_config.h>
30 #include <pkgmgr-info.h>
34 #include "service_common.h"
35 #include "notification_service.h"
36 #include "badge_service.h"
37 #include "shortcut_service.h"
39 #define DBUS_NAME "org.freedesktop.DBus"
40 #define DBUS_OBJECT_PATH "/org/freedesktop/DBus"
41 #define DBUS_INTERFACE_NAME "org.freedesktop.DBus"
43 #define PROVIDER_BUS_NAME "org.tizen.data_provider_service"
44 #define PROVIDER_OBJECT_PATH "/org/tizen/data_provider_service"
46 static GDBusConnection *_gdbus_conn;
47 static GHashTable *_noti_pkg_privilege_info;
48 static GHashTable *_badge_pkg_privilege_info;
50 uid_t get_sender_uid(const char *sender_name)
52 GDBusMessage *msg = NULL;
53 GDBusMessage *reply = NULL;
58 msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
59 DBUS_INTERFACE_NAME, "GetConnectionUnixUser");
61 LOGE("Failed to alloc new method call");
65 g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
66 reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
67 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
71 LOGE("Failed to get uid [%s]", err->message);
77 body = g_dbus_message_get_body(reply);
78 g_variant_get(body, "(u)", &uid);
84 g_object_unref(reply);
89 pid_t get_sender_pid(const char *sender_name)
91 GDBusMessage *msg = NULL;
92 GDBusMessage *reply = NULL;
97 msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
98 DBUS_INTERFACE_NAME, "GetConnectionUnixProcessID");
100 LOGE("Failed to alloc new method call");
104 g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
105 reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
106 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
110 LOGE("Failed to get uid [%s]", err->message);
116 body = g_dbus_message_get_body(reply);
117 g_variant_get(body, "(u)", &pid);
123 g_object_unref(reply);
128 bool is_existed_busname(const char *sender_name)
130 GDBusMessage *msg = NULL;
131 GDBusMessage *reply = NULL;
134 bool is_existed = false;
136 msg = g_dbus_message_new_method_call(DBUS_NAME, DBUS_OBJECT_PATH,
137 DBUS_INTERFACE_NAME, "NameHasOwner");
139 LOGE("Failed to alloc new method call");
143 g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
144 reply = g_dbus_connection_send_message_with_reply_sync(_gdbus_conn, msg,
145 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
149 LOGE("Failed to get uid [%s]", err->message);
155 body = g_dbus_message_get_body(reply);
156 g_variant_get(body, "(b)", &is_existed);
162 g_object_unref(reply);
167 int send_notify(GVariant *body, char *cmd, GHashTable **monitoring_hash, char *interface_name, uid_t uid)
170 GList *monitoring_list = NULL;
172 char *target_bus_name;
173 int monitoring_count = 0;
174 bool is_existed = false;
176 monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
177 target_list = g_list_first(monitoring_list);
178 for (; target_list != NULL; ) {
180 target_bus_name = target_list->data;
181 target_list = target_list->next;
183 if (g_variant_is_floating(body))
186 if (g_dbus_connection_emit_signal(_gdbus_conn,
188 PROVIDER_OBJECT_PATH,
194 ERR("Emit signal err [%s]", err->message);
197 is_existed = is_existed_busname(target_bus_name);
198 if (is_existed == false)
199 delete_monitoring_list(monitoring_hash, target_bus_name, uid);
200 ERR("Fail, emit signal to [%s]", target_bus_name);
203 DBG("Success, emit signal to [%s]", target_bus_name);
206 DBG("Success, cmd[%s] monitoring count[%d]", cmd, monitoring_count);
207 return SERVICE_COMMON_ERROR_NONE;
210 int send_event_notify_by_busname(GVariant *body, char *cmd, char *busname, char *interface_name)
214 if (g_variant_is_floating(body))
217 if (g_dbus_connection_emit_signal(_gdbus_conn,
219 PROVIDER_OBJECT_PATH,
225 ERR("Emit signal err [%s]",
229 ERR("Failed to emit signal to [%s]", busname);
230 return SERVICE_COMMON_ERROR_IO_ERROR;
232 DBG("Success, Emit signal to [%s] cmd[%s]", busname, cmd);
233 return SERVICE_COMMON_ERROR_NONE;
236 /* register service */
238 static int _monitoring_app_list_compare_cb(gconstpointer a, gconstpointer b)
243 int service_register(GVariant *parameters, GVariant **reply_body, const gchar *sender,
244 GBusNameAppearedCallback name_appeared_handler,
245 GBusNameVanishedCallback name_vanished_handler,
246 GHashTable **monitoring_hash,
249 GList *added_list = NULL;
250 const char *bus_name = sender;
251 monitoring_info_s *m_info = NULL;
252 uid_t request_uid = 0;
253 GList *monitoring_list = NULL;
256 return SERVICE_COMMON_ERROR_IO_ERROR;
258 g_variant_get(parameters, "(i)", &request_uid);
259 if (uid > NORMAL_UID_BASE && uid != request_uid)
260 return SERVICE_COMMON_ERROR_IO_ERROR;
262 DBG("service_register : uid %d , request_uid %d", uid, request_uid);
263 monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid));
264 added_list = g_list_find_custom(monitoring_list, bus_name,
265 (GCompareFunc)_monitoring_app_list_compare_cb);
267 if (added_list == NULL) {
268 DBG("add new sender to list");
269 m_info = (monitoring_info_s *)calloc(1, sizeof(monitoring_info_s));
270 if (m_info == NULL) {
271 ERR("Failed to alloc memory");
272 return SERVICE_COMMON_ERROR_IO_ERROR;
275 m_info->bus_name = strdup(bus_name);
276 m_info->uid = request_uid;
277 m_info->watcher_id = g_bus_watch_name_on_connection(
280 G_BUS_NAME_WATCHER_FLAGS_NONE,
281 name_appeared_handler,
282 name_vanished_handler,
285 if (m_info->watcher_id == 0) {
286 ERR("Fail to watch name [%s]", bus_name);
287 free(m_info->bus_name);
289 return SERVICE_COMMON_ERROR_IO_ERROR;
291 DBG("Watch on [%s] success", bus_name);
293 monitoring_list = g_list_append(monitoring_list, strdup(bus_name));
294 DBG("Success, sender[%s] length[%d]",
295 sender, g_list_length(monitoring_list));
296 if (g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(request_uid)) == NULL)
297 g_hash_table_insert(*monitoring_hash, GUINT_TO_POINTER(request_uid), monitoring_list);
299 ERR("Sender [%s] already exist", sender);
302 *reply_body = g_variant_new("()");
303 if (*reply_body == NULL) {
305 if (m_info->bus_name)
306 free(m_info->bus_name);
309 monitoring_list = g_list_remove(monitoring_list, bus_name);
310 ERR("Failed to make reply");
311 return SERVICE_COMMON_ERROR_OUT_OF_MEMORY;
313 return SERVICE_COMMON_ERROR_NONE;
316 int delete_monitoring_list(GHashTable **monitoring_hash, const char *sender, uid_t uid)
318 GList *monitoring_list = NULL;
319 GList *del_list = NULL;
322 monitoring_list = (GList *)g_hash_table_lookup(*monitoring_hash, GUINT_TO_POINTER(uid));
323 if (monitoring_list == NULL) {
324 ERR("No uid[%d] in monitoring hash", uid);
325 return SERVICE_COMMON_ERROR_IO_ERROR;
328 monitoring_list = g_list_first(monitoring_list);
329 del_list = g_list_find_custom(monitoring_list, sender,
330 (GCompareFunc)_monitoring_app_list_compare_cb);
333 DBG("Find delete list - uid[%d] sender[%s]", uid, sender);
334 bus_name = g_list_nth_data(del_list, 0);
337 monitoring_list = g_list_delete_link(monitoring_list, del_list);
339 if (monitoring_list == NULL) {
340 g_hash_table_steal(*monitoring_hash, GUINT_TO_POINTER(uid));
342 monitoring_list = g_list_first(monitoring_list);
343 g_hash_table_replace(*monitoring_hash, GUINT_TO_POINTER(uid), monitoring_list);
346 return SERVICE_COMMON_ERROR_NONE;
349 static int _dbus_init(void)
351 GError *error = NULL;
353 if (_gdbus_conn == NULL) {
354 _gdbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
355 if (_gdbus_conn == NULL) {
357 ERR("Failed to get dbus [%s]", error->message);
360 return SERVICE_COMMON_ERROR_IO_ERROR;
364 return SERVICE_COMMON_ERROR_NONE;
367 int service_common_register_dbus_interface(char *introspection_xml, GDBusInterfaceVTable interface_vtable)
370 int owner_id, noti_registration_id;
371 GError *error = NULL;
372 GDBusNodeInfo *introspection_data = NULL;
374 result = _dbus_init();
375 if (result != SERVICE_COMMON_ERROR_NONE) {
376 ERR("Can't init dbus [%d]", result);
377 result = SERVICE_COMMON_ERROR_IO_ERROR;
381 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
383 G_BUS_NAME_OWNER_FLAGS_NONE,
389 ERR("Failed to own name");
390 result = SERVICE_COMMON_ERROR_IO_ERROR;
394 DBG("Acquiring the own name [%d]", owner_id);
395 introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
396 if (!introspection_data) {
397 ERR("g_dbus_node_info_new_for_xml is failed.");
398 result = SERVICE_COMMON_ERROR_IO_ERROR;
400 ERR("g_dbus_node_info_new_for_xml err [%s]", error->message);
406 noti_registration_id = g_dbus_connection_register_object(_gdbus_conn,
407 PROVIDER_OBJECT_PATH, introspection_data->interfaces[0],
408 &interface_vtable, NULL, NULL, NULL);
410 DBG("registration id[%d]", noti_registration_id);
411 if (noti_registration_id == 0) {
412 ERR("Failed to g_dbus_connection_register_object");
413 result = SERVICE_COMMON_ERROR_IO_ERROR;
418 if (introspection_data)
419 g_dbus_node_info_unref(introspection_data);
424 static int _package_install_cb(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data)
430 if (status != PKGMGR_STATUS_END)
433 if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
434 uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
436 if (g_hash_table_contains(_noti_pkg_privilege_info, pkgname)) {
437 tmp = g_hash_table_lookup(_noti_pkg_privilege_info, pkgname);
438 privilege_info = GPOINTER_TO_UINT(tmp);
439 if (privilege_info == 1)
440 notification_setting_db_update_pkg_disabled(pkgname, false, uid);
442 g_hash_table_remove(_noti_pkg_privilege_info, pkgname);
444 /* In consideration of the reboot status, change the disable information. */
445 ret = notification_setting_db_update_pkg_disabled(pkgname, false, uid);
446 if (ret != NOTIFICATION_ERROR_NONE)
447 notification_setting_insert_package_for_uid(pkgname, uid);
450 if (g_hash_table_contains(_badge_pkg_privilege_info, pkgname)) {
451 tmp = g_hash_table_lookup(_badge_pkg_privilege_info, pkgname);
452 privilege_info = GPOINTER_TO_UINT(tmp);
453 if (privilege_info == 1)
454 badge_db_update_pkg_disabled(pkgname, false, uid);
456 g_hash_table_remove(_badge_pkg_privilege_info, pkgname);
458 /* In consideration of the reboot status, change the disable information. */
459 ret = badge_db_update_pkg_disabled(pkgname, false, uid);
460 if (ret != BADGE_ERROR_NONE)
461 badge_setting_insert_package_for_uid(pkgname, uid);
467 static int _package_uninstall_cb(uid_t uid, const char *pkgname, enum pkgmgr_status status, double value, void *data)
470 pkgmgrinfo_pkginfo_h pkginfo;
472 if (status != PKGMGR_STATUS_END)
475 if (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER))
476 uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
478 ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(pkgname, uid, &pkginfo);
479 if (ret == PMINFO_R_OK) {
480 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo);
482 if (_noti_pkg_privilege_info == NULL) {
483 _noti_pkg_privilege_info = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
484 _badge_pkg_privilege_info = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
487 ret = notification_setting_db_update_pkg_disabled(pkgname, true, uid);
488 if (ret == NOTIFICATION_ERROR_NONE)
489 g_hash_table_insert(_noti_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(1));
491 g_hash_table_insert(_noti_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(0));
493 ret = badge_db_update_pkg_disabled(pkgname, true, uid);
494 if (ret == BADGE_ERROR_NONE)
495 g_hash_table_insert(_badge_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(1));
497 g_hash_table_insert(_badge_pkg_privilege_info, strdup(pkgname), GUINT_TO_POINTER(0));
499 notification_setting_delete_package_for_uid(pkgname, uid);
500 badge_db_delete_by_pkgname(pkgname, uid);
501 badge_setting_delete_package_for_uid(pkgname, uid);
502 notification_noti_delete_template(pkgname);
508 static int _app_enabled_cb(uid_t uid, const char *app_id, enum pkgmgr_status status, double value, void *data)
510 if (status == PKGMGR_STATUS_END)
511 notification_setting_db_update_app_disabled(app_id, false, uid);
516 static int _app_disabled_cb(uid_t uid, const char *app_id, enum pkgmgr_status status, double value, void *data)
518 if (status == PKGMGR_STATUS_END) {
519 notification_delete_noti_by_app_id(app_id, uid);
520 notification_setting_db_update_app_disabled(app_id, true, uid);
526 void service_common_init(void)
529 pkgmgr_add_event_callback(PKGMGR_EVENT_INSTALL, _package_install_cb, NULL);
530 pkgmgr_add_event_callback(PKGMGR_EVENT_UPDATE, _package_install_cb, NULL);
531 pkgmgr_add_event_callback(PKGMGR_EVENT_UNINSTALL, _package_uninstall_cb, NULL);
532 pkgmgr_add_event_callback(PKGMGR_EVENT_APP_ENABLE, _app_enabled_cb, NULL);
533 pkgmgr_add_event_callback(PKGMGR_EVENT_APP_DISABLE, _app_disabled_cb, NULL);