Back to index

indicator-session  12.10.0
session-dbus.c
Go to the documentation of this file.
00001 /*
00002 The Dbus object on the bus for the indicator.
00003 
00004 Copyright 2010 Canonical Ltd.
00005 
00006 Authors:
00007     Ted Gould <ted@canonical.com>
00008     Conor Curran <conor.curran@canonical.com>
00009 
00010 This program is free software: you can redistribute it and/or modify it
00011 under the terms of the GNU General Public License version 3, as published
00012 by the Free Software Foundation.
00013 
00014 This program is distributed in the hope that it will be useful, but
00015 WITHOUT ANY WARRANTY; without even the implied warranties of
00016 MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
00017 PURPOSE.  See the GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License along
00020 with this program.  If not, see <http://www.gnu.org/licenses/>.
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 #include <gio/gio.h>
00028 
00029 #include "session-dbus.h"
00030 #include "shared-names.h"
00031 
00032 static GVariant * get_users_real_name (SessionDbus * service);
00033 static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data);
00034 static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data);
00035 
00036 #include "gen-session-dbus.xml.h"
00037 
00038 typedef struct _SessionDbusPrivate SessionDbusPrivate;
00039 struct _SessionDbusPrivate {
00040        gchar * name;
00041        GDBusConnection * bus;
00042        GCancellable * bus_cancel;
00043        guint dbus_registration;
00044 };
00045 
00046 /* GDBus Stuff */
00047 static GDBusNodeInfo *      node_info = NULL;
00048 static GDBusInterfaceInfo * interface_info = NULL;
00049 static GDBusInterfaceVTable interface_table = {
00050        method_call:    bus_method_call,
00051        get_property:   NULL, /* No properties */
00052        set_property:   NULL  /* No properties */
00053 };
00054 
00055 #define SESSION_DBUS_GET_PRIVATE(o) \
00056 (G_TYPE_INSTANCE_GET_PRIVATE ((o), SESSION_DBUS_TYPE, SessionDbusPrivate))
00057 
00058 static void session_dbus_class_init (SessionDbusClass *klass);
00059 static void session_dbus_init       (SessionDbus *self);
00060 static void session_dbus_dispose    (GObject *object);
00061 static void session_dbus_finalize   (GObject *object);
00062 
00063 G_DEFINE_TYPE (SessionDbus, session_dbus, G_TYPE_OBJECT);
00064 
00065 static void
00066 session_dbus_class_init (SessionDbusClass *klass)
00067 {
00068        GObjectClass *object_class = G_OBJECT_CLASS (klass);
00069 
00070        g_type_class_add_private (klass, sizeof (SessionDbusPrivate));
00071 
00072        object_class->dispose = session_dbus_dispose;
00073        object_class->finalize = session_dbus_finalize;
00074 
00075        /* Setting up the DBus interfaces */
00076        if (node_info == NULL) {
00077               GError * error = NULL;
00078 
00079               node_info = g_dbus_node_info_new_for_xml(_session_dbus, &error);
00080               if (error != NULL) {
00081                      g_error("Unable to parse Session Service Interface description: %s", error->message);
00082                      g_error_free(error);
00083               }
00084        }
00085 
00086        if (interface_info == NULL) {
00087               interface_info = g_dbus_node_info_lookup_interface(node_info, INDICATOR_SESSION_SERVICE_DBUS_IFACE);
00088 
00089               if (interface_info == NULL) {
00090                      g_error("Unable to find interface '" INDICATOR_SESSION_SERVICE_DBUS_IFACE "'");
00091               }
00092        }
00093 
00094        return;
00095 }
00096 
00097 static void
00098 session_dbus_init (SessionDbus *self)
00099 {
00100        SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(self);
00101 
00102        priv->name = NULL;
00103        priv->bus = NULL;
00104        priv->bus_cancel = NULL;
00105        priv->dbus_registration = 0;
00106 
00107        priv->bus_cancel = g_cancellable_new();
00108        g_bus_get(G_BUS_TYPE_SESSION,
00109                  priv->bus_cancel,
00110                  bus_get_cb,
00111                  self);
00112 
00113        return;
00114 }
00115 
00116 static void
00117 bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data)
00118 {
00119        GError * error = NULL;
00120        GDBusConnection * connection = g_bus_get_finish(res, &error);
00121 
00122        if (error != NULL) {
00123               g_error("OMG! Unable to get a connection to DBus: %s", error->message);
00124               g_error_free(error);
00125               return;
00126        }
00127 
00128        SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(user_data);
00129 
00130        g_warn_if_fail(priv->bus == NULL);
00131        priv->bus = connection;
00132 
00133        if (priv->bus_cancel != NULL) {
00134               g_object_unref(priv->bus_cancel);
00135               priv->bus_cancel = NULL;
00136        }
00137 
00138        /* Now register our object on our new connection */
00139        priv->dbus_registration = g_dbus_connection_register_object(priv->bus,
00140                                                                    INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
00141                                                                    interface_info,
00142                                                                    &interface_table,
00143                                                                    user_data,
00144                                                                    NULL,
00145                                                                    &error);
00146 
00147        if (error != NULL) {
00148               g_error("Unable to register the object to DBus: %s", error->message);
00149               g_error_free(error);
00150               return;
00151        }
00152 
00153        return;       
00154 }
00155 
00156 /* A method has been called from our dbus inteface.  Figure out what it
00157    is and dispatch it. */
00158 static void
00159 bus_method_call (GDBusConnection * connection, const gchar * sender,
00160                  const gchar * path, const gchar * interface,
00161                  const gchar * method, GVariant * params,
00162                  GDBusMethodInvocation * invocation, gpointer user_data)
00163 {
00164        SessionDbus * service = SESSION_DBUS (user_data);
00165 
00166        GVariant * retval = NULL;
00167 
00168        if (g_strcmp0(method, "GetUserRealName") == 0) {
00169               retval = get_users_real_name (service);
00170        }
00171   else {
00172     g_warning("Calling method '%s' on the indicator service and it's unknown", method);
00173        }
00174        g_dbus_method_invocation_return_value(invocation, retval);
00175        return;
00176 }
00177 
00178 static void
00179 session_dbus_dispose (GObject *object)
00180 {
00181        SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(object);
00182 
00183        if (priv->dbus_registration != 0) {
00184               g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration);
00185               /* Don't care if it fails, there's nothing we can do */
00186               priv->dbus_registration = 0;
00187        }
00188 
00189        if (priv->bus != NULL) {
00190               g_object_unref(priv->bus);
00191               priv->bus = NULL;
00192        }
00193 
00194        if (priv->bus_cancel != NULL) {
00195               g_cancellable_cancel(priv->bus_cancel);
00196               g_object_unref(priv->bus_cancel);
00197               priv->bus_cancel = NULL;
00198        }
00199 
00200        G_OBJECT_CLASS (session_dbus_parent_class)->dispose (object);
00201        return;
00202 }
00203 
00204 static void
00205 session_dbus_finalize (GObject *object)
00206 {
00207        SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(object);
00208 
00209        g_clear_pointer (&priv->name, g_free);
00210 
00211        G_OBJECT_CLASS (session_dbus_parent_class)->finalize (object);
00212        return;
00213 }
00214 
00215 static GVariant *
00216 get_users_real_name (SessionDbus * service)
00217 {
00218        SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(service);
00219        return g_variant_new ("(s)", priv->name ? priv->name : "");
00220 }
00221 
00222 SessionDbus *
00223 session_dbus_new (void)
00224 {
00225        return SESSION_DBUS(g_object_new(SESSION_DBUS_TYPE, NULL));
00226 }
00227 
00228 void
00229 session_dbus_set_name (SessionDbus * session, const gchar * name)
00230 {
00231 }
00232 
00233 void
00234 session_dbus_set_users_real_name (SessionDbus * session, const gchar * name)
00235 {
00236        SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session);
00237        GError * error = NULL;
00238 
00239        g_free (priv->name);
00240        priv->name = g_strdup(name);
00241 
00242        if (priv->bus != NULL) {
00243               g_dbus_connection_emit_signal (priv->bus,
00244                                    NULL,
00245                                    INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
00246                                    INDICATOR_SESSION_SERVICE_DBUS_IFACE,
00247                                    "UserRealNameUpdated",
00248                                    g_variant_new ("(s)", priv->name, NULL),
00249                                    &error);
00250 
00251               if (error != NULL) {
00252                      g_warning("Unable to send UserRealNameUpdated signal: %s", error->message);
00253                      g_error_free(error);
00254                      return;
00255               }
00256        }
00257        return;
00258 }
00259 
00260 void session_dbus_restart_required (SessionDbus* session)
00261 {
00262        SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session);
00263        GError * error = NULL;
00264 
00265        if (priv->bus != NULL) {
00266     g_debug("About to send RebootRequired signal");
00267 
00268               g_dbus_connection_emit_signal (priv->bus,
00269                                    NULL,
00270                                    INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
00271                                    INDICATOR_SESSION_SERVICE_DBUS_IFACE,
00272                                    "RestartRequired",
00273                                    NULL,
00274                                    &error);
00275 
00276               if (error != NULL) {
00277                      g_warning("Unable to send reboot-required signal: %s", error->message);
00278                      g_error_free(error);
00279               }
00280        }
00281 
00282 }