[network-manager-applet] core: correctly show mobile broadband enabled state in the menu



commit 264c223bbdda06d0ff9ff50329881def1019d253
Author: Dan Williams <dcbw redhat com>
Date:   Fri Apr 2 10:17:59 2010 -0700

    core: correctly show mobile broadband enabled state in the menu

 src/applet-device-cdma.c |  200 +++++++++++++++++++++++++++++++++++-----------
 src/applet-device-gsm.c  |   22 ++++-
 src/mb-menu-item.c       |   98 +++++++++++++----------
 src/mb-menu-item.h       |    1 +
 4 files changed, 229 insertions(+), 92 deletions(-)
---
diff --git a/src/applet-device-cdma.c b/src/applet-device-cdma.c
index 6f4da1e..78cc052 100644
--- a/src/applet-device-cdma.c
+++ b/src/applet-device-cdma.c
@@ -47,6 +47,30 @@
 typedef struct {
 	NMApplet *applet;
 	NMDevice *device;
+
+	DBusGProxy *props_proxy;
+	DBusGProxy *cdma_proxy;
+	gboolean quality_valid;
+	guint32 quality;
+	guint32 cdma1x_state;
+	guint32 evdo_state;
+	gboolean evdo_capable;
+	guint32 sid;
+	gboolean modem_enabled;
+
+	GHashTable *providers;
+	char *provider_name;
+
+	guint32 poll_id;
+	gboolean skip_reg_poll;
+	gboolean skip_signal_poll;
+} CdmaDeviceInfo;
+
+static void check_start_polling (CdmaDeviceInfo *info);
+
+typedef struct {
+	NMApplet *applet;
+	NMDevice *device;
 	NMConnection *connection;
 } CdmaMenuItemInfo;
 
@@ -198,28 +222,12 @@ add_connection_item (NMDevice *device,
 	gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 }
 
-typedef struct {
-	NMApplet *applet;
-
-	DBusGProxy *props_proxy;
-	DBusGProxy *cdma_proxy;
-	gboolean quality_valid;
-	guint32 quality;
-	guint32 cdma1x_state;
-	guint32 evdo_state;
-	gboolean evdo_capable;
-	guint32 sid;
-
-	GHashTable *providers;
-	char *provider_name;
-
-	gboolean nopoll;
-	guint32 poll_id;
-} CdmaDeviceInfo;
-
 static guint32
 cdma_state_to_mb_state (CdmaDeviceInfo *info)
 {
+	if (!info->modem_enabled)
+		return MB_STATE_UNKNOWN;
+
 	/* EVDO state overrides 1X state for now */
 	if (info->evdo_state) {
 		if (info->evdo_state == 3)
@@ -293,12 +301,13 @@ cdma_add_menu_item (NMDevice *device,
 		                            info->provider_name,
 		                            cdma_act_to_mb_act (info),
 		                            cdma_state_to_mb_state (info),
+		                            info->modem_enabled,
 		                            applet);
 
 		add_connection_item (device, active, item, menu, applet);
 	}
 
-	/* Notify user of unmanaged or unavailable device */
+	/* Get the "disconnect" item if connected */
 	if (nm_device_get_state (device) > NM_DEVICE_STATE_DISCONNECTED) {
 		item = nma_menu_device_get_menu_item (device, applet, NULL);
 		if (item) {
@@ -306,11 +315,13 @@ cdma_add_menu_item (NMDevice *device,
 			gtk_widget_show (item);
 		}
 	} else {
+		/* Otherwise show idle registration state or disabled */
 		item = nm_mb_menu_item_new (NULL,
 		                            info->quality_valid ? info->quality : 0,
 		                            info->provider_name,
 		                            cdma_act_to_mb_act (info),
 		                            cdma_state_to_mb_state (info),
+		                            info->modem_enabled,
 		                            applet);
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 	}
@@ -346,12 +357,7 @@ cdma_device_state_changed (NMDevice *device,
                            NMDeviceStateReason reason,
                            NMApplet *applet)
 {
-	CdmaDeviceInfo *info = g_object_get_data (G_OBJECT (device), "devinfo");
-
-	if (info) {
-		/* Don't poll for signal/registration if device isn't usable */
-		info->nopoll = (new_state <= NM_DEVICE_STATE_UNAVAILABLE);
-	}
+	CdmaDeviceInfo *info;
 
 	if (new_state == NM_DEVICE_STATE_ACTIVATED) {
 		NMConnection *connection;
@@ -375,6 +381,10 @@ cdma_device_state_changed (NMDevice *device,
 		                            PREF_DISABLE_CONNECTED_NOTIFICATIONS);
 		g_free (str);
 	}
+
+	/* Start/stop polling of quality and registration when device state changes */
+	info = g_object_get_data (G_OBJECT (device), "devinfo");
+	check_start_polling (info);
 }
 
 static GdkPixbuf *
@@ -743,28 +753,87 @@ serving_system_reply (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_dat
 	g_clear_error (&error);
 }
 
+static void
+enabled_reply (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+	CdmaDeviceInfo *info = user_data;
+	GError *error = NULL;
+	GValue value = { 0 };
+
+	if (dbus_g_proxy_end_call (proxy, call, &error,
+	                           G_TYPE_VALUE, &value,
+	                           G_TYPE_INVALID)) {
+		if (G_VALUE_HOLDS_BOOLEAN (&value))
+			info->modem_enabled = g_value_get_boolean (&value);
+		g_value_unset (&value);
+	}
+
+	g_clear_error (&error);
+	check_start_polling (info);
+}
+
 static gboolean
 cdma_poll_cb (gpointer user_data)
 {
 	CdmaDeviceInfo *info = user_data;
 
-	if (info->nopoll)
-		return TRUE;
-
 	/* Kick off calls to get registration state and signal quality */
-	dbus_g_proxy_begin_call (info->cdma_proxy, "GetRegistrationState",
-	                         reg_state_reply, info, NULL,
-	                         G_TYPE_INVALID);
+	if (!info->skip_reg_poll) {
+		dbus_g_proxy_begin_call (info->cdma_proxy, "GetRegistrationState",
+		                         reg_state_reply, info, NULL,
+		                         G_TYPE_INVALID);
+		info->skip_reg_poll = FALSE;
+	}
 
-	dbus_g_proxy_begin_call (info->cdma_proxy, "GetSignalQuality",
-	                         signal_reply, info, NULL,
-	                         G_TYPE_INVALID);
+	if (!info->skip_signal_poll) {
+		dbus_g_proxy_begin_call (info->cdma_proxy, "GetSignalQuality",
+		                         signal_reply, info, NULL,
+		                         G_TYPE_INVALID);
+		info->skip_signal_poll = FALSE;
+	}
 
 	dbus_g_proxy_begin_call (info->cdma_proxy, "GetServingSystem",
 	                         serving_system_reply, info, NULL,
 	                         G_TYPE_INVALID);
 
-	return TRUE;
+	return TRUE;  /* keep running until we're told to stop */
+}
+
+static void
+check_start_polling (CdmaDeviceInfo *info)
+{
+	NMDeviceState state;
+	gboolean poll = TRUE;
+
+	g_return_if_fail (info != NULL);
+
+	/* Don't poll if any of the following are true:
+	 *
+	 * 1) NM says the device is not available
+	 * 3) the modem isn't enabled
+	 */
+
+	state = nm_device_get_state (info->device);
+	if (   (state <= NM_DEVICE_STATE_UNAVAILABLE)
+	    || (info->modem_enabled == FALSE))
+		poll = FALSE;
+
+	if (poll) {
+		if (!info->poll_id) {
+			/* 33 seconds to be just a bit more than MM's poll interval, so
+			 * that if we get an unsolicited update from MM between polls we'll
+			 * skip the next poll.
+			 */
+	        info->poll_id = g_timeout_add_seconds (33, cdma_poll_cb, info);
+		}
+		cdma_poll_cb (info);
+	} else {
+		if (info->poll_id)
+			g_source_remove (info->poll_id);
+		info->poll_id = 0;
+		info->skip_reg_poll = FALSE;
+		info->skip_signal_poll = FALSE;
+	}
 }
 
 static void
@@ -777,6 +846,7 @@ reg_state_changed_cb (DBusGProxy *proxy,
 
 	info->cdma1x_state = cdma1x_state;
 	info->evdo_state = evdo_state;
+	info->skip_reg_poll = TRUE;
 
 	applet_schedule_update_icon (info->applet);
 }
@@ -790,10 +860,41 @@ signal_quality_changed_cb (DBusGProxy *proxy,
 
 	info->quality = quality;
 	info->quality_valid = TRUE;
+	info->skip_signal_poll = TRUE;
 
 	applet_schedule_update_icon (info->applet);
 }
 
+#define MM_DBUS_INTERFACE_MODEM "org.freedesktop.ModemManager.Modem"
+#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
+
+static void
+modem_properties_changed (DBusGProxy *proxy,
+                          const char *interface,
+                          GHashTable *props,
+                          gpointer user_data)
+{
+	CdmaDeviceInfo *info = user_data;
+	GValue *value;
+
+	if (!strcmp (interface, MM_DBUS_INTERFACE_MODEM)) {
+		value = g_hash_table_lookup (props, "Enabled");
+		if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+			info->modem_enabled = g_value_get_boolean (value);
+			if (!info->modem_enabled) {
+				info->quality = 0;
+				info->quality_valid = 0;
+				info->cdma1x_state = 0;
+				info->evdo_state = 0;
+				info->sid = 0;
+				g_free (info->provider_name);
+				info->provider_name = NULL;
+			}
+			check_start_polling (info);
+		}
+	}
+}
+
 static void
 cdma_device_added (NMDevice *device, NMApplet *applet)
 {
@@ -802,7 +903,6 @@ cdma_device_added (NMDevice *device, NMApplet *applet)
 	DBusGConnection *bus = applet_dbus_manager_get_connection (dbus_mgr);
 	CdmaDeviceInfo *info;
 	const char *udi;
-	NMDeviceState state;
 
 	udi = nm_device_get_udi (device);
 	if (!udi)
@@ -810,15 +910,11 @@ cdma_device_added (NMDevice *device, NMApplet *applet)
 
 	info = g_malloc0 (sizeof (CdmaDeviceInfo));
 	info->applet = applet;
+	info->device = device;
 	info->quality_valid = FALSE;
 
 	info->providers = nmn_mobile_providers_parse (NULL);
 
-	/* Don't bother polling if the device isn't usable */
-	state = nm_device_get_state (device);
-	if (state <= NM_DEVICE_STATE_UNAVAILABLE)
-		info->nopoll = TRUE;
-
 	info->props_proxy = dbus_g_proxy_new_for_name (bus,
 	                                               "org.freedesktop.ModemManager",
 	                                               udi,
@@ -857,10 +953,22 @@ cdma_device_added (NMDevice *device, NMApplet *applet)
 	dbus_g_proxy_connect_signal (info->cdma_proxy, "SignalQuality",
 	                             G_CALLBACK (signal_quality_changed_cb), info, NULL);
 
-	/* periodically poll for signal quality and registration state */
-	info->poll_id = g_timeout_add_seconds (10, cdma_poll_cb, info);
-	if (!info->nopoll)
-		cdma_poll_cb (info);
+	/* Modem property change signal */
+	dbus_g_object_register_marshaller (nma_marshal_VOID__STRING_BOXED,
+	                                   G_TYPE_NONE, G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
+	                                   G_TYPE_INVALID);
+	dbus_g_proxy_add_signal (info->props_proxy, "MmPropertiesChanged",
+	                         G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (info->props_proxy, "MmPropertiesChanged",
+	                             G_CALLBACK (modem_properties_changed),
+	                             info, NULL);
+
+	/* Ask whether the device is enabled */
+	dbus_g_proxy_begin_call (info->props_proxy, "Get",
+	                         enabled_reply, info, NULL,
+	                         G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
+	                         G_TYPE_STRING, "Enabled",
+	                         G_TYPE_INVALID);
 
 	g_object_unref (dbus_mgr);
 }
diff --git a/src/applet-device-gsm.c b/src/applet-device-gsm.c
index f53f4ad..ad60985 100644
--- a/src/applet-device-gsm.c
+++ b/src/applet-device-gsm.c
@@ -251,6 +251,9 @@ add_connection_item (NMDevice *device,
 static guint32
 gsm_state_to_mb_state (GsmDeviceInfo *info)
 {
+	if (!info->modem_enabled)
+		return MB_STATE_UNKNOWN;
+
 	switch (info->reg_state) {
 	case 1:  /* IDLE */
 		return MB_STATE_IDLE;
@@ -342,6 +345,7 @@ gsm_add_menu_item (NMDevice *device,
 		                            info->op_name,
 		                            gsm_act_to_mb_act (info),
 		                            gsm_state_to_mb_state (info),
+		                            info->modem_enabled,
 		                            applet);
 
 		add_connection_item (device, active, item, menu, applet);
@@ -360,6 +364,7 @@ gsm_add_menu_item (NMDevice *device,
 		                            info->op_name,
 		                            gsm_act_to_mb_act (info),
 		                            gsm_state_to_mb_state (info),
+		                            info->modem_enabled,
 		                            applet);
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
 	}
@@ -1287,17 +1292,16 @@ gsm_poll_cb (gpointer user_data)
 		dbus_g_proxy_begin_call (info->net_proxy, "GetRegistrationInfo",
 		                         reg_info_reply, info, NULL,
 		                         G_TYPE_INVALID);
+		info->skip_reg_poll = FALSE;
 	}
 
 	if (!info->skip_signal_poll) {
 		dbus_g_proxy_begin_call (info->net_proxy, "GetSignalQuality",
 		                         signal_reply, info, NULL,
 		                         G_TYPE_INVALID);
+		info->skip_signal_poll = FALSE;
 	}
 
-	info->skip_reg_poll = FALSE;
-	info->skip_signal_poll = FALSE;
-
 	return TRUE;  /* keep running until we're told to stop */
 }
 
@@ -1394,6 +1398,16 @@ modem_properties_changed (DBusGProxy *proxy,
 		value = g_hash_table_lookup (props, "Enabled");
 		if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
 			info->modem_enabled = g_value_get_boolean (value);
+			if (!info->modem_enabled) {
+				info->quality = 0;
+				info->quality_valid = 0;
+				info->reg_state = 0;
+				info->act = 0;
+				g_free (info->op_code);
+				info->op_code = NULL;
+				g_free (info->op_name);
+				info->op_name = NULL;
+			}
 			check_start_polling (info);
 		}
 	} else if (!strcmp (interface, MM_DBUS_INTERFACE_MODEM_GSM_NETWORK)) {
@@ -1487,7 +1501,7 @@ gsm_device_added (NMDevice *device, NMApplet *applet)
 	                         G_TYPE_STRING, "UnlockRequired",
 	                         G_TYPE_INVALID);
 
-	/* Ask whether the device needs to be unlocked */
+	/* Ask whether the device is enabled */
 	dbus_g_proxy_begin_call (info->props_proxy, "Get",
 	                         enabled_reply, info, NULL,
 	                         G_TYPE_STRING, MM_DBUS_INTERFACE_MODEM,
diff --git a/src/mb-menu-item.c b/src/mb-menu-item.c
index e2bea5f..6ee163c 100644
--- a/src/mb-menu-item.c
+++ b/src/mb-menu-item.c
@@ -53,34 +53,25 @@ get_tech_name (guint32 tech)
 	switch (tech) {
 	case MB_TECH_1XRTT:
 		return _("CDMA");
-		break;
 	case MB_TECH_EVDO_REV0:
 	case MB_TECH_EVDO_REVA:
 		return _("EVDO");
-		break;
 	case MB_TECH_GSM:
 		return _("GSM");
-		break;
 	case MB_TECH_GPRS:
 		return _("GPRS");
-		break;
 	case MB_TECH_EDGE:
 		return _("EDGE");
-		break;
 	case MB_TECH_UMTS:
 		return _("UMTS");
-		break;
 	case MB_TECH_HSDPA:
 		return _("HSDPA");
-		break;
 	case MB_TECH_HSUPA:
 		return _("HSUPA");
-		break;
 	case MB_TECH_HSPA:
 		return _("HSPA");
-		break;
 	default:
-		g_assert_not_reached ();
+		break;
 	}
 	return NULL;
 }
@@ -91,14 +82,13 @@ nm_mb_menu_item_new (const char *connection_name,
                      const char *provider,
                      guint32 technology,
                      guint32 state,
+                     gboolean enabled,
                      NMApplet *applet)
 {
 	NMMbMenuItem *item;
 	NMMbMenuItemPrivate *priv;
 	const char *tech_name;
 
-	g_return_val_if_fail (technology != MB_TECH_UNKNOWN, NULL);
-
 	item = g_object_new (NM_TYPE_MB_MENU_ITEM, NULL);
 	if (!item)
 		return NULL;
@@ -110,6 +100,9 @@ nm_mb_menu_item_new (const char *connection_name,
 	tech_name = get_tech_name (technology);
 	switch (state) {
 	default:
+	case MB_STATE_UNKNOWN:
+		priv->desc_string = g_strdup (_("not enabled"));
+		break;
 	case MB_STATE_IDLE:
 		if (connection_name)
 			priv->desc_string = g_strdup (connection_name);
@@ -118,15 +111,24 @@ nm_mb_menu_item_new (const char *connection_name,
 		break;
 	case MB_STATE_HOME:
 		if (connection_name) {
-			if (provider)
+			if (provider && tech_name)
 				priv->desc_string = g_strdup_printf ("%s (%s %s)", connection_name, provider, tech_name);
+			else if (provider || tech_name)
+				priv->desc_string = g_strdup_printf ("%s (%s)", connection_name, provider ? provider : tech_name);
 			else
-				priv->desc_string = g_strdup_printf ("%s (%s)", connection_name, tech_name);
+				priv->desc_string = g_strdup_printf ("%s", connection_name);
 		} else {
-			if (provider)
-				priv->desc_string = g_strdup_printf ("%s %s", provider, tech_name);
-			else
-				priv->desc_string = g_strdup_printf (_("Home network (%s)"), tech_name);
+			if (provider) {
+				if (tech_name)
+					priv->desc_string = g_strdup_printf ("%s %s", provider, tech_name);
+				else
+					priv->desc_string = g_strdup_printf ("%s", provider);
+			} else {
+				if (tech_name)
+					priv->desc_string = g_strdup_printf (_("Home network (%s)"), tech_name);
+				else
+					priv->desc_string = g_strdup_printf (_("Home network"));
+			}
 		}
 		break;
 	case MB_STATE_SEARCHING:
@@ -139,36 +141,48 @@ nm_mb_menu_item_new (const char *connection_name,
 		priv->desc_string = g_strdup (_("registration denied"));
 		break;
 	case MB_STATE_ROAMING:
-		if (connection_name)
-			priv->desc_string = g_strdup_printf (_("%s (%s roaming)"), connection_name, tech_name);
-		else {
-			if (provider)
-				priv->desc_string = g_strdup_printf (_("%s (%s roaming)"), provider, tech_name);
+		if (connection_name) {
+			if (tech_name)
+				priv->desc_string = g_strdup_printf (_("%s (%s roaming)"), connection_name, tech_name);
 			else
-				priv->desc_string = g_strdup_printf (_("Roaming network (%s)"), tech_name);
+				priv->desc_string = g_strdup_printf (_("%s (roaming)"), connection_name);
+		} else {
+			if (provider) {
+				if (tech_name)
+					priv->desc_string = g_strdup_printf (_("%s (%s roaming)"), provider, tech_name);
+				else
+					priv->desc_string = g_strdup_printf (_("%s (roaming)"), provider);
+			} else {
+				if (tech_name)
+					priv->desc_string = g_strdup_printf (_("Roaming network (%s)"), tech_name);
+				else
+					priv->desc_string = g_strdup_printf (_("Roaming network"));
+			}
 		}
 		break;
 	}
 
-	/* Assume a connection name means the label should be active */
-	if (connection_name) {
-		char *markup;
-
-		gtk_label_set_use_markup (GTK_LABEL (priv->desc), TRUE);
-		markup = g_markup_printf_escaped ("<b>%s</b>", priv->desc_string);
-		gtk_label_set_markup (GTK_LABEL (priv->desc), markup);
-		g_free (markup);
-		gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
-	} else {
-		gtk_label_set_use_markup (GTK_LABEL (priv->desc), FALSE);
-		gtk_label_set_text (GTK_LABEL (priv->desc), priv->desc_string);
-		gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
-	}
+	if (enabled) {
+		/* Assume a connection name means the label should be active */
+		if (connection_name) {
+			char *markup;
 
-	/* And the strength icon, if we have strength information at all */
-	if (strength) {
-		gtk_image_set_from_pixbuf (GTK_IMAGE (priv->strength),
-		                           mobile_helper_get_quality_icon (strength, applet));
+			gtk_label_set_use_markup (GTK_LABEL (priv->desc), TRUE);
+			markup = g_markup_printf_escaped ("<b>%s</b>", priv->desc_string);
+			gtk_label_set_markup (GTK_LABEL (priv->desc), markup);
+			g_free (markup);
+			gtk_widget_set_sensitive (GTK_WIDGET (item), TRUE);
+		} else {
+			gtk_label_set_use_markup (GTK_LABEL (priv->desc), FALSE);
+			gtk_label_set_text (GTK_LABEL (priv->desc), priv->desc_string);
+			gtk_widget_set_sensitive (GTK_WIDGET (item), FALSE);
+		}
+
+		/* And the strength icon, if we have strength information at all */
+		if (strength) {
+			gtk_image_set_from_pixbuf (GTK_IMAGE (priv->strength),
+			                           mobile_helper_get_quality_icon (strength, applet));
+		}
 	}
 
 	return GTK_WIDGET (item);
diff --git a/src/mb-menu-item.h b/src/mb-menu-item.h
index e479f5e..cba8df4 100644
--- a/src/mb-menu-item.h
+++ b/src/mb-menu-item.h
@@ -51,6 +51,7 @@ GtkWidget *nm_mb_menu_item_new (const char *connection_name,
                                 const char *provider,
                                 guint32 technology,
                                 guint32 state,
+                                gboolean enabled,
                                 NMApplet *applet);
 
 #endif /* _MB_MENU_ITEM_H_ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]