device: _get_available_connections() with _get_best_connection()
authorLubomir Rintel <lkundrak@v3.sk>
Wed, 23 Mar 2016 09:35:55 +0000 (10:35 +0100)
committerLubomir Rintel <lkundrak@v3.sk>
Sat, 26 Mar 2016 10:29:41 +0000 (11:29 +0100)
We'll need to share the best conneciton logic and it's the only caller
of nm_device_get_available_connections(). Let's just move it all to
NMDevice and provide the best connection from there instead.

src/devices/nm-device.c
src/devices/nm-device.h
src/nm-manager.c

index f18b9c1..583218f 100644 (file)
@@ -9689,39 +9689,55 @@ nm_device_recheck_available_connections (NMDevice *self)
 }
 
 /**
- * nm_device_get_available_connections:
+ * nm_device_get_best_connection:
  * @self: the #NMDevice
  * @specific_object: a specific object path if any
+ * @error: reason why no connection was returned
  *
- * Returns a list of connections available to activate on the device, taking
- * into account any device-specific details given by @specific_object (like
- * WiFi access point path).
+ * Returns a connection that's most suitable for user-initiated activation
+ * of a device, optionally with a given specific object.
  *
- * Returns: caller-owned #GPtrArray of #NMConnections
+ * Returns: the #NMSettingsConnection or %NULL (setting an @error)
  */
-GPtrArray *
-nm_device_get_available_connections (NMDevice *self, const char *specific_object)
+NMSettingsConnection *
+nm_device_get_best_connection (NMDevice *self,
+                               const char *specific_object,
+                               GError **error)
 {
        NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+       NMSettingsConnection *connection = NULL;
+       NMSettingsConnection *candidate;
+       guint64 best_timestamp = 0;
        GHashTableIter iter;
-       guint num_available;
-       NMConnection *connection = NULL;
-       GPtrArray *array = NULL;
 
-       num_available = g_hash_table_size (priv->available_connections);
-       if (num_available > 0) {
-               array = g_ptr_array_sized_new (num_available);
-               g_hash_table_iter_init (&iter, priv->available_connections);
-               while (g_hash_table_iter_next (&iter, (gpointer) &connection, NULL)) {
-                       /* If a specific object is given, only include connections that are
-                        * compatible with it.
-                        */
-                       if (   !specific_object /* << Optimization: we know that the connection is available without @specific_object.  */
-                           || nm_device_check_connection_available (self, connection, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, specific_object))
-                               g_ptr_array_add (array, connection);
+       g_hash_table_iter_init (&iter, priv->available_connections);
+       while (g_hash_table_iter_next (&iter, (gpointer) &candidate, NULL)) {
+               guint64 candidate_timestamp = 0;
+
+               /* If a specific object is given, only include connections that are
+                * compatible with it.
+                */
+               if (    specific_object /* << Optimization: we know that the connection is available without @specific_object.  */
+                   && !nm_device_check_connection_available (self,
+                                                             NM_CONNECTION (candidate),
+                                                             _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST,
+                                                             specific_object))
+                       continue;
+
+               nm_settings_connection_get_timestamp (candidate, &candidate_timestamp);
+               if (!connection || (candidate_timestamp > best_timestamp)) {
+                       connection = candidate;
+                       best_timestamp = candidate_timestamp;
                }
        }
-       return array;
+
+       if (!connection) {
+               g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
+                            "The device '%s' has no connections available for activation.",
+                             nm_device_get_iface (self));
+       }
+
+       return connection;
 }
 
 static void
index 9b9edda..bd657e6 100644 (file)
@@ -529,8 +529,9 @@ gboolean nm_device_add_pending_action    (NMDevice *device, const char *action,
 gboolean nm_device_remove_pending_action (NMDevice *device, const char *action, gboolean assert_is_pending);
 gboolean nm_device_has_pending_action    (NMDevice *device);
 
-GPtrArray *nm_device_get_available_connections (NMDevice *device,
-                                                const char *specific_object);
+NMSettingsConnection *nm_device_get_best_connection (NMDevice *device,
+                                                     const char *specific_object,
+                                                     GError **error);
 
 gboolean   nm_device_check_connection_available (NMDevice *device,
                                                  NMConnection *connection,
index 0ccb987..2490d91 100644 (file)
@@ -3325,11 +3325,15 @@ impl_manager_activate_connection (NMManager *self,
         * regardless of whether that connection is autoconnect-enabled or not
         * (since this is an explicit request, not an auto-activation request).
         */
-       if (!connection_path) {
-               GPtrArray *available;
-               guint64 best_timestamp = 0;
-               guint i;
-
+       if (connection_path) {
+               connection = nm_settings_get_connection_by_path (priv->settings, connection_path);
+               if (!connection) {
+                       error = g_error_new_literal (NM_MANAGER_ERROR,
+                                                    NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
+                                                    "Connection could not be found.");
+                       goto error;
+               }
+       } else {
                /* If no connection is given, find a suitable connection for the given device path */
                if (!device_path) {
                        error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE,
@@ -3343,36 +3347,9 @@ impl_manager_activate_connection (NMManager *self,
                        goto error;
                }
 
-               available = nm_device_get_available_connections (device, specific_object_path);
-               for (i = 0; available && i < available->len; i++) {
-                       NMSettingsConnection *candidate = g_ptr_array_index (available, i);
-                       guint64 candidate_timestamp = 0;
-
-                       nm_settings_connection_get_timestamp (candidate, &candidate_timestamp);
-                       if (!connection_path || (candidate_timestamp > best_timestamp)) {
-                               connection_path = nm_connection_get_path (NM_CONNECTION (candidate));
-                               best_timestamp = candidate_timestamp;
-                       }
-               }
-
-               if (available)
-                       g_ptr_array_free (available, TRUE);
-
-               if (!connection_path) {
-                       error = g_error_new_literal (NM_MANAGER_ERROR,
-                                                    NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
-                                                    "The device has no connections available.");
+               connection = nm_device_get_best_connection (device, specific_object_path, &error);
+               if (!connection)
                        goto error;
-               }
-       }
-
-       g_assert (connection_path);
-       connection = nm_settings_get_connection_by_path (priv->settings, connection_path);
-       if (!connection) {
-               error = g_error_new_literal (NM_MANAGER_ERROR,
-                                            NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
-                                            "Connection could not be found.");
-               goto error;
        }
 
        subject = validate_activation_request (self,