diff options
-rw-r--r-- | configure.ac | 45 | ||||
-rw-r--r-- | data/empathy.schemas.in | 8 | ||||
-rw-r--r-- | libempathy-gtk/empathy-conf.h | 2 | ||||
-rw-r--r-- | libempathy-gtk/empathy-presence-chooser.c | 26 | ||||
-rw-r--r-- | libempathy/Makefile.am | 8 | ||||
-rw-r--r-- | libempathy/empathy-connectivity.c | 433 | ||||
-rw-r--r-- | libempathy/empathy-connectivity.h | 71 | ||||
-rw-r--r-- | libempathy/empathy-debug.c | 1 | ||||
-rw-r--r-- | libempathy/empathy-debug.h | 1 | ||||
-rw-r--r-- | libempathy/empathy-idle.c | 158 | ||||
-rw-r--r-- | libempathy/empathy-idle.h | 3 | ||||
-rw-r--r-- | src/empathy.c | 27 |
12 files changed, 630 insertions, 153 deletions
diff --git a/configure.ac b/configure.ac index 3484e3cd3..bc0491cae 100644 --- a/configure.ac +++ b/configure.ac @@ -157,14 +157,31 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Gettext package name]) AM_GLIB_GNU_GETTEXT # ----------------------------------------------------------- -# NM integration +# Connectivity integration # ----------------------------------------------------------- -AC_ARG_ENABLE(network-manager, - AS_HELP_STRING([--enable-network-manager=@<:@no/yes/auto@:>@], - [build with network-manager support]), , - enable_network_manager=auto) +AC_ARG_WITH(connectivity, + AS_HELP_STRING([--with-connectivity=@<:@nm/connman/auto/no@:>@], + [build with connectivity support]), , + with_connectivity=auto) + +if test "x$with_connectivity" = "xno"; then + have_nm=no + have_connman=no + +elif test "x$with_connectivity" = "xconnman"; then + + PKG_CHECK_MODULES(CONNMAN, + [ + dbus-glib-1 + ], have_connman="yes", have_connman="no") + + if test "x$have_connman" = "xyes"; then + AC_DEFINE(HAVE_CONNMAN, 1, [Define if you have connman dependencies]) + have_nm=no + fi + +else -if test "x$enable_network_manager" != "xno"; then PKG_CHECK_MODULES(NETWORK_MANAGER, [ libnm_glib >= $NETWORK_MANAGER_REQUIRED @@ -172,15 +189,20 @@ if test "x$enable_network_manager" != "xno"; then if test "x$have_nm" = "xyes"; then AC_DEFINE(HAVE_NM, 1, [Define if you have libnm-glib]) + have_connman=no fi -else - have_nm=no fi -if test "x$enable_network_manager" = "xyes" -a "x$have_nm" != "xyes"; then +if test "x$with_connectivity" = "xconnman" -a "x$have_connman" != "xyes"; then + AC_MSG_ERROR([Couldn't find connman dependencies.]) +fi + +if test "x$with_connectivity" = "xnm" -a "x$have_nm" != "xyes"; then AC_MSG_ERROR([Couldn't find libnm-glib dependencies.]) fi -AM_CONDITIONAL(HAVE_NM, test "x$have_NM" = "xyes") + +AM_CONDITIONAL(HAVE_NM, test "x$have_nm" = "xyes") +AM_CONDITIONAL(HAVE_CONNMAN, test "x$have_connman" = "xyes") # ----------------------------------------------------------- # Webkit @@ -479,7 +501,10 @@ Configure summary: Display maps (libchamplain).: ${have_libchamplain} Location awareness (Geoclue): ${have_geoclue} Adium themes (Webkit).......: ${have_webkit} + + Connectivity: NetworkManager integration..: ${have_nm} + ConnMan integration.........: ${have_connman} Extras: Documentation...............: ${enable_gtk_doc} diff --git a/data/empathy.schemas.in b/data/empathy.schemas.in index edd8e5bdf..bb9068725 100644 --- a/data/empathy.schemas.in +++ b/data/empathy.schemas.in @@ -479,15 +479,15 @@ </schema> <schema> - <key>/schemas/apps/empathy/use_nm</key> - <applyto>/apps/empathy/use_nm</applyto> + <key>/schemas/apps/empathy/use_conn</key> + <applyto>/apps/empathy/use_conn</applyto> <owner>empathy</owner> <type>bool</type> <default>true</default> <locale name="C"> - <short>NetworkManager should be used</short> + <short>Connection managers should be used</short> <long> - Whether or not the network manager should be used to automatically + Whether or not connectivity managers should be used to automatically disconnect/reconnect. </long> </locale> diff --git a/libempathy-gtk/empathy-conf.h b/libempathy-gtk/empathy-conf.h index 2383a7edf..d8e34f6b9 100644 --- a/libempathy-gtk/empathy-conf.h +++ b/libempathy-gtk/empathy-conf.h @@ -78,7 +78,7 @@ struct _EmpathyConfClass { #define EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM EMPATHY_PREFS_PATH "/contacts/sort_criterium" #define EMPATHY_PREFS_HINTS_CLOSE_MAIN_WINDOW EMPATHY_PREFS_PATH "/hints/close_main_window" #define EMPATHY_PREFS_SALUT_ACCOUNT_CREATED EMPATHY_PREFS_PATH "/accounts/salut_created" -#define EMPATHY_PREFS_USE_NM EMPATHY_PREFS_PATH "/use_nm" +#define EMPATHY_PREFS_USE_CONN EMPATHY_PREFS_PATH "/use_conn" #define EMPATHY_PREFS_AUTOCONNECT EMPATHY_PREFS_PATH "/autoconnect" #define EMPATHY_PREFS_IMPORT_ASKED EMPATHY_PREFS_PATH "/import_asked" #define EMPATHY_PREFS_FILE_TRANSFER_DEFAULT_FOLDER EMPATHY_PREFS_PATH "/file_transfer/default_folder" diff --git a/libempathy-gtk/empathy-presence-chooser.c b/libempathy-gtk/empathy-presence-chooser.c index 7c5850af8..ba36e091c 100644 --- a/libempathy-gtk/empathy-presence-chooser.c +++ b/libempathy-gtk/empathy-presence-chooser.c @@ -35,6 +35,7 @@ #include <telepathy-glib/util.h> +#include <libempathy/empathy-connectivity.h> #include <libempathy/empathy-idle.h> #include <libempathy/empathy-utils.h> #include <libempathy/empathy-status-presets.h> @@ -98,6 +99,9 @@ typedef enum { typedef struct { EmpathyIdle *idle; + EmpathyConnectivity *connectivity; + + gulong state_change_signal_id; gboolean editing_status; int block_set_editing; @@ -710,6 +714,14 @@ presence_chooser_entry_focus_out_cb (EmpathyPresenceChooser *chooser, } static void +presence_chooser_connectivity_state_change (EmpathyConnectivity *connectivity, + gboolean new_online, + EmpathyPresenceChooser *chooser) +{ + gtk_widget_set_sensitive (GTK_WIDGET (chooser), new_online); +} + +static void empathy_presence_chooser_init (EmpathyPresenceChooser *chooser) { EmpathyPresenceChooserPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (chooser, @@ -780,6 +792,14 @@ empathy_presence_chooser_init (EmpathyPresenceChooser *chooser) /* FIXME: this string sucks */ gtk_widget_set_tooltip_text (GTK_WIDGET (chooser), _("Set your presence and current status")); + + priv->connectivity = empathy_connectivity_dup_singleton (); + priv->state_change_signal_id = g_signal_connect (priv->connectivity, + "state-change", + G_CALLBACK (presence_chooser_connectivity_state_change), + chooser); + presence_chooser_connectivity_state_change (priv->connectivity, + empathy_connectivity_is_online (priv->connectivity), chooser); } static void @@ -802,6 +822,12 @@ presence_chooser_finalize (GObject *object) object); g_object_unref (priv->idle); + g_signal_handler_disconnect (priv->connectivity, + priv->state_change_signal_id); + priv->state_change_signal_id = 0; + + g_object_unref (priv->connectivity); + G_OBJECT_CLASS (empathy_presence_chooser_parent_class)->finalize (object); } diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am index 27671543a..0250a63d8 100644 --- a/libempathy/Makefile.am +++ b/libempathy/Makefile.am @@ -10,7 +10,8 @@ AM_CPPFLAGS = \ -DG_LOG_DOMAIN=\"empathy\" \ $(LIBEMPATHY_CFLAGS) \ $(GEOCLUE_CFLAGS) \ - $(NETWORK_MANAGER_CFLAGS) \ + $(NETWORK_MANAGER_CFLAGS) \ + $(CONNMAN_CFLAGS) \ $(WARN_CFLAGS) \ $(DISABLE_DEPRECATED) @@ -31,6 +32,7 @@ libempathy_la_SOURCES = \ empathy-chatroom-manager.c \ empathy-call-factory.c \ empathy-call-handler.c \ + empathy-connectivity.c \ empathy-contact.c \ empathy-contact-groups.c \ empathy-contact-list.c \ @@ -69,7 +71,8 @@ libempathy_la_LIBADD = \ $(top_builddir)/extensions/libemp-extensions.la \ $(LIBEMPATHY_LIBS) \ $(GEOCLUE_LIBS) \ - $(NETWORK_MANAGER_LIBS) + $(NETWORK_MANAGER_LIBS) \ + $(CONNMAN_LIBS) libempathy_la_LDFLAGS = \ -version-info ${LIBEMPATHY_CURRENT}:${LIBEMPATHY_REVISION}:${LIBEMPATHY_AGE} \ @@ -82,6 +85,7 @@ libempathy_headers = \ empathy-chatroom-manager.h \ empathy-call-factory.h \ empathy-call-handler.h \ + empathy-connectivity.h \ empathy-contact.h \ empathy-contact-groups.h \ empathy-contact-list.h \ diff --git a/libempathy/empathy-connectivity.c b/libempathy/empathy-connectivity.c new file mode 100644 index 000000000..bbbcba467 --- /dev/null +++ b/libempathy/empathy-connectivity.c @@ -0,0 +1,433 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * 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.1 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> + */ + +#include "config.h" +#include "empathy-connectivity.h" + +#ifdef HAVE_NM +#include <nm-client.h> +#endif + +#ifdef HAVE_CONNMAN +#include <dbus/dbus-glib.h> +#endif + +#include <telepathy-glib/util.h> + +#include "empathy-utils.h" +#include "empathy-marshal.h" + +#define DEBUG_FLAG EMPATHY_DEBUG_CONNECTIVITY +#include "empathy-debug.h" + +#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyConnectivity) + +typedef struct { +#ifdef HAVE_NM + NMClient *nm_client; + gulong state_change_signal_id; +#endif + +#ifdef HAVE_CONNMAN + DBusGProxy *proxy; +#endif + + gboolean connected; + gboolean use_conn; +} EmpathyConnectivityPriv; + +enum { + STATE_CHANGE, + LAST_SIGNAL +}; + +enum { + PROP_0, + PROP_USE_CONN, +}; + +static guint signals[LAST_SIGNAL]; +static EmpathyConnectivity *connectivity_singleton = NULL; + +G_DEFINE_TYPE (EmpathyConnectivity, empathy_connectivity, G_TYPE_OBJECT); + +static void +connectivity_change_state (EmpathyConnectivity *connectivity, + gboolean new_state) +{ + EmpathyConnectivityPriv *priv; + + priv = GET_PRIV (connectivity); + + if (priv->connected == new_state) + return; + + priv->connected = new_state; + + g_signal_emit (connectivity, signals[STATE_CHANGE], 0, + priv->connected); +} + +#ifdef HAVE_NM +static void +connectivity_nm_state_change_cb (NMClient *client, + const GParamSpec *pspec, + EmpathyConnectivity *connectivity) +{ + EmpathyConnectivityPriv *priv; + gboolean new_nm_connected; + NMState state; + + priv = GET_PRIV (connectivity); + + if (!priv->use_conn) + return; + + state = nm_client_get_state (priv->nm_client); + new_nm_connected = !(state == NM_STATE_CONNECTING + || state == NM_STATE_DISCONNECTED); + + DEBUG ("New NetworkManager network state %d", state); + + connectivity_change_state (connectivity, new_nm_connected); +} +#endif + +#ifdef HAVE_CONNMAN +static void +connectivity_connman_state_changed_cb (DBusGProxy *proxy, + const gchar *new_state, + EmpathyConnectivity *connectivity) +{ + EmpathyConnectivityPriv *priv; + gboolean new_connected; + + priv = GET_PRIV (connectivity); + + if (!priv->use_conn) + return; + + new_connected = !tp_strdiff (new_state, "online"); + + DEBUG ("New ConnMan network state %s", new_state); + + connectivity_change_state (connectivity, new_connected); +} + +static void +connectivity_connman_check_state_cb (DBusGProxy *proxy, + DBusGProxyCall *call_id, + gpointer user_data) +{ + EmpathyConnectivity *connectivity = (EmpathyConnectivity *) user_data; + GError *error = NULL; + gchar *state; + + if (dbus_g_proxy_end_call (proxy, call_id, &error, + G_TYPE_STRING, &state, G_TYPE_INVALID)) + { + connectivity_connman_state_changed_cb (proxy, state, + connectivity); + g_free (state); + } + else + { + DEBUG ("Failed to call GetState: %s", error->message); + connectivity_connman_state_changed_cb (proxy, "offline", + connectivity); + } +} + +static void +connectivity_connman_check_state (EmpathyConnectivity *connectivity) +{ + EmpathyConnectivityPriv *priv; + + priv = GET_PRIV (connectivity); + + dbus_g_proxy_begin_call (priv->proxy, "GetState", + connectivity_connman_check_state_cb, connectivity, NULL, + G_TYPE_INVALID); +} +#endif + +static void +empathy_connectivity_init (EmpathyConnectivity *connectivity) +{ + EmpathyConnectivityPriv *priv; +#ifdef HAVE_CONNMAN + DBusGConnection *connection; + GError *error = NULL; +#endif + + priv = G_TYPE_INSTANCE_GET_PRIVATE (connectivity, + EMPATHY_TYPE_CONNECTIVITY, EmpathyConnectivityPriv); + + connectivity->priv = priv; + + priv->use_conn = TRUE; + +#ifdef HAVE_NM + priv->nm_client = nm_client_new (); + if (priv->nm_client != NULL) + { + priv->state_change_signal_id = g_signal_connect (priv->nm_client, + "notify::" NM_CLIENT_STATE, + G_CALLBACK (connectivity_nm_state_change_cb), connectivity); + + connectivity_nm_state_change_cb (priv->nm_client, NULL, connectivity); + } + else + { + DEBUG ("Failed to get NetworkManager proxy"); + } +#endif + +#ifdef HAVE_CONNMAN + connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (connection != NULL) + { + priv->proxy = dbus_g_proxy_new_for_name (connection, + "org.moblin.connman", "/", + "org.moblin.connman.Manager"); + + dbus_g_object_register_marshaller ( + _empathy_marshal_VOID__STRING, + G_TYPE_NONE, G_TYPE_STRING, G_TYPE_INVALID); + + dbus_g_proxy_add_signal (priv->proxy, "StateChanged", + G_TYPE_STRING, G_TYPE_INVALID); + + dbus_g_proxy_connect_signal (priv->proxy, "StateChanged", + G_CALLBACK (connectivity_connman_state_changed_cb), + connectivity, NULL); + + connectivity_connman_check_state (connectivity); + } + else + { + DEBUG ("Failed to get system bus connection: %s", error->message); + g_error_free (error); + } +#endif + +#if !defined(HAVE_NM) || !defined(HAVE_CONNMAN) + priv->connected = TRUE; +#endif +} + +static void +connectivity_finalize (GObject *object) +{ +#ifdef HAVE_NM + EmpathyConnectivity *connectivity = EMPATHY_CONNECTIVITY (object); + EmpathyConnectivityPriv *priv = GET_PRIV (connectivity); + + if (priv->nm_client != NULL) + { + g_signal_handler_disconnect (priv->nm_client, + priv->state_change_signal_id); + priv->state_change_signal_id = 0; + g_object_unref (priv->nm_client); + priv->nm_client = NULL; + } +#endif + +#ifdef HAVE_CONNMAN + EmpathyConnectivity *connectivity = EMPATHY_CONNECTIVITY (object); + EmpathyConnectivityPriv *priv = GET_PRIV (connectivity); + + if (priv->proxy != NULL) + { + dbus_g_proxy_disconnect_signal (priv->proxy, "StateChanged", + G_CALLBACK (connectivity_connman_state_changed_cb), connectivity); + + g_object_unref (priv->proxy); + priv->proxy = NULL; + } +#endif + + G_OBJECT_CLASS (empathy_connectivity_parent_class)->finalize (object); +} + +static void +connectivity_dispose (GObject *object) +{ + G_OBJECT_CLASS (empathy_connectivity_parent_class)->dispose (object); +} + +static GObject * +connectivity_constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *retval; + + if (!connectivity_singleton) + { + retval = G_OBJECT_CLASS (empathy_connectivity_parent_class)->constructor + (type, n_construct_params, construct_params); + + connectivity_singleton = EMPATHY_CONNECTIVITY (retval); + g_object_add_weak_pointer (retval, (gpointer) &connectivity_singleton); + } + else + { + retval = g_object_ref (connectivity_singleton); + } + + return retval; +} + +static void +connectivity_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + EmpathyConnectivity *connectivity = EMPATHY_CONNECTIVITY (object); + + switch (param_id) + { + case PROP_USE_CONN: + g_value_set_boolean (value, empathy_connectivity_get_use_conn ( + connectivity)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + }; +} + +static void +connectivity_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + EmpathyConnectivity *connectivity = EMPATHY_CONNECTIVITY (object); + + switch (param_id) + { + case PROP_USE_CONN: + empathy_connectivity_set_use_conn (connectivity, + g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + }; +} + +static void +empathy_connectivity_class_init (EmpathyConnectivityClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + + oclass->finalize = connectivity_finalize; + oclass->dispose = connectivity_dispose; + oclass->constructor = connectivity_constructor; + oclass->get_property = connectivity_get_property; + oclass->set_property = connectivity_set_property; + + signals[STATE_CHANGE] = + g_signal_new ("state-change", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _empathy_marshal_VOID__BOOLEAN, + G_TYPE_NONE, + 1, G_TYPE_BOOLEAN, NULL); + + g_object_class_install_property (oclass, + PROP_USE_CONN, + g_param_spec_boolean ("use-conn", + "Use connectivity managers", + "Set presence according to connectivity managers", + TRUE, + G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + + g_type_class_add_private (oclass, sizeof (EmpathyConnectivityPriv)); +} + +/* public methods */ + +EmpathyConnectivity * +empathy_connectivity_dup_singleton (void) +{ + return g_object_new (EMPATHY_TYPE_CONNECTIVITY, NULL); +} + +gboolean +empathy_connectivity_is_online (EmpathyConnectivity *connectivity) +{ + EmpathyConnectivityPriv *priv = GET_PRIV (connectivity); + + if (priv->use_conn) + { + return priv->connected; + } + else + { + return TRUE; + } +} + +gboolean +empathy_connectivity_get_use_conn (EmpathyConnectivity *connectivity) +{ + EmpathyConnectivityPriv *priv = GET_PRIV (connectivity); + + return priv->use_conn; +} + +void +empathy_connectivity_set_use_conn (EmpathyConnectivity *connectivity, + gboolean use_conn) +{ + EmpathyConnectivityPriv *priv = GET_PRIV (connectivity); + + if (use_conn == priv->use_conn) + return; + + DEBUG ("use_conn gconf key changed; new value = %s", + use_conn ? "true" : "false"); + + priv->use_conn = use_conn; + +#if defined(HAVE_NM) || defined(HAVE_CONNMAN) + if (use_conn) + { +#if defined(HAVE_NM) + connectivity_nm_state_change_cb (priv->nm_client, NULL, connectivity); +#elif defined(HAVE_CONNMAN) + connectivity_connman_check_state (connectivity); +#endif + } + else +#endif + { + connectivity_change_state (connectivity, TRUE); + } + + g_object_notify (G_OBJECT (connectivity), "use-conn"); +} diff --git a/libempathy/empathy-connectivity.h b/libempathy/empathy-connectivity.h new file mode 100644 index 000000000..ca507e910 --- /dev/null +++ b/libempathy/empathy-connectivity.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * 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.1 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Jonny Lamb <jonny.lamb@collabora.co.uk> + */ + +#ifndef __EMPATHY_CONNECTIVITY_H__ +#define __EMPATHY_CONNECTIVITY_H__ + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define EMPATHY_TYPE_CONNECTIVITY (empathy_connectivity_get_type ()) +#define EMPATHY_CONNECTIVITY(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_CONNECTIVITY, \ + EmpathyConnectivity)) +#define EMPATHY_CONNECTIVITY_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), EMPATHY_TYPE_CONNECTIVITY, \ + EmpathyConnectivityClass)) +#define EMPATHY_IS_CONNECTIVITY(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_CONNECTIVITY)) +#define EMPATHY_IS_CONNECTIVITY_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_CONNECTIVITY)) +#define EMPATHY_CONNECTIVITY_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_CONNECTIVITY, \ + EmpathyConnectivityClass)) + +typedef struct _EmpathyConnectivity EmpathyConnectivity; +typedef struct _EmpathyConnectivityClass EmpathyConnectivityClass; + +struct _EmpathyConnectivity { + GObject parent; + gpointer priv; +}; + +struct _EmpathyConnectivityClass { + GObjectClass parent_class; +}; + +GType empathy_connectivity_get_type (void); + +/* public methods */ + +EmpathyConnectivity * empathy_connectivity_dup_singleton (void); + +gboolean empathy_connectivity_is_online (EmpathyConnectivity *connectivity); + +gboolean empathy_connectivity_get_use_conn (EmpathyConnectivity *connectivity); +void empathy_connectivity_set_use_conn (EmpathyConnectivity *connectivity, + gboolean use_conn); + +G_END_DECLS + +#endif /* __EMPATHY_CONNECTIVITY_H__ */ + diff --git a/libempathy/empathy-debug.c b/libempathy/empathy-debug.c index 99111deec..9d69b801c 100644 --- a/libempathy/empathy-debug.c +++ b/libempathy/empathy-debug.c @@ -49,6 +49,7 @@ static GDebugKey keys[] = { { "Ft", EMPATHY_DEBUG_FT }, { "Location", EMPATHY_DEBUG_LOCATION }, { "Other", EMPATHY_DEBUG_OTHER }, + { "Connectivity", EMPATHY_DEBUG_CONNECTIVITY }, { 0, } }; diff --git a/libempathy/empathy-debug.h b/libempathy/empathy-debug.h index 0d25f22dd..edfa05d95 100644 --- a/libempathy/empathy-debug.h +++ b/libempathy/empathy-debug.h @@ -42,6 +42,7 @@ typedef enum EMPATHY_DEBUG_LOCATION = 1 << 8, EMPATHY_DEBUG_OTHER = 1 << 9, EMPATHY_DEBUG_SHARE_DESKTOP = 1 << 10, + EMPATHY_DEBUG_CONNECTIVITY = 1 << 11, } EmpathyDebugFlags; gboolean empathy_debug_flag_is_set (EmpathyDebugFlags flag); diff --git a/libempathy/empathy-idle.c b/libempathy/empathy-idle.c index 5d2fa2bdc..ac0ca72f6 100644 --- a/libempathy/empathy-idle.c +++ b/libempathy/empathy-idle.c @@ -25,9 +25,6 @@ #include <glib/gi18n-lib.h> #include <dbus/dbus-glib.h> -#ifdef HAVE_NM -#include <nm-client.h> -#endif #include <telepathy-glib/dbus.h> #include <telepathy-glib/util.h> @@ -35,6 +32,7 @@ #include "empathy-idle.h" #include "empathy-utils.h" +#include "empathy-connectivity.h" #define DEBUG_FLAG EMPATHY_DEBUG_OTHER #include "empathy-debug.h" @@ -46,22 +44,19 @@ typedef struct { MissionControl *mc; DBusGProxy *gs_proxy; -#ifdef HAVE_NM - NMClient *nm_client; -#endif + EmpathyConnectivity *connectivity; + gulong state_change_signal_id; TpConnectionPresenceType state; gchar *status; TpConnectionPresenceType flash_state; gboolean auto_away; - gboolean use_nm; TpConnectionPresenceType away_saved_state; - TpConnectionPresenceType nm_saved_state; - gchar *nm_saved_status; + TpConnectionPresenceType saved_state; + gchar *saved_status; gboolean is_idle; - gboolean nm_connected; guint ext_away_timeout; } EmpathyIdlePriv; @@ -78,8 +73,7 @@ enum { PROP_STATE, PROP_STATUS, PROP_FLASH_STATE, - PROP_AUTO_AWAY, - PROP_USE_NM + PROP_AUTO_AWAY }; G_DEFINE_TYPE (EmpathyIdle, empathy_idle, G_TYPE_OBJECT); @@ -172,7 +166,7 @@ idle_session_status_changed_cb (DBusGProxy *gs_proxy, is_idle ? "yes" : "no"); if (!priv->auto_away || - (priv->nm_saved_state == TP_CONNECTION_PRESENCE_TYPE_UNSET && + (priv->saved_state == TP_CONNECTION_PRESENCE_TYPE_UNSET && (priv->state <= TP_CONNECTION_PRESENCE_TYPE_OFFLINE || priv->state == TP_CONNECTION_PRESENCE_TYPE_HIDDEN))) { /* We don't want to go auto away OR we explicitely asked to be @@ -187,11 +181,11 @@ idle_session_status_changed_cb (DBusGProxy *gs_proxy, idle_ext_away_start (idle); - if (priv->nm_saved_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) { + if (priv->saved_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) { /* We are disconnected, when coming back from away * we want to restore the presence before the * disconnection. */ - priv->away_saved_state = priv->nm_saved_state; + priv->away_saved_state = priv->saved_state; } else { priv->away_saved_state = priv->state; } @@ -231,56 +225,37 @@ idle_session_status_changed_cb (DBusGProxy *gs_proxy, priv->is_idle = is_idle; } -#ifdef HAVE_NM static void -idle_nm_state_change_cb (NMClient *client, - const GParamSpec *pspec, - EmpathyIdle *idle) +idle_state_change_cb (EmpathyConnectivity *connectivity, + gboolean new_online, + EmpathyIdle *idle) { EmpathyIdlePriv *priv; - gboolean old_nm_connected; - gboolean new_nm_connected; - NMState state; priv = GET_PRIV (idle); - if (!priv->use_nm) { - return; - } - - state = nm_client_get_state (priv->nm_client); - old_nm_connected = priv->nm_connected; - new_nm_connected = !(state == NM_STATE_CONNECTING || - state == NM_STATE_DISCONNECTED); - priv->nm_connected = TRUE; /* To be sure _set_state will work */ - - DEBUG ("New network state %d", state); - - if (old_nm_connected && !new_nm_connected) { - /* We are no more connected */ + if (!new_online) { + /* We are no longer connected */ DEBUG ("Disconnected: Save state %d (%s)", priv->state, priv->status); - priv->nm_saved_state = priv->state; - g_free (priv->nm_saved_status); - priv->nm_saved_status = g_strdup (priv->status); + priv->saved_state = priv->state; + g_free (priv->saved_status); + priv->saved_status = g_strdup (priv->status); empathy_idle_set_state (idle, TP_CONNECTION_PRESENCE_TYPE_OFFLINE); } - else if (!old_nm_connected && new_nm_connected - && priv->nm_saved_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) { + else if (new_online + && priv->saved_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) { /* We are now connected */ DEBUG ("Reconnected: Restore state %d (%s)", - priv->nm_saved_state, priv->nm_saved_status); + priv->saved_state, priv->saved_status); empathy_idle_set_presence (idle, - priv->nm_saved_state, - priv->nm_saved_status); - priv->nm_saved_state = TP_CONNECTION_PRESENCE_TYPE_UNSET; - g_free (priv->nm_saved_status); - priv->nm_saved_status = NULL; + priv->saved_state, + priv->saved_status); + priv->saved_state = TP_CONNECTION_PRESENCE_TYPE_UNSET; + g_free (priv->saved_status); + priv->saved_status = NULL; } - - priv->nm_connected = new_nm_connected; } -#endif static void idle_finalize (GObject *object) @@ -296,11 +271,11 @@ idle_finalize (GObject *object) g_object_unref (priv->gs_proxy); } -#ifdef HAVE_NM - if (priv->nm_client) { - g_object_unref (priv->nm_client); - } -#endif + g_signal_handler_disconnect (priv->connectivity, + priv->state_change_signal_id); + priv->state_change_signal_id = 0; + + g_object_unref (priv->connectivity); idle_ext_away_stop (EMPATHY_IDLE (object)); } @@ -350,9 +325,6 @@ idle_get_property (GObject *object, case PROP_AUTO_AWAY: g_value_set_boolean (value, empathy_idle_get_auto_away (idle)); break; - case PROP_USE_NM: - g_value_set_boolean (value, empathy_idle_get_use_nm (idle)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -384,9 +356,6 @@ idle_set_property (GObject *object, case PROP_AUTO_AWAY: empathy_idle_set_auto_away (idle, g_value_get_boolean (value)); break; - case PROP_USE_NM: - empathy_idle_set_use_nm (idle, g_value_get_boolean (value)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -435,14 +404,6 @@ empathy_idle_class_init (EmpathyIdleClass *klass) FALSE, G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_USE_NM, - g_param_spec_boolean ("use-nm", - "Use Network Manager", - "Set presence according to Network Manager", - TRUE, - G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); - g_type_class_add_private (object_class, sizeof (EmpathyIdlePriv)); } @@ -522,16 +483,9 @@ empathy_idle_init (EmpathyIdle *idle) DEBUG ("Failed to get gs proxy"); } -#ifdef HAVE_NM - priv->nm_client = nm_client_new (); - if (priv->nm_client) { - g_signal_connect (priv->nm_client, "notify::" NM_CLIENT_STATE, - G_CALLBACK (idle_nm_state_change_cb), - idle); - } else { - DEBUG ("Failed to get nm proxy"); - } -#endif + priv->connectivity = empathy_connectivity_dup_singleton (); + priv->state_change_signal_id = g_signal_connect (priv->connectivity, + "state-change", G_CALLBACK (idle_state_change_cb), idle); } EmpathyIdle * @@ -664,10 +618,9 @@ empathy_idle_set_presence (EmpathyIdle *idle, status = NULL; } - if (!priv->nm_connected) { - DEBUG ("NM not connected"); + if (!empathy_connectivity_is_online (priv->connectivity)) { + DEBUG ("Empathy is not online"); - priv->nm_saved_state = state; if (tp_strdiff (priv->status, status)) { g_free (priv->status); priv->status = NULL; @@ -676,8 +629,6 @@ empathy_idle_set_presence (EmpathyIdle *idle, } g_object_notify (G_OBJECT (idle), "status"); } - - return; } empathy_idle_do_set_presence (idle, state, status); @@ -702,42 +653,3 @@ empathy_idle_set_auto_away (EmpathyIdle *idle, g_object_notify (G_OBJECT (idle), "auto-away"); } -gboolean -empathy_idle_get_use_nm (EmpathyIdle *idle) -{ - EmpathyIdlePriv *priv = GET_PRIV (idle); - - return priv->use_nm; -} - -void -empathy_idle_set_use_nm (EmpathyIdle *idle, - gboolean use_nm) -{ - EmpathyIdlePriv *priv = GET_PRIV (idle); - -#ifdef HAVE_NM - if (!priv->nm_client || use_nm == priv->use_nm) { - return; - } -#endif - - priv->use_nm = use_nm; - -#ifdef HAVE_NM - if (use_nm) { - idle_nm_state_change_cb (priv->nm_client, NULL, idle); -#else - if (0) { -#endif - } else { - priv->nm_connected = TRUE; - if (priv->nm_saved_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) { - empathy_idle_set_state (idle, priv->nm_saved_state); - } - priv->nm_saved_state = TP_CONNECTION_PRESENCE_TYPE_UNSET; - } - - g_object_notify (G_OBJECT (idle), "use-nm"); -} - diff --git a/libempathy/empathy-idle.h b/libempathy/empathy-idle.h index 0f7f23deb..d0b426e59 100644 --- a/libempathy/empathy-idle.h +++ b/libempathy/empathy-idle.h @@ -64,9 +64,6 @@ void empathy_idle_set_presence (EmpathyIdle *idle, gboolean empathy_idle_get_auto_away (EmpathyIdle *idle); void empathy_idle_set_auto_away (EmpathyIdle *idle, gboolean auto_away); -gboolean empathy_idle_get_use_nm (EmpathyIdle *idle); -void empathy_idle_set_use_nm (EmpathyIdle *idle, - gboolean use_nm); G_END_DECLS diff --git a/src/empathy.c b/src/empathy.c index 15155d28d..660e47cea 100644 --- a/src/empathy.c +++ b/src/empathy.c @@ -46,6 +46,7 @@ #include <libempathy/empathy-utils.h> #include <libempathy/empathy-call-factory.h> #include <libempathy/empathy-chatroom-manager.h> +#include <libempathy/empathy-connectivity.h> #include <libempathy/empathy-account-manager.h> #include <libempathy/empathy-debugger.h> #include <libempathy/empathy-dispatcher.h> @@ -208,15 +209,15 @@ operation_error_cb (MissionControl *mc, } static void -use_nm_notify_cb (EmpathyConf *conf, - const gchar *key, - gpointer user_data) +use_conn_notify_cb (EmpathyConf *conf, + const gchar *key, + gpointer user_data) { - EmpathyIdle *idle = user_data; - gboolean use_nm; + EmpathyConnectivity *connectivity = user_data; + gboolean use_conn; - if (empathy_conf_get_bool (conf, key, &use_nm)) { - empathy_idle_set_use_nm (idle, use_nm); + if (empathy_conf_get_bool (conf, key, &use_conn)) { + empathy_connectivity_set_use_conn (connectivity, use_conn); } } @@ -555,6 +556,7 @@ main (int argc, char *argv[]) GtkWidget *window; MissionControl *mc; EmpathyIdle *idle; + EmpathyConnectivity *connectivity; gboolean autoconnect = TRUE; gboolean no_connect = FALSE; gboolean hide_contact_list = FALSE; @@ -684,9 +686,13 @@ main (int argc, char *argv[]) /* Setting up Idle */ idle = empathy_idle_dup_singleton (); empathy_idle_set_auto_away (idle, TRUE); - use_nm_notify_cb (empathy_conf_get (), EMPATHY_PREFS_USE_NM, idle); - empathy_conf_notify_add (empathy_conf_get (), EMPATHY_PREFS_USE_NM, - use_nm_notify_cb, idle); + + /* Setting up Connectivity */ + connectivity = empathy_connectivity_dup_singleton (); + use_conn_notify_cb (empathy_conf_get (), EMPATHY_PREFS_USE_CONN, + connectivity); + empathy_conf_notify_add (empathy_conf_get (), EMPATHY_PREFS_USE_CONN, + use_conn_notify_cb, connectivity); /* Autoconnect */ empathy_conf_get_bool (empathy_conf_get (), @@ -747,6 +753,7 @@ main (int argc, char *argv[]) g_object_unref (mc); g_object_unref (idle); + g_object_unref (connectivity); g_object_unref (icon); g_object_unref (log_manager); g_object_unref (dispatcher); |