[network-manager-netbook] Add gnome-bluetooth plugin
- From: Tambet Ingo <tambeti src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [network-manager-netbook] Add gnome-bluetooth plugin
- Date: Wed, 9 Dec 2009 14:47:58 +0000 (UTC)
commit 37433bc6b912fe0d69aa4941a0dc5072fea5da58
Author: Tambet Ingo <tambet gmail com>
Date: Wed Dec 9 15:38:45 2009 +0200
Add gnome-bluetooth plugin
Copied from network-manager-applet and modified to handle system connections,
not re-read everything from GConf, not leak GConf settings etc. This should
be changed in nm-applet as well.
Makefile.am | 2 +-
configure.in | 10 +
gnome-bluetooth/Makefile.am | 15 ++
gnome-bluetooth/network-manager-applet.c | 344 ++++++++++++++++++++++++++++++
libnm-gtk/nm-gconf-settings.c | 81 ++++++-
po/POTFILES.in | 1 +
src/nmn-panel-client.c | 1 +
7 files changed, 441 insertions(+), 13 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 1d7321d..3755ab9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = icons marshallers libnm-gtk src po
+SUBDIRS = icons marshallers libnm-gtk src gnome-bluetooth po
autostartdir = $(sysconfdir)/xdg/autostart
autostart_in_files = network-manager-netbook.desktop.in
diff --git a/configure.in b/configure.in
index c9087a5..9cee737 100644
--- a/configure.in
+++ b/configure.in
@@ -28,11 +28,21 @@ PKG_CHECK_MODULES(LIBNM_GTK, gtk+-2.0 gconf-2.0 gnome-keyring-1 libnm-util >= $N
PKG_CHECK_MODULES(NMN, dbus-glib-1 >= 0.75 gtk+-2.0 gconf-2.0 gnome-keyring-1 libnotify libnm-util >= $NM_REQUIRED libnm-glib >= $NM_REQUIRED mobile-broadband-provider-info moblin-panel nbtk-gtk-1.2)
+dnl Check for gnome-bluetooth
+PKG_CHECK_MODULES(GNOME_BLUETOOTH,
+ gconf-2.0
+ gnome-bluetooth-1.0 >= 2.27.6
+ libnm-util
+ libnm-glib,
+ have_gbt=yes, have_gbt=no)
+AM_CONDITIONAL(HAVE_GBT, test x"$have_gbt" = "xyes")
+
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
AC_SUBST(GLIB_GENMARSHAL)
AC_CONFIG_FILES([
Makefile
+gnome-bluetooth/Makefile
icons/Makefile
icons/22/Makefile
icons/32/Makefile
diff --git a/gnome-bluetooth/Makefile.am b/gnome-bluetooth/Makefile.am
new file mode 100644
index 0000000..6406ab7
--- /dev/null
+++ b/gnome-bluetooth/Makefile.am
@@ -0,0 +1,15 @@
+plugindir = $(libdir)/gnome-bluetooth/plugins
+
+if HAVE_GBT
+plugin_LTLIBRARIES = libnma.la
+
+libnma_la_CPPFLAGS = \
+ -I${top_srcdir}/libnm-gtk \
+ $(GNOME_BLUETOOTH_CFLAGS)
+
+libnma_la_SOURCES = network-manager-applet.c
+libnma_la_LDFLAGS = -module -avoid-version
+libnma_la_LIBADD = $(top_builddir)/libnm-gtk/libnm-gtk.la $(GNOME_BLUETOOTH_LIBS)
+endif
+
+EXTRA_DIST = network-manager-applet.c
diff --git a/gnome-bluetooth/network-manager-applet.c b/gnome-bluetooth/network-manager-applet.c
new file mode 100644
index 0000000..e9a8117
--- /dev/null
+++ b/gnome-bluetooth/network-manager-applet.c
@@ -0,0 +1,344 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2009 Bastien Nocera <hadess hadess net>
+ *
+ *
+ * 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
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <net/ethernet.h>
+#include <netinet/ether.h>
+#include <glib/gi18n-lib.h>
+
+#include <gtk/gtk.h>
+#include <bluetooth-plugin.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-bluetooth.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-utils.h>
+#include <nm-settings-interface.h>
+#include <nm-remote-settings.h>
+#include <nm-remote-settings-system.h>
+#include <gconf-helpers.h>
+
+static gboolean
+has_config_widget (const char *bdaddr, const char **uuids)
+{
+ guint i;
+
+ for (i = 0; uuids && uuids[i] != NULL; i++) {
+ if (g_str_equal (uuids[i], "NAP"))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static GByteArray *
+get_array_from_bdaddr (const char *str)
+{
+ struct ether_addr *addr;
+ GByteArray *array;
+
+ addr = ether_aton (str);
+ if (addr) {
+ array = g_byte_array_sized_new (ETH_ALEN);
+ g_byte_array_append (array, (const guint8 *) addr->ether_addr_octet, ETH_ALEN);
+ return array;
+ }
+
+ return NULL;
+}
+
+typedef struct {
+ GSList *settings;
+ GMainLoop *loop;
+ guint counter;
+} GetSettingsSyncInfo;
+
+static void
+connection_added (NMSettingsInterface *settings,
+ NMSettingsConnectionInterface *connection,
+ gpointer user_data)
+{
+ GetSettingsSyncInfo *info = user_data;
+
+ info->settings = g_slist_prepend (info->settings, g_object_ref (connection));
+}
+
+static void
+connections_read (NMSettingsInterface *settings,
+ gpointer user_data)
+{
+ GetSettingsSyncInfo *info = user_data;
+
+ info->counter--;
+ if (info->counter < 1)
+ g_main_loop_quit (info->loop);
+}
+
+static gboolean
+get_settings_timed_out (gpointer user_data)
+{
+ GetSettingsSyncInfo *info = user_data;
+
+ g_warning ("Getting settings timed out");
+ g_main_loop_quit (info->loop);
+
+ return FALSE;
+}
+
+static GSList *
+get_settings_sync ()
+{
+ DBusGConnection *bus;
+ NMSettingsInterface *user_settings;
+ NMSettingsInterface *system_settings;
+ GetSettingsSyncInfo info;
+ GError *err = NULL;
+ gboolean running;
+
+ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+ if (!bus) {
+ g_warning ("Couldn't connect to system bus: %s", err->message);
+ g_error_free (err);
+ return NULL;
+ }
+
+ info.settings = NULL;
+ info.loop = g_main_loop_new (NULL, FALSE);
+ info.counter = 0;
+
+ user_settings = NM_SETTINGS_INTERFACE (nm_remote_settings_new (bus, NM_CONNECTION_SCOPE_USER));
+ g_object_get (user_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running, NULL);
+ if (running) {
+ g_signal_connect (user_settings, "new-connection", G_CALLBACK (connection_added), &info);
+ g_signal_connect (user_settings, "connections-read", G_CALLBACK (connections_read), &info);
+ info.counter++;
+ }
+
+ system_settings = NM_SETTINGS_INTERFACE (nm_remote_settings_system_new (bus));
+ g_object_get (system_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &running, NULL);
+ if (running) {
+ g_signal_connect (system_settings, "new-connection", G_CALLBACK (connection_added), &info);
+ g_signal_connect (system_settings, "connections-read", G_CALLBACK (connections_read), &info);
+ info.counter++;
+ }
+
+ dbus_g_connection_unref (bus);
+
+ if (info.counter > 0) {
+ /* Add a timer so that we don't wait here forever in case we never
+ get signaled that services are read */
+ g_timeout_add_seconds (5, get_settings_timed_out, &info);
+ g_main_loop_run (info.loop);
+ }
+
+ g_main_loop_unref (info.loop);
+ g_object_unref (user_settings);
+ g_object_unref (system_settings);
+
+ return info.settings;
+}
+
+static NMSettingsConnectionInterface *
+get_connection_for_bdaddr (const char *bdaddr)
+{
+ NMSettingsConnectionInterface *found = NULL;
+ GSList *list, *l;
+ GByteArray *array;
+
+ array = get_array_from_bdaddr (bdaddr);
+ if (array == NULL)
+ return NULL;
+
+ list = get_settings_sync ();
+ for (l = list; l != NULL; l = l->next) {
+ NMSettingsConnectionInterface *candidate = l->data;
+ NMSetting *setting;
+ const char *type;
+ const GByteArray *addr;
+
+ setting = nm_connection_get_setting_by_name (NM_CONNECTION (candidate), NM_SETTING_BLUETOOTH_SETTING_NAME);
+ if (setting == NULL)
+ continue;
+ type = nm_setting_bluetooth_get_connection_type (NM_SETTING_BLUETOOTH (setting));
+ if (g_strcmp0 (type, NM_SETTING_BLUETOOTH_TYPE_PANU) != 0)
+ continue;
+ addr = nm_setting_bluetooth_get_bdaddr (NM_SETTING_BLUETOOTH (setting));
+ if (addr == NULL || memcmp (addr->data, array->data, addr->len) != 0)
+ continue;
+ found = g_object_ref (candidate);
+ break;
+ }
+
+ g_slist_foreach (list, (GFunc) g_object_unref, NULL);
+ g_slist_free (list);
+
+ return found;
+}
+
+static NMConnection *
+create_connection (const char *bdaddr)
+{
+ NMConnection *connection;
+ NMSetting *setting;
+ GByteArray *mac;
+ char *id, *uuid;
+
+ mac = get_array_from_bdaddr (bdaddr);
+ if (mac == NULL)
+ return NULL;
+
+ /* The connection */
+ connection = nm_connection_new ();
+
+ /* The connection settings */
+ setting = nm_setting_connection_new ();
+ id = g_strdup_printf ("%s %s", bdaddr, "PANU");
+ uuid = nm_utils_uuid_generate ();
+ g_object_set (G_OBJECT (setting),
+ NM_SETTING_CONNECTION_ID, id,
+ NM_SETTING_CONNECTION_UUID, uuid,
+ NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_SETTING_NAME,
+ NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+ NULL);
+ g_free (id);
+ g_free (uuid);
+ nm_connection_add_setting (connection, setting);
+
+ /* The Bluetooth settings */
+ setting = nm_setting_bluetooth_new ();
+ g_object_set (G_OBJECT (setting),
+ NM_SETTING_BLUETOOTH_BDADDR, mac,
+ NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
+ NULL);
+ g_byte_array_free (mac, TRUE);
+ nm_connection_add_setting (connection, setting);
+
+ /* The IPv4 settings */
+ setting = nm_setting_ip4_config_new ();
+ g_object_set (G_OBJECT (setting),
+ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+ NULL);
+ nm_connection_add_setting (connection, setting);
+
+ nm_gconf_write_connection (connection, NULL, NULL);
+
+ return connection;
+}
+
+static void
+delete_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data)
+{
+ if (error)
+ g_warning ("Error deleting connection: (%d) %s", error->code, error->message);
+ if (user_data)
+ g_object_set_data (G_OBJECT (user_data), "conn", NULL);
+}
+
+static void
+delete_connection (GObject *button, NMConnection *connection)
+{
+ NMSettingsConnectionInterface *ci;
+
+ if (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection))
+ ci = NM_SETTINGS_CONNECTION_INTERFACE (connection);
+ else {
+ const char *bdaddr;
+
+ bdaddr = g_object_get_data (button, "bdaddr");
+ g_assert (bdaddr);
+ ci = get_connection_for_bdaddr (bdaddr);
+ }
+
+ if (ci)
+ nm_settings_connection_interface_delete (ci, delete_cb, button);
+}
+
+static void
+button_toggled (GtkToggleButton *button, gpointer user_data)
+{
+ NMConnection *connection;
+
+ if (gtk_toggle_button_get_active (button) == FALSE) {
+ connection = g_object_get_data (G_OBJECT (button), "conn");
+ delete_connection (G_OBJECT (button), connection);
+ } else {
+ const char *bdaddr;
+
+ bdaddr = g_object_get_data (G_OBJECT (button), "bdaddr");
+ g_assert (bdaddr);
+
+ connection = create_connection (bdaddr);
+ if (connection)
+ g_object_set_data_full (G_OBJECT (button), "conn", connection, g_object_unref);
+ }
+}
+
+static GtkWidget *
+get_config_widgets (const char *bdaddr, const char **uuids)
+{
+ GtkWidget *button;
+ NMSettingsConnectionInterface *connection;
+
+ button = gtk_check_button_new_with_label (_("Access the Internet using your mobile phone"));
+ g_object_set_data_full (G_OBJECT (button),
+ "bdaddr", g_strdup (bdaddr),
+ (GDestroyNotify) g_free);
+ connection = get_connection_for_bdaddr (bdaddr);
+ if (connection != NULL) {
+ g_object_set_data_full (G_OBJECT (button), "conn", connection, g_object_unref);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+ }
+ g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK (button_toggled), NULL);
+
+ return button;
+}
+
+static void
+device_removed (const char *bdaddr)
+{
+ NMSettingsConnectionInterface *connection;
+
+ g_message ("Device '%s' got removed", bdaddr);
+
+ // FIXME: don't just delete any random PAN conenction for this
+ // bdaddr, actually delete the one this plugin created
+ connection = get_connection_for_bdaddr (bdaddr);
+ if (connection) {
+ nm_settings_connection_interface_delete (connection, delete_cb, NULL);
+ g_object_unref (connection);
+ }
+}
+
+static GbtPluginInfo plugin_info = {
+ "network-manager-applet",
+ has_config_widget,
+ get_config_widgets,
+ device_removed
+};
+
+GBT_INIT_PLUGIN(plugin_info)
+
diff --git a/libnm-gtk/nm-gconf-settings.c b/libnm-gtk/nm-gconf-settings.c
index e9b0b21..062b34f 100644
--- a/libnm-gtk/nm-gconf-settings.c
+++ b/libnm-gtk/nm-gconf-settings.c
@@ -180,6 +180,67 @@ nm_gconf_settings_add_connection (NMGConfSettings *self, NMConnection *connectio
return exported;
}
+static gboolean
+is_dbus_request_authorized (DBusGMethodInvocation *context,
+ GError **error)
+{
+ DBusGConnection *bus = NULL;
+ DBusConnection *connection = NULL;
+ char *sender = NULL;
+ gulong sender_uid = G_MAXULONG;
+ DBusError dbus_error;
+ gboolean success = FALSE;
+
+ sender = dbus_g_method_get_sender (context);
+ if (!sender) {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ "%s", "Could not determine D-Bus requestor");
+ goto out;
+ }
+
+ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+ if (!bus) {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ "%s", "Could not get the system bus");
+ goto out;
+ }
+ connection = dbus_g_connection_get_connection (bus);
+ if (!connection) {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
+ "%s", "Could not get the D-Bus system bus");
+ goto out;
+ }
+
+ dbus_error_init (&dbus_error);
+ sender_uid = dbus_bus_get_unix_user (connection, sender, &dbus_error);
+ if (dbus_error_is_set (&dbus_error)) {
+ dbus_error_free (&dbus_error);
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_PERMISSION_DENIED,
+ "%s", "Could not determine the Unix user ID of the requestor");
+ goto out;
+ }
+
+ /* And finally, the actual UID check */
+ if (sender_uid == geteuid ())
+ success = TRUE;
+ else {
+ g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
+ NM_SETTINGS_INTERFACE_ERROR_PERMISSION_DENIED,
+ "%s", "Requestor UID does not match the UID of the user settings service");
+ }
+
+ out:
+ if (bus)
+ dbus_g_connection_unref (bus);
+
+ g_free (sender);
+ return success;
+}
+
static void
add_connection (NMSettingsService *settings,
NMConnection *connection,
@@ -188,21 +249,17 @@ add_connection (NMSettingsService *settings,
gpointer user_data)
{
NMGConfSettings *self = NM_GCONF_SETTINGS (settings);
+ GError *error = NULL;
- /* For now, we don't support additions via D-Bus until we figure out
- * the security implications.
- */
- if (context) {
- GError *error;
+ if (context)
+ is_dbus_request_authorized (context, &error);
- error = g_error_new (0, 0, "%s: adding connections via D-Bus is not (yet) supported", __func__);
- callback (NM_SETTINGS_INTERFACE (settings), error, user_data);
- g_error_free (error);
- return;
- }
+ if (!error)
+ nm_gconf_settings_add_connection (self, connection);
- nm_gconf_settings_add_connection (self, connection);
- callback (NM_SETTINGS_INTERFACE (settings), NULL, user_data);
+ callback (NM_SETTINGS_INTERFACE (settings), error, user_data);
+ if (error)
+ g_error_free (error);
}
static NMGConfConnection *
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 934405a..7cc96fd 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,4 +1,5 @@
network-manager-netbook.desktop.in
+gnome-bluetooth/networm-manager-applet.c
libnm-gtk/nm-bt-item.c
libnm-gtk/nm-ethernet-item.c
libnm-gtk/nm-wifi-item.c
diff --git a/src/nmn-panel-client.c b/src/nmn-panel-client.c
index 138b66f..48e124a 100644
--- a/src/nmn-panel-client.c
+++ b/src/nmn-panel-client.c
@@ -96,6 +96,7 @@ activation_animation (gpointer data)
priv->animation_step = 1;
image = g_strdup_printf ("progress-%02d", priv->animation_step);
+ g_print ("Requesting button style %s", image);
mpl_panel_client_request_button_style (MPL_PANEL_CLIENT (self), image);
g_free (image);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]