guint watcher_id;
} event_sender_info_s;
+static GList *__dnd_app_list;
+
+typedef struct _dnd_app_info {
+ pid_t pid;
+ char *busname;
+ guint watcher_id;
+} dnd_app_info_s;
+
+typedef struct _disturb_noti_info {
+ int priv_id;
+ notification_op_type_e status;
+} disturb_noti_info_s;
+
+static GList *__disturb_noti_list;
+
static int _update_noti(GVariant **reply_body, notification_h noti, uid_t uid);
static int _delete_noti(const char *app_id, int priv_id, uid_t uid);
+static bool _is_dnd_app_exist();
+static void __delete_dnd_app_info(pid_t pid);
+static dnd_app_info_s *__find_dnd_app_info_by_pid(pid_t pid);
+
/*!
* SERVICE HANDLER
*/
ret = notification_reset_event_receiver(parameters, &reply_body, sender);
} else if (g_strcmp0(method_name, "del_noti_by_display_applist") == 0) {
ret = notification_del_noti_by_display_applist(parameters, &reply_body, uid);
+ } else if (g_strcmp0(method_name, "register_dnd_app") == 0) {
+ ret = notification_register_dnd_app(parameters, &reply_body, sender, pid, uid);
}
if (ret == NOTIFICATION_ERROR_NONE) {
" <method name='post_toast'>"
" </method>"
+
+ " <method name='register_dnd_app'>"
+ " <arg type='i' name='pid' direction='in'/>"
+ " <arg type='i' name='uid' direction='in'/>"
+ " </method>"
" </interface>"
" </node>";
return ret;
}
+/* for dnd app */
+static gint __disturb_noti_compare(gconstpointer a, gconstpointer b)
+{
+ disturb_noti_info_s *info = NULL;
+
+ if (!a)
+ return -1;
+
+ info = (disturb_noti_info_s *)a;
+
+ if (info->priv_id == GPOINTER_TO_INT(b))
+ return 0;
+
+ return 1;
+}
+
+static void __delete_disturb_noti_info(int priv_id)
+{
+ disturb_noti_info_s *info;
+ GList *delete_list = NULL;
+
+ WARN("delete disturb noti info : %d", priv_id);
+
+ if (__disturb_noti_list != NULL) {
+ __disturb_noti_list = g_list_first(__disturb_noti_list);
+ delete_list = g_list_find_custom(__disturb_noti_list, GINT_TO_POINTER(priv_id),
+ (GCompareFunc)__disturb_noti_compare);
+ if (delete_list != NULL) {
+ info = (disturb_noti_info_s *)delete_list->data;
+
+ WARN("delete from disturb list id : %d, status : %d", info->priv_id, info->status);
+
+ __disturb_noti_list = g_list_remove(g_list_first(__disturb_noti_list), info);
+ free(info);
+ }
+ WARN("disturb noti info deleted, len : %d", g_list_length(__disturb_noti_list));
+ }
+}
+
+static void __add_disturb_noti_info(int priv_id, int status)
+{
+ disturb_noti_info_s *noti_info;
+
+ WARN("add disturb noti list, id : %d, status : %d", priv_id, status);
+
+ noti_info = (disturb_noti_info_s *)malloc(sizeof(disturb_noti_info_s));
+ if (noti_info == NULL) {
+ ERR("malloc failed");
+ return;
+ }
+
+ noti_info->priv_id = priv_id;
+ noti_info->status = status;
+
+ if (status == NOTIFICATION_OP_UPDATE)
+ __delete_disturb_noti_info(priv_id);
+
+ __disturb_noti_list = g_list_append(__disturb_noti_list, noti_info);
+}
+
+void _aul_app_dead_event_cb_v2(int pid, int status, void* user_data)
+{
+ int ret;
+ dnd_app_info_s *info;
+ disturb_noti_info_s *noti_info;
+ int latest_priv_id = NOTIFICATION_PRIV_ID_NONE;
+ int latest_status = NOTIFICATION_OP_NONE;
+
+ WARN("add dead, pid : %d, status : %d", pid, status);
+
+ info = __find_dnd_app_info_by_pid(pid);
+ if (info == NULL || info->busname == NULL) {
+ WARN("not dnd app");
+ return;
+ }
+
+ __delete_dnd_app_info(pid);
+
+ if (__disturb_noti_list != NULL && g_list_length(__disturb_noti_list) > 0) {
+ noti_info = (disturb_noti_info_s *)g_list_last(__disturb_noti_list)->data;
+ latest_priv_id = noti_info->priv_id;
+ latest_status = noti_info->status;
+ }
+
+ if (!_is_dnd_app_exist() && latest_priv_id > NOTIFICATION_PRIV_ID_NONE) {
+ /* uid not used*/
+ WARN("launch viewer");
+ ret = notification_launch_default_viewer(latest_priv_id, latest_status, 0);
+ if (ret != NOTIFICATION_ERROR_NONE)
+ ERR("@Failed to launch default viewer from dead callback [%d]", ret);
+
+ g_list_free_full(__disturb_noti_list, free);
+ __disturb_noti_list = NULL;
+ } else {
+ WARN("viewer not launched");
+ }
+}
+
+int _notification_launch_viewer(notification_h noti, int priv_id,
+ notification_op_type_e status, uid_t uid)
+{
+ int ret;
+ bool pairing = false;
+ GVariant *body = NULL;
+ dnd_app_info_s *info = NULL;
+
+ WARN("launch noti viewer : [%d]", priv_id);
+
+ if (_is_dnd_app_exist()) {
+ WARN("dnd app exist, viewer does not launch");
+
+ if (status == NOTIFICATION_OP_INSERT || status == NOTIFICATION_OP_UPDATE)
+ __add_disturb_noti_info(priv_id, status);
+
+ /* pairing */
+ if (noti == NULL) {
+ ERR("notification not exist");
+ return NOTIFICATION_ERROR_INVALID_PARAMETER;
+ }
+
+ ret = notification_get_pairing_type(noti, &pairing);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ERR("Failed to get pairing : %d", ret);
+ return ret;
+ }
+
+ if (pairing) {
+ WARN("dnd app exist, pairing type. exit dnd apps");
+ /* call all disturb callback */
+ __dnd_app_list = g_list_first(__dnd_app_list);
+ for (GList *iter = __dnd_app_list; iter != NULL; iter = iter->next) {
+ info = iter->data;
+ WARN("disturb app : %s", info->busname);
+
+ body = g_variant_new("()");
+ ret = send_event_notify_by_busname(body, "disturb_app", info->busname,
+ PROVIDER_NOTI_EVENT_INTERFACE_NAME);
+ g_variant_unref(body);
+ if (ret != NOTIFICATION_ERROR_NONE) {
+ ERR("Failed to call disturb callback [%d], name [%s]", ret, info->busname);
+ return ret;
+ }
+ }
+ }
+ } else {
+ ret = notification_launch_default_viewer(priv_id, status, uid);
+ if (ret != NOTIFICATION_ERROR_NONE)
+ ERR("Failed to launch default viewer [%d]", ret);
+ }
+
+ return ret;
+}
+
/* add noti */
static int _add_noti(GVariant **reply_body, notification_h noti, uid_t uid)
{
return ret;
}
- ret = notification_launch_default_viewer(priv_id,
- NOTIFICATION_OP_INSERT, uid);
+ ret = _notification_launch_viewer(noti, priv_id,
+ NOTIFICATION_OP_INSERT, uid);
if (ret != NOTIFICATION_ERROR_NONE) {
- ERR("Failed to launch default viewer [%d]", ret);
+ ERR("Failed to launch viewer [%d]", ret);
ret = NOTIFICATION_ERROR_NONE;
}
-
*reply_body = g_variant_new("(i)", priv_id);
if (*reply_body == NULL) {
ERR("Failed to make reply");
return ret;
}
- ret = notification_launch_default_viewer(priv_id,
- NOTIFICATION_OP_UPDATE, uid);
+ ret = _notification_launch_viewer(noti, priv_id,
+ NOTIFICATION_OP_UPDATE, uid);
if (ret != NOTIFICATION_ERROR_NONE) {
- ERR("Failed to launch default viewer [%d]", ret);
+ ERR("Failed to launch viewer [%d]", ret);
ret = NOTIFICATION_ERROR_NONE;
}
if (ret != NOTIFICATION_ERROR_NONE)
return ret;
- ret = notification_launch_default_viewer(NOTIFICATION_PRIV_ID_NONE,
+ /* delete disturb noti info from list */
+ __delete_disturb_noti_info(priv_id);
+
+ ret = _notification_launch_viewer(NULL, NOTIFICATION_PRIV_ID_NONE,
NOTIFICATION_OP_DELETE,
uid);
if (ret != NOTIFICATION_ERROR_NONE) {
- ERR("Failed to launch default viewer [%d]", ret);
+ ERR("Failed to launch viewer [%d]", ret);
ret = NOTIFICATION_ERROR_NONE;
}
}
free(list_deleted);
return ret;
}
+
+ /* delete disturb noti info from list */
+ __delete_disturb_noti_info(*(list_deleted + i));
}
free(list_deleted);
- ret = notification_launch_default_viewer(NOTIFICATION_PRIV_ID_NONE,
+ ret = _notification_launch_viewer(NULL, NOTIFICATION_PRIV_ID_NONE,
NOTIFICATION_OP_DELETE_ALL,
param_uid);
if (ret != NOTIFICATION_ERROR_NONE) {
- ERR("Failed to launch default viewer [%d]", ret);
+ ERR("Failed to launch viewer [%d]", ret);
ret = NOTIFICATION_ERROR_NONE;
}
}
(deleted_list +i)->priv_id,
param_uid);
__delete_sender_info((deleted_list +i)->priv_id);
+
+ /* delete disturb noti info from list */
+ __delete_disturb_noti_info((deleted_list +i)->priv_id);
}
__free_deleted_list_info(deleted_list, deleted_num);
return ret;
}
- ret = notification_launch_default_viewer(NOTIFICATION_PRIV_ID_NONE,
+ ret = _notification_launch_viewer(NULL, NOTIFICATION_PRIV_ID_NONE,
NOTIFICATION_OP_DELETE_ALL,
param_uid);
if (ret != NOTIFICATION_ERROR_NONE) {
- ERR("Failed to launch default viewer [%d]", ret);
+ ERR("Failed to launch viewer [%d]", ret);
ret = NOTIFICATION_ERROR_NONE;
}
}
ret = __delete_sender_info(*(list_deleted + i));
if (ret != NOTIFICATION_ERROR_NONE)
goto out;
+
+ /* delete disturb noti info from list */
+ __delete_disturb_noti_info(*(list_deleted + i));
}
}
out:
return NOTIFICATION_ERROR_NONE;
}
+/* added for do not disturb app */
+static bool _is_dnd_app_exist(void)
+{
+ if (__dnd_app_list != NULL && g_list_length(__dnd_app_list) > 0)
+ return true;
+
+ return false;
+}
+
+static void __free_dnd_app_info(gpointer data)
+{
+ dnd_app_info_s *info = (dnd_app_info_s *)data;
+
+ if (info) {
+ if (info->busname)
+ free(info->busname);
+ free(info);
+ }
+}
+
+static gint __pid_compare(gconstpointer a, gconstpointer b)
+{
+ dnd_app_info_s *info = NULL;
+
+ if (!a)
+ return -1;
+
+ info = (dnd_app_info_s *)a;
+
+ if (info->pid == GPOINTER_TO_INT(b))
+ return 0;
+
+ return 1;
+}
+
+static void __dnd_app_sender_name_appeared_cb(GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ WARN("name[%s], name_owner[%s]", name, name_owner);
+}
+
+static void __dnd_app_sender_name_vanished_cb(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ dnd_app_info_s *info;
+
+ if (!user_data)
+ return;
+
+ info = (dnd_app_info_s *)user_data;
+
+ WARN("name[%s], pid[%d], watcher_id[%d]",
+ name, (int)info->pid, info->watcher_id);
+}
+
+static guint __insert_dnd_app_sender_watcher_id(dnd_app_info_s *sender_info)
+{
+ guint watcher_id = 0;
+
+ watcher_id = g_bus_watch_name(G_BUS_TYPE_SYSTEM,
+ sender_info->busname,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ __dnd_app_sender_name_appeared_cb,
+ __dnd_app_sender_name_vanished_cb,
+ sender_info,
+ NULL);
+ if (!watcher_id) {
+ ERR("Failed to watch sender name");
+ return 0;
+ }
+
+ WARN("Watch on busname[%s] watcher_id[%d]", sender_info->busname, watcher_id);
+ return watcher_id;
+}
+
+static dnd_app_info_s *__find_dnd_app_info_by_pid(pid_t pid)
+{
+ dnd_app_info_s *dnd_app_info;
+ GList *find_list;
+
+ if (__dnd_app_list == NULL) {
+ ERR("find disturb list null");
+ return NULL;
+ }
+
+ __dnd_app_list = g_list_first(__dnd_app_list);
+ find_list = g_list_find_custom(__dnd_app_list, GINT_TO_POINTER(pid),
+ (GCompareFunc)__pid_compare);
+
+ if (find_list)
+ dnd_app_info = g_list_nth_data(find_list, 0);
+ else
+ return NULL;
+
+ return dnd_app_info;
+}
+
+static void __delete_dnd_app_info(pid_t pid)
+{
+ dnd_app_info_s *info;
+ GList *delete_list = NULL;
+
+ WARN("delete dnd app info : [%d]", pid);
+
+ if (__dnd_app_list != NULL) {
+ __dnd_app_list = g_list_first(__dnd_app_list);
+ delete_list = g_list_find_custom(__dnd_app_list, GINT_TO_POINTER(pid),
+ (GCompareFunc)__pid_compare);
+ if (delete_list != NULL) {
+ info = (dnd_app_info_s *)g_list_nth_data(delete_list, 0);
+
+ WARN("delete dnd app from list : [%d], name : %s", info->pid, info->busname);
+
+ __dnd_app_list = g_list_remove(g_list_first(__dnd_app_list), info);
+ g_bus_unwatch_name(info->watcher_id);
+ __free_dnd_app_info(info);
+ if (g_list_length(__dnd_app_list) == 0)
+ __dnd_app_list = NULL;
+ }
+ }
+}
+
+int notification_register_dnd_app(GVariant *parameters, GVariant **reply_body,
+ const char *sender, pid_t pid, uid_t uid)
+{
+ GList *find_list = NULL;
+ dnd_app_info_s *sender_info;
+ dnd_app_info_s *tmp_info = NULL;
+ uid_t param_uid;
+ pid_t param_pid;
+
+ /* is parameter necessary ?? */
+ /* is it necessary to check valid uid, pid ?? */
+ g_variant_get(parameters, "(ii)", ¶m_uid, ¶m_pid);
+
+ WARN("register dnd app, uid : %d, param uid : %d, pid : %d, param pid : %d",
+ uid, param_uid, pid, param_pid);
+
+ if (sender == NULL)
+ return NOTIFICATION_ERROR_INVALID_PARAMETER;
+
+ sender_info = (dnd_app_info_s *)malloc(sizeof(dnd_app_info_s));
+ if (sender_info == NULL) {
+ ERR("malloc failed");
+ return NOTIFICATION_ERROR_OUT_OF_MEMORY;
+ }
+
+ sender_info->pid = pid;
+ sender_info->busname = strdup(sender);
+
+ if (__dnd_app_list == NULL) {
+ sender_info->watcher_id = __insert_dnd_app_sender_watcher_id(sender_info);
+ __dnd_app_list = g_list_append(__dnd_app_list, sender_info);
+ } else {
+ __dnd_app_list = g_list_first(__dnd_app_list);
+ find_list = g_list_find_custom(__dnd_app_list, GINT_TO_POINTER(pid),
+ (GCompareFunc)__pid_compare);
+ if (find_list == NULL) {
+ sender_info->watcher_id = __insert_dnd_app_sender_watcher_id(sender_info);
+ __dnd_app_list = g_list_append(__dnd_app_list, sender_info);
+ } else {
+ tmp_info = (dnd_app_info_s *)g_list_nth_data(find_list, 0);
+ if (tmp_info->busname) {
+ if (strcmp(tmp_info->busname, sender)) {
+ free(tmp_info->busname);
+ tmp_info->busname = strdup(sender);
+ g_bus_unwatch_name(tmp_info->watcher_id);
+ tmp_info->watcher_id = __insert_dnd_app_sender_watcher_id(sender_info);
+ }
+ } else {
+ tmp_info->busname = strdup(sender);
+ if (!tmp_info->watcher_id)
+ g_bus_unwatch_name(tmp_info->watcher_id);
+ tmp_info->watcher_id = __insert_dnd_app_sender_watcher_id(tmp_info);
+ }
+ __free_dnd_app_info(sender_info);
+ }
+ }
+ aul_listen_app_dead_signal_v2(_aul_app_dead_event_cb_v2, NULL);
+
+ *reply_body = g_variant_new("()");
+ if (*reply_body == NULL)
+ ERR("Failed to make reply_body");
+
+ return NOTIFICATION_ERROR_NONE;
+}
+
/* End of a file */