diff options
-rw-r--r-- | introspection/nm-device.xml | 3 | ||||
-rw-r--r-- | src/devices/nm-device.c | 68 | ||||
-rw-r--r-- | src/nm-policy.c | 2 |
3 files changed, 64 insertions, 9 deletions
diff --git a/introspection/nm-device.xml b/introspection/nm-device.xml index 0dca23c37d..0c2a330c00 100644 --- a/introspection/nm-device.xml +++ b/introspection/nm-device.xml @@ -106,7 +106,8 @@ If TRUE, indicates the device is allowed to autoconnect. If FALSE, manual intervention is required before the device will automatically connect to a known network, such as activating a connection using the - device, or setting this property to TRUE. + device, or setting this property to TRUE. This property cannot be + set to TRUE for default-unmanaged devices, since they never autoconnect. </tp:docstring> </property> <property name="FirmwareMissing" type="b" access="read"> diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 87bebdb1eb..4f8e86c07a 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1573,6 +1573,14 @@ nm_device_set_enabled (NMDevice *self, gboolean enabled) NM_DEVICE_GET_CLASS (self)->set_enabled (self, enabled); } +/** + * nm_device_get_autoconnect: + * @self: the #NMDevice + * + * Returns: %TRUE if the device is explicitly blocking all autoconnect + * connections. Does not take into account transient conditions like + * companion devices that may wish to block the device. + */ gboolean nm_device_get_autoconnect (NMDevice *self) { @@ -1581,6 +1589,29 @@ nm_device_get_autoconnect (NMDevice *self) return NM_DEVICE_GET_PRIVATE (self)->autoconnect; } +static void +nm_device_set_autoconnect (NMDevice *self, gboolean autoconnect) +{ + NMDevicePrivate *priv; + + g_return_if_fail (NM_IS_DEVICE (self)); + + priv = NM_DEVICE_GET_PRIVATE (self); + if (priv->autoconnect == autoconnect) + return; + + if (autoconnect) { + /* Default-unmanaged devices never autoconnect */ + if (!nm_device_get_default_unmanaged (self)) { + priv->autoconnect = TRUE; + g_object_notify (G_OBJECT (self), NM_DEVICE_AUTOCONNECT); + } + } else { + priv->autoconnect = FALSE; + g_object_notify (G_OBJECT (self), NM_DEVICE_AUTOCONNECT); + } +} + static gboolean autoconnect_allowed_accumulator (GSignalInvocationHint *ihint, GValue *return_accu, @@ -1591,6 +1622,14 @@ autoconnect_allowed_accumulator (GSignalInvocationHint *ihint, return TRUE; } +/** + * nm_device_autoconnect_allowed: + * @self: the #NMDevice + * + * Returns: %TRUE if the device can be auto-connected immediately, taking + * transient conditions into account (like companion devices that may wish to + * block autoconnect for a time). + */ gboolean nm_device_autoconnect_allowed (NMDevice *self) { @@ -1598,6 +1637,16 @@ nm_device_autoconnect_allowed (NMDevice *self) GValue instance = G_VALUE_INIT; GValue retval = G_VALUE_INIT; + if (priv->state < NM_DEVICE_STATE_DISCONNECTED || !priv->autoconnect) + return FALSE; + + /* The 'autoconnect-allowed' signal is emitted on a device to allow + * other listeners to block autoconnect on the device if they wish. + * This is mainly used by the OLPC Mesh devices to block autoconnect + * on their companion WiFi device as they share radio resources and + * cannot be connected at the same time. + */ + g_value_init (&instance, G_TYPE_OBJECT); g_value_set_object (&instance, self); @@ -1639,8 +1688,9 @@ can_auto_connect (NMDevice *self, * Checks if @connection can be auto-activated on @self right now. * This requires, at a minimum, that the connection be compatible with * @self, and that it have the #NMSettingConnection:autoconnect property - * set. Some devices impose additional requirements. (Eg, a Wi-Fi connection - * can only be activated if its SSID was seen in the last scan.) + * set, and that the device allow auto connections. Some devices impose + * additional requirements. (Eg, a Wi-Fi connection can only be activated + * if its SSID was seen in the last scan.) * * Returns: %TRUE, if the @connection can be auto-activated. **/ @@ -1653,7 +1703,9 @@ nm_device_can_auto_connect (NMDevice *self, g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); g_return_val_if_fail (specific_object && !*specific_object, FALSE); - return NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object); + if (nm_device_autoconnect_allowed (self)) + return NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object); + return FALSE; } static gboolean @@ -5076,7 +5128,7 @@ disconnect_cb (NMDevice *self, dbus_g_method_return_error (context, local); g_error_free (local); } else { - priv->autoconnect = FALSE; + nm_device_set_autoconnect (self, FALSE); nm_device_state_changed (self, NM_DEVICE_STATE_DEACTIVATING, @@ -6856,7 +6908,7 @@ _set_state_full (NMDevice *self, /* Reset autoconnect flag when the device is activating or connected. */ if ( state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_ACTIVATED) - priv->autoconnect = TRUE; + nm_device_set_autoconnect (self, TRUE); g_object_notify (G_OBJECT (self), NM_DEVICE_STATE); g_object_notify (G_OBJECT (self), NM_DEVICE_STATE_REASON); @@ -7412,8 +7464,10 @@ constructed (GObject *object) * since they don't transition from UNMANAGED (and thus the state handler * doesn't run and update them) until something external happens. */ - if (nm_device_get_default_unmanaged (self)) + if (nm_device_get_default_unmanaged (self)) { + nm_device_set_autoconnect (self, FALSE); nm_device_recheck_available_connections (self); + } G_OBJECT_CLASS (nm_device_parent_class)->constructed (object); } @@ -7561,7 +7615,7 @@ set_property (GObject *object, guint prop_id, priv->ip4_address = g_value_get_uint (value); break; case PROP_AUTOCONNECT: - priv->autoconnect = g_value_get_boolean (value); + nm_device_set_autoconnect (self, g_value_get_boolean (value)); break; case PROP_FIRMWARE_MISSING: priv->firmware_missing = g_value_get_boolean (value); diff --git a/src/nm-policy.c b/src/nm-policy.c index ff100d069d..ddb85bd96b 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1658,7 +1658,7 @@ device_autoconnect_changed (NMDevice *device, GParamSpec *pspec, gpointer user_data) { - if (nm_device_get_autoconnect (device)) + if (nm_device_autoconnect_allowed (device)) schedule_activate_check ((NMPolicy *) user_data, device); } |