/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* * Copyright © 2014 Pranav Kant * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, see . * */ #include "config.h" #include #include "goadleynaservermanager.h" #include "goadleynaservermediadevice.h" #include "goadlnaservermanager.h" struct _GoaDlnaServerManager { GObject parent_instance; DleynaServerManager *proxy; GHashTable *servers; }; enum { SERVER_FOUND, SERVER_LOST, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (GoaDlnaServerManager, goa_dlna_server_manager, G_TYPE_OBJECT); static GObject *goa_dlna_server_manager_singleton = NULL; static void goa_dlna_server_manager_server_new_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GoaDlnaServerManager *self = GOA_DLNA_SERVER_MANAGER (user_data); DleynaServerMediaDevice *server; GError *error = NULL; const gchar *object_path; server = dleyna_server_media_device_proxy_new_for_bus_finish (res, &error); if (error != NULL) { g_warning ("Unable to load server object: %s", error->message); g_error_free (error); goto out; } object_path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (server)); g_debug ("%s '%s' %s %s", G_STRFUNC, dleyna_server_media_device_get_friendly_name (server), dleyna_server_media_device_get_udn (server), object_path); g_hash_table_insert (self->servers, (gpointer) object_path, server); g_signal_emit (self, signals[SERVER_FOUND], 0, server); out: g_object_unref (self); } static void goa_dlna_server_manager_server_found_cb (GoaDlnaServerManager *self, const gchar *object_path, gpointer *data) { dleyna_server_media_device_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, "com.intel.dleyna-server", object_path, NULL, /* GCancellable */ goa_dlna_server_manager_server_new_cb, g_object_ref (self)); } static void goa_dlna_server_manager_server_lost_cb (GoaDlnaServerManager *self, const gchar *object_path, gpointer *data) { DleynaServerMediaDevice *server; server = DLEYNA_SERVER_MEDIA_DEVICE (g_hash_table_lookup (self->servers, object_path)); g_return_if_fail (server != NULL); g_hash_table_steal (self->servers, object_path); g_debug ("%s '%s' %s %s", G_STRFUNC, dleyna_server_media_device_get_friendly_name (server), dleyna_server_media_device_get_udn (server), object_path); g_signal_emit (self, signals[SERVER_LOST], 0, server); g_object_unref (server); } static void goa_dlna_server_manager_proxy_get_servers_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GoaDlnaServerManager *self = GOA_DLNA_SERVER_MANAGER (user_data); GError *error = NULL; gchar **object_paths = NULL; guint i; dleyna_server_manager_call_get_servers_finish (self->proxy, &object_paths, res, &error); if (error != NULL) { g_warning ("Unable to fetch the list of available servers: %s", error->message); g_error_free (error); goto out; } for (i = 0; object_paths[i] != NULL; i++) goa_dlna_server_manager_server_found_cb (self, object_paths[i], NULL); g_signal_connect_swapped (self->proxy, "found-server", G_CALLBACK (goa_dlna_server_manager_server_found_cb), self); g_signal_connect_swapped (self->proxy, "lost-server", G_CALLBACK (goa_dlna_server_manager_server_lost_cb), self); out: g_strfreev (object_paths); g_object_unref (self); } static void goa_dlna_server_manager_proxy_new_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { GoaDlnaServerManager *self = GOA_DLNA_SERVER_MANAGER (user_data); GError *error = NULL; self->proxy = dleyna_server_manager_proxy_new_for_bus_finish (res, &error); if (error != NULL) { g_warning ("Unable to connect to the dLeynaServer.Manager DBus object: %s", error->message); g_error_free (error); goto out; } g_debug ("%s DLNA server manager initialized", G_STRFUNC); dleyna_server_manager_call_get_servers (self->proxy, NULL, goa_dlna_server_manager_proxy_get_servers_cb, g_object_ref (self)); out: g_object_unref (self); } static void goa_dlna_server_manager_dispose (GObject *object) { GoaDlnaServerManager *self = GOA_DLNA_SERVER_MANAGER (object); g_clear_pointer (&self->servers, (GDestroyNotify) g_hash_table_unref); g_clear_object (&self->proxy); G_OBJECT_CLASS (goa_dlna_server_manager_parent_class)->dispose (object); } static GObject * goa_dlna_server_manager_constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params) { if (goa_dlna_server_manager_singleton == NULL) { goa_dlna_server_manager_singleton = G_OBJECT_CLASS (goa_dlna_server_manager_parent_class)->constructor (type, n_construct_params, construct_params); g_object_add_weak_pointer (goa_dlna_server_manager_singleton, (gpointer) &goa_dlna_server_manager_singleton); return goa_dlna_server_manager_singleton; } return g_object_ref (goa_dlna_server_manager_singleton); } static void goa_dlna_server_manager_init (GoaDlnaServerManager *self) { dleyna_server_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, "com.intel.dleyna-server", "/com/intel/dLeynaServer", NULL, /* GCancellable */ goa_dlna_server_manager_proxy_new_cb, g_object_ref (self)); self->servers = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); } static void goa_dlna_server_manager_class_init (GoaDlnaServerManagerClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); object_class->constructor = goa_dlna_server_manager_constructor; object_class->dispose = goa_dlna_server_manager_dispose; signals[SERVER_FOUND] = g_signal_new ("server-found", G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, DLEYNA_SERVER_TYPE_MEDIA_DEVICE); signals[SERVER_LOST] = g_signal_new ("server-lost", G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, DLEYNA_SERVER_TYPE_MEDIA_DEVICE); } GoaDlnaServerManager * goa_dlna_server_manager_dup_singleton (void) { return g_object_new (GOA_TYPE_DLNA_SERVER_MANAGER, NULL); } GList * goa_dlna_server_manager_dup_servers (GoaDlnaServerManager *self) { GList *servers; servers = g_hash_table_get_values (self->servers); g_list_foreach (servers, (GFunc) g_object_ref, NULL); return servers; }