diff options
-rw-r--r-- | clients/cli/connections.c | 121 | ||||
-rw-r--r-- | clients/cli/devices.c | 101 | ||||
-rw-r--r-- | clients/cli/network-manager.c | 7 | ||||
-rw-r--r-- | clients/tui/nmt-editor.c | 49 | ||||
-rw-r--r-- | clients/tui/nmtui-connect.c | 45 | ||||
-rw-r--r-- | clients/tui/nmtui-edit.c | 12 | ||||
-rw-r--r-- | clients/tui/nmtui-hostname.c | 12 | ||||
-rw-r--r-- | examples/C/glib/add-connection-libnm.c | 33 | ||||
-rw-r--r-- | libnm/libnm.ver | 33 | ||||
-rw-r--r-- | libnm/nm-client.c | 308 | ||||
-rw-r--r-- | libnm/nm-client.h | 52 | ||||
-rw-r--r-- | libnm/nm-device-wifi.c | 111 | ||||
-rw-r--r-- | libnm/nm-device-wifi.h | 11 | ||||
-rw-r--r-- | libnm/nm-device.c | 163 | ||||
-rw-r--r-- | libnm/nm-device.h | 18 | ||||
-rw-r--r-- | libnm/nm-remote-connection.c | 368 | ||||
-rw-r--r-- | libnm/nm-remote-connection.h | 83 | ||||
-rw-r--r-- | libnm/nm-remote-settings.c | 236 | ||||
-rw-r--r-- | libnm/nm-remote-settings.h | 44 | ||||
-rw-r--r-- | libnm/tests/test-remote-settings-client.c | 58 | ||||
-rw-r--r-- | libnm/tests/test-secret-agent.c | 111 |
21 files changed, 1169 insertions, 807 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 985336e024..6160b94f36 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -1678,11 +1678,13 @@ active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpoin nmc_terminal_erase_line (); printf (_("Connection successfully activated (D-Bus active path: %s)\n"), nm_object_get_path (NM_OBJECT (active))); + g_object_unref (active); quit (); } else if ( state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED || state == NM_ACTIVE_CONNECTION_STATE_UNKNOWN) { g_string_printf (nmc->return_text, _("Error: Connection activation failed.")); nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; + g_object_unref (active); quit (); } else if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING) { /* activating master connection does not automatically activate any slaves, so their @@ -1726,6 +1728,7 @@ vpn_connection_state_cb (NMVpnConnection *vpn, nmc_terminal_erase_line (); printf (_("VPN connection successfully activated (D-Bus active path: %s)\n"), nm_object_get_path (NM_OBJECT (vpn))); + g_object_unref (vpn); quit (); break; @@ -1734,6 +1737,7 @@ vpn_connection_state_cb (NMVpnConnection *vpn, g_string_printf (nmc->return_text, _("Error: Connection activation failed: %s."), vpn_connection_state_reason_to_string (reason)); nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; + g_object_unref (vpn); quit (); break; @@ -1796,16 +1800,21 @@ typedef struct { } ActivateConnectionInfo; static void -activate_connection_cb (NMClient *client, NMActiveConnection *active, GError *error, gpointer user_data) +activate_connection_cb (GObject *client, GAsyncResult *result, gpointer user_data) { ActivateConnectionInfo *info = (ActivateConnectionInfo *) user_data; NmCli *nmc = info->nmc; NMDevice *device = info->device; + NMActiveConnection *active; NMActiveConnectionState state; const GPtrArray *ac_devs; + GError *error = NULL; + + active = nm_client_activate_connection_finish (NM_CLIENT (client), result, &error); if (error) { g_string_printf (nmc->return_text, _("Error: Connection activation failed: %s"), error->message); + g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; quit (); } else { @@ -1824,6 +1833,7 @@ activate_connection_cb (NMClient *client, NMActiveConnection *active, GError *er printf (_("Connection successfully activated (D-Bus active path: %s)\n"), nm_object_get_path (NM_OBJECT (active))); } + g_object_unref (active); quit (); } else { if (NM_IS_VPN_CONNECTION (active)) { @@ -1860,7 +1870,7 @@ nmc_activate_connection (NmCli *nmc, const char *ifname, const char *ap, const char *nsp, - NMClientActivateFn callback, + GAsyncReadyCallback callback, GError **error) { ActivateConnectionInfo *info; @@ -1899,12 +1909,13 @@ nmc_activate_connection (NmCli *nmc, info->nmc = nmc; info->device = device; - nm_client_activate_connection (nmc->client, - connection, - device, - spec_object, - callback, - info); + nm_client_activate_connection_async (nmc->client, + connection, + device, + spec_object, + NULL, + callback, + info); return TRUE; } @@ -2061,7 +2072,7 @@ do_connection_down (NmCli *nmc, int argc, char **argv) active = find_active_connection (active_cons, nmc->system_connections, selector, *arg_ptr, &idx); if (active) { - nm_client_deactivate_connection (nmc->client, active); + nm_client_deactivate_connection (nmc->client, active, NULL, NULL); } else { g_string_printf (nmc->return_text, _("Error: '%s' is not an active connection."), *arg_ptr); nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND; @@ -4865,23 +4876,28 @@ typedef struct { } AddConnectionInfo; static void -add_connection_cb (NMRemoteSettings *settings, - NMRemoteConnection *connection, - GError *error, +add_connection_cb (GObject *settings, + GAsyncResult *result, gpointer user_data) { AddConnectionInfo *info = (AddConnectionInfo *) user_data; NmCli *nmc = info->nmc; + NMRemoteConnection *connection; + GError *error = NULL; + connection = nm_remote_settings_add_connection_finish (NM_REMOTE_SETTINGS (settings), + result, &error); if (error) { g_string_printf (nmc->return_text, - _("Error: Failed to add '%s' connection: (%d) %s"), - info->con_name, error->code, error->message); + _("Error: Failed to add '%s' connection: %s"), + info->con_name, error->message); + g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; } else { printf (_("Connection '%s' (%s) successfully added.\n"), nm_connection_get_id (NM_CONNECTION (connection)), nm_connection_get_uuid (NM_CONNECTION (connection))); + g_object_unref (connection); } g_free (info->con_name); @@ -4889,23 +4905,25 @@ add_connection_cb (NMRemoteSettings *settings, quit (); } -static gboolean +static void add_new_connection (gboolean persistent, NMRemoteSettings *settings, NMConnection *connection, - NMRemoteSettingsAddConnectionFunc callback, + GAsyncReadyCallback callback, gpointer user_data) { - return nm_remote_settings_add_connection (settings, connection, persistent, callback, user_data); + nm_remote_settings_add_connection_async (settings, connection, persistent, + NULL, callback, user_data); } static void update_connection (gboolean persistent, NMRemoteConnection *connection, - NMRemoteConnectionResultFunc callback, + GAsyncReadyCallback callback, gpointer user_data) { - nm_remote_connection_commit_changes (connection, persistent, callback, user_data); + nm_remote_connection_commit_changes_async (connection, persistent, + NULL, callback, user_data); } static char * @@ -6298,20 +6316,32 @@ set_info_and_signal_editor_thread (GError *error, MonitorACInfo *monitor_ac_info } static void -add_connection_editor_cb (NMRemoteSettings *settings, - NMRemoteConnection *connection, - GError *error, +add_connection_editor_cb (GObject *settings, + GAsyncResult *result, gpointer user_data) { + NMRemoteConnection *connection; + GError *error = NULL; + + connection = nm_remote_settings_add_connection_finish (NM_REMOTE_SETTINGS (settings), + result, &error); set_info_and_signal_editor_thread (error, NULL); + + g_clear_object (&connection); + g_clear_error (&error); } static void -update_connection_editor_cb (NMRemoteConnection *connection, - GError *error, +update_connection_editor_cb (GObject *connection, + GAsyncResult *result, gpointer user_data) { + GError *error = NULL; + + nm_remote_connection_commit_changes_finish (NM_REMOTE_CONNECTION (connection), + result, &error); set_info_and_signal_editor_thread (error, NULL); + g_clear_error (&error); } static gboolean @@ -6355,15 +6385,18 @@ finish: } static void -activate_connection_editor_cb (NMClient *client, - NMActiveConnection *active, - GError *error, +activate_connection_editor_cb (GObject *client, + GAsyncResult *result, gpointer user_data) { ActivateConnectionInfo *info = (ActivateConnectionInfo *) user_data; NMDevice *device = info->device; const GPtrArray *ac_devs; MonitorACInfo *monitor_ac_info = NULL; + NMActiveConnection *active; + GError *error = NULL; + + active = nm_client_activate_connection_finish (NM_CLIENT (client), result, &error); if (!error) { if (!device) { @@ -6373,11 +6406,13 @@ activate_connection_editor_cb (NMClient *client, if (device) { monitor_ac_info = g_malloc0 (sizeof (AddConnectionInfo)); monitor_ac_info->device = g_object_ref (device); - monitor_ac_info->ac = active ? g_object_ref (active) : NULL; + monitor_ac_info->ac = active; monitor_ac_info->monitor_id = g_timeout_add (120, progress_activation_editor_cb, monitor_ac_info); - } + } else + g_object_unref (active); } set_info_and_signal_editor_thread (error, monitor_ac_info); + g_clear_error (&error); } /*----------------------------------------------------------------------------*/ @@ -7888,17 +7923,20 @@ error: static void -modify_connection_cb (NMRemoteConnection *connection, - GError *error, +modify_connection_cb (GObject *connection, + GAsyncResult *result, gpointer user_data) { NmCli *nmc = (NmCli *) user_data; + GError *error = NULL; - if (error) { + if (!nm_remote_connection_commit_changes_finish (NM_REMOTE_CONNECTION (connection), + result, &error)) { g_string_printf (nmc->return_text, - _("Error: Failed to modify connection '%s': (%d) %s"), + _("Error: Failed to modify connection '%s': %s"), nm_connection_get_id (NM_CONNECTION (connection)), - error->code, error->message); + error->message); + g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; } else { if (nmc->print_output == NMC_PRINT_PRETTY) @@ -8100,12 +8138,14 @@ typedef struct { } DeleteStateInfo; static void -delete_cb (NMRemoteConnection *con, GError *err, gpointer user_data) +delete_cb (GObject *con, GAsyncResult *result, gpointer user_data) { DeleteStateInfo *info = (DeleteStateInfo *) user_data; + GError *error = NULL; - if (err) { - g_string_printf (info->nmc->return_text, _("Error: Connection deletion failed: %s"), err->message); + if (!nm_remote_connection_delete_finish (NM_REMOTE_CONNECTION (con), result, &error)) { + g_string_printf (info->nmc->return_text, _("Error: Connection deletion failed: %s"), error->message); + g_error_free (error); info->nmc->return_value = NMC_RESULT_ERROR_CON_DEL; } @@ -8189,7 +8229,8 @@ do_connection_delete (NmCli *nmc, int argc, char **argv) del_info->counter++; /* Delete the connection */ - nm_remote_connection_delete (NM_REMOTE_CONNECTION (connection), delete_cb, del_info); + nm_remote_connection_delete_async (NM_REMOTE_CONNECTION (connection), + NULL, delete_cb, del_info); /* Take next argument (if there's no other connection of the same name) */ if (!pos) @@ -8225,7 +8266,7 @@ do_connection_reload (NmCli *nmc, int argc, char **argv) return nmc->return_value; } - if (!nm_remote_settings_reload_connections (nmc->system_settings, &error)) { + if (!nm_remote_settings_reload_connections (nmc->system_settings, NULL, &error)) { g_string_printf (nmc->return_text, _("Error: %s."), error->message); if (error->code == NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE) nmc->return_value = NMC_RESULT_ERROR_NM_NOT_RUNNING; @@ -8264,7 +8305,7 @@ do_connection_load (NmCli *nmc, int argc, char **argv) filenames[i] = argv[i]; filenames[i] = NULL; - nm_remote_settings_load_connections (nmc->system_settings, filenames, &failures, &error); + nm_remote_settings_load_connections (nmc->system_settings, filenames, &failures, NULL, &error); g_free (filenames); if (error) { g_string_printf (nmc->return_text, _("Error: %s."), error->message); diff --git a/clients/cli/devices.c b/clients/cli/devices.c index 4f908daab1..b20917c719 100644 --- a/clients/cli/devices.c +++ b/clients/cli/devices.c @@ -1287,6 +1287,7 @@ connected_state_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) printf (_("Device '%s' successfully activated with '%s'.\n"), nm_device_get_iface (device), nm_active_connection_get_uuid (active)); + g_object_unref (active); quit (); } } @@ -1323,20 +1324,23 @@ typedef struct { } AddAndActivateInfo; static void -add_and_activate_cb (NMClient *client, - NMActiveConnection *active, - const char *connection_path, - GError *error, +add_and_activate_cb (GObject *client, + GAsyncResult *result, gpointer user_data) { AddAndActivateInfo *info = (AddAndActivateInfo *) user_data; NmCli *nmc = info->nmc; NMDevice *device = info->device; NMActiveConnectionState state; + NMActiveConnection *active; + GError *error = NULL; + + active = nm_client_add_and_activate_connection_finish (NM_CLIENT (client), result, &error); - if (error) { - g_string_printf (nmc->return_text, _("Error: Failed to add/activate new connection: (%d) %s"), - error->code, error->message); + if (error) { + g_string_printf (nmc->return_text, _("Error: Failed to add/activate new connection: %s"), + error->message); + g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; quit (); } else { @@ -1356,6 +1360,7 @@ add_and_activate_cb (NMClient *client, printf (_("Connection with UUID '%s' created and activated on device '%s'\n"), nm_active_connection_get_uuid (active), nm_device_get_iface (device)); } + g_object_unref (active); quit (); } else { g_signal_connect (device, "notify::state", G_CALLBACK (monitor_device_state_cb), nmc); @@ -1363,6 +1368,7 @@ add_and_activate_cb (NMClient *client, if (nmc->print_output == NMC_PRINT_PRETTY) progress_id = g_timeout_add (120, progress_cb, device); + g_object_unref (active); } } @@ -1384,23 +1390,28 @@ create_connect_connection_for_device (AddAndActivateInfo *info) NM_SETTING_CONNECTION_INTERFACE_NAME, nm_device_get_iface (info->device), NULL); - nm_client_add_and_activate_connection (info->nmc->client, - connection, - info->device, - NULL, - add_and_activate_cb, - info); + nm_client_add_and_activate_connection_async (info->nmc->client, + connection, + info->device, + NULL, + NULL, + add_and_activate_cb, + info); } static void -connect_device_cb (NMClient *client, NMActiveConnection *active, GError *error, gpointer user_data) +connect_device_cb (GObject *client, GAsyncResult *result, gpointer user_data) { AddAndActivateInfo *info = (AddAndActivateInfo *) user_data; NmCli *nmc = info->nmc; + NMActiveConnection *active; + GError *error = NULL; const GPtrArray *devices; NMDevice *device; NMDeviceState state; + active = nm_client_activate_connection_finish (NM_CLIENT (client), result, &error); + if (error) { char *dbus_err; @@ -1414,7 +1425,8 @@ connect_device_cb (NMClient *client, NMActiveConnection *active, GError *error, g_free (dbus_err); g_string_printf (nmc->return_text, _("Error: Device activation failed: %s"), - error->message ? error->message : _("(unknown)")); + error->message); + g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION; quit (); } else { @@ -1513,12 +1525,13 @@ do_device_connect (NmCli *nmc, int argc, char **argv) info->nmc = nmc; info->device = device; - nm_client_activate_connection (nmc->client, - NULL, /* let NM find a connection automatically */ - device, - NULL, - connect_device_cb, - info); + nm_client_activate_connection_async (nmc->client, + NULL, /* let NM find a connection automatically */ + device, + NULL, + NULL, + connect_device_cb, + info); /* Start progress indication */ if (nmc->print_output == NMC_PRINT_PRETTY) @@ -1545,16 +1558,19 @@ disconnect_state_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) } static void -disconnect_device_cb (NMDevice *device, GError *error, gpointer user_data) +disconnect_device_cb (GObject *object, GAsyncResult *result, gpointer user_data) { + NMDevice *device = NM_DEVICE (object); NmCli *nmc = (NmCli *) user_data; NMDeviceState state; + GError *error = NULL; - if (error) { + if (!nm_device_disconnect_finish (device, result, &error)) { g_string_printf (nmc->return_text, _("Error: Device '%s' (%s) disconnecting failed: %s"), nm_device_get_iface (device), nm_object_get_path (NM_OBJECT (device)), - error->message ? error->message : _("(unknown)")); + error->message); + g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_DEV_DISCONNECT; quit (); } else { @@ -1637,7 +1653,7 @@ do_device_disconnect (NmCli *nmc, int argc, char **argv) */ nmc->nowait_flag = (nmc->timeout == 0); nmc->should_wait = TRUE; - nm_device_disconnect (device, disconnect_device_cb, nmc); + nm_device_disconnect_async (device, NULL, disconnect_device_cb, nmc); /* Start progress indication */ if (nmc->print_output == NMC_PRINT_PRETTY) @@ -1648,15 +1664,18 @@ error: } static void -delete_device_cb (NMDevice *device, GError *error, gpointer user_data) +delete_device_cb (GObject *object, GAsyncResult *result, gpointer user_data) { + NMDevice *device = NM_DEVICE (object); NmCli *nmc = (NmCli *) user_data; + GError *error = NULL; - if (error) { + if (!nm_device_delete_finish (device, result, &error)) { g_string_printf (nmc->return_text, _("Error: Device '%s' (%s) deletion failed: %s"), nm_device_get_iface (device), nm_object_get_path (NM_OBJECT (device)), - error->message ? error->message : _("(unknown)")); + error->message); + g_error_free (error); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; } quit (); @@ -1727,7 +1746,7 @@ do_device_delete (NmCli *nmc, int argc, char **argv) */ nmc->nowait_flag = (nmc->timeout == 0); nmc->should_wait = TRUE; - nm_device_delete (device, delete_device_cb, nmc); + nm_device_delete_async (device, NULL, delete_device_cb, nmc); /* Start progress indication */ if (nmc->print_output == NMC_PRINT_PRETTY) @@ -2308,12 +2327,13 @@ do_device_wifi_connect_network (NmCli *nmc, int argc, char **argv) info->nmc = nmc; info->device = device; - nm_client_add_and_activate_connection (nmc->client, - connection, - device, - nm_object_get_path (NM_OBJECT (ap)), - add_and_activate_cb, - info); + nm_client_add_and_activate_connection_async (nmc->client, + connection, + device, + nm_object_get_path (NM_OBJECT (ap)), + NULL, + add_and_activate_cb, + info); error: if (bssid1_arr) @@ -2327,14 +2347,16 @@ error: } static void -request_rescan_cb (NMDeviceWifi *device, GError *error, gpointer user_data) +request_rescan_cb (GObject *object, GAsyncResult *result, gpointer user_data) { NmCli *nmc = (NmCli *) user_data; + GError *error = NULL; + nm_device_wifi_request_scan_finish (NM_DEVICE_WIFI (object), result, &error); if (error) { - g_string_printf (nmc->return_text, _("Error: %s."), - error->message ? error->message : _("unknown")); + g_string_printf (nmc->return_text, _("Error: %s."), error->message); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + g_error_free (error); } quit (); } @@ -2375,7 +2397,8 @@ do_device_wifi_rescan (NmCli *nmc, int argc, char **argv) goto error; } - nm_device_wifi_request_scan_simple (NM_DEVICE_WIFI (device), request_rescan_cb, nmc); + nm_device_wifi_request_scan_async (NM_DEVICE_WIFI (device), NULL, + request_rescan_cb, nmc); return nmc->return_value; error: diff --git a/clients/cli/network-manager.c b/clients/cli/network-manager.c index d4841ebc43..f65b51a82c 100644 --- a/clients/cli/network-manager.c +++ b/clients/cli/network-manager.c @@ -550,14 +550,17 @@ show_general_logging (NmCli *nmc) } static void -save_hostname_cb (NMRemoteSettings *settings, GError *error, gpointer user_data) +save_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data) { NmCli *nmc = (NmCli *) user_data; + GError *error = NULL; + nm_remote_settings_save_hostname_finish (NM_REMOTE_SETTINGS (object), result, &error); if (error) { g_string_printf (nmc->return_text, _("Error: failed to set hostname: (%d) %s"), error->code, error->message); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + g_error_free (error); } quit (); } @@ -627,7 +630,7 @@ do_general (NmCli *nmc, int argc, char **argv) printf ("Warning: ignoring extra garbage after '%s' hostname\n", hostname); nmc->should_wait = TRUE; - nm_remote_settings_save_hostname (rem_settings, hostname, save_hostname_cb, nmc); + nm_remote_settings_save_hostname_async (rem_settings, hostname, NULL, save_hostname_cb, nmc); } } else if (matches (*argv, "permissions") == 0) { diff --git a/clients/tui/nmt-editor.c b/clients/tui/nmt-editor.c index 46710efeae..93e36d7919 100644 --- a/clients/tui/nmt-editor.c +++ b/clients/tui/nmt-editor.c @@ -103,20 +103,30 @@ nmt_editor_init (NmtEditor *entry) } static void -connection_updated (NMRemoteConnection *connection, - GError *error, - gpointer op) +connection_updated (GObject *connection, + GAsyncResult *result, + gpointer op) { + GError *error = NULL; + + nm_remote_connection_commit_changes_finish (NM_REMOTE_CONNECTION (connection), result, &error); nmt_sync_op_complete_boolean (op, error == NULL, error); + g_clear_error (&error); } static void -connection_added (NMRemoteSettings *settings, - NMRemoteConnection *connection, - GError *error, - gpointer op) +connection_added (GObject *settings, + GAsyncResult *result, + gpointer op) { + NMRemoteConnection *connection; + GError *error = NULL; + + connection = nm_remote_settings_add_connection_finish (NM_REMOTE_SETTINGS (settings), + result, &error); nmt_sync_op_complete_boolean (op, error == NULL, error); + g_clear_object (&connection); + g_clear_error (&error); } static void @@ -133,8 +143,8 @@ save_connection_and_exit (NmtNewtButton *button, nmt_sync_op_init (&op); if (NM_IS_REMOTE_CONNECTION (priv->orig_connection)) { - nm_remote_connection_commit_changes (NM_REMOTE_CONNECTION (priv->orig_connection), TRUE, - connection_updated, &op); + nm_remote_connection_commit_changes_async (NM_REMOTE_CONNECTION (priv->orig_connection), + TRUE, NULL, connection_updated, &op); if (!nmt_sync_op_wait_boolean (&op, &error)) { nmt_newt_message_dialog (_("Unable to save connection: %s"), error->message); @@ -147,8 +157,8 @@ save_connection_and_exit (NmtNewtButton *button, */ nm_connection_clear_secrets (priv->orig_connection); } else { - nm_remote_settings_add_connection (nm_settings, priv->orig_connection, TRUE, - connection_added, &op); + nm_remote_settings_add_connection_async (nm_settings, priv->orig_connection, TRUE, + NULL, connection_added, &op); if (!nmt_sync_op_wait_boolean (&op, &error)) { nmt_newt_message_dialog (_("Unable to add new connection: %s"), error->message); @@ -161,14 +171,19 @@ save_connection_and_exit (NmtNewtButton *button, } static void -got_secrets (NMRemoteConnection *connection, - GVariant *secrets, - GError *error, - gpointer op) +got_secrets (GObject *object, + GAsyncResult *result, + gpointer op) { + GVariant *secrets; + GError *error = NULL; + + secrets = nm_remote_connection_get_secrets_finish (NM_REMOTE_CONNECTION (object), + result, &error); if (secrets) g_variant_ref (secrets); nmt_sync_op_complete_pointer (op, secrets, error); + g_clear_error (&error); } static NMConnection * @@ -189,8 +204,8 @@ build_edit_connection (NMConnection *orig_connection) g_variant_iter_init (&iter, settings); while (g_variant_iter_next (&iter, "{&s@a{sv}}", &setting_name, NULL)) { nmt_sync_op_init (&op); - nm_remote_connection_get_secrets (NM_REMOTE_CONNECTION (orig_connection), - setting_name, got_secrets, &op); + nm_remote_connection_get_secrets_async (NM_REMOTE_CONNECTION (orig_connection), + setting_name, NULL, got_secrets, &op); /* FIXME: error handling */ secrets = nmt_sync_op_wait_pointer (&op, NULL); if (secrets) { diff --git a/clients/tui/nmtui-connect.c b/clients/tui/nmtui-connect.c index 309d485e6e..7e04657aff 100644 --- a/clients/tui/nmtui-connect.c +++ b/clients/tui/nmtui-connect.c @@ -95,28 +95,35 @@ activate_ac_state_changed (GObject *object, } static void -activate_callback (NMClient *client, - NMActiveConnection *ac, - GError *error, - gpointer user_data) +activate_callback (GObject *client, + GAsyncResult *result, + gpointer user_data) { NmtSyncOp *op = user_data; + NMActiveConnection *ac; + GError *error = NULL; + ac = nm_client_activate_connection_finish (NM_CLIENT (client), result, &error); if (error) nmt_sync_op_complete_pointer (op, NULL, error); else - nmt_sync_op_complete_pointer (op, g_object_ref (ac), NULL); + nmt_sync_op_complete_pointer (op, ac, NULL); } static void -add_and_activate_callback (NMClient *client, - NMActiveConnection *ac, - const char *new_connection_path, - GError *error, - gpointer user_data) +add_and_activate_callback (GObject *client, + GAsyncResult *result, + gpointer user_data) { - /* We don't care about @new_connection_path, so... */ - activate_callback (client, ac, error, user_data); + NmtSyncOp *op = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_client_add_and_activate_connection_finish (NM_CLIENT (client), result, &error); + if (error) + nmt_sync_op_complete_pointer (op, NULL, error); + else + nmt_sync_op_complete_pointer (op, ac, NULL); } static void @@ -151,13 +158,13 @@ activate_connection (NMConnection *connection, nmt_sync_op_init (&op); if (connection) { - nm_client_activate_connection (nm_client, - connection, device, specific_object_path, - activate_callback, &op); + nm_client_activate_connection_async (nm_client, + connection, device, specific_object_path, + NULL, activate_callback, &op); } else { - nm_client_add_and_activate_connection (nm_client, - NULL, device, specific_object_path, - add_and_activate_callback, &op); + nm_client_add_and_activate_connection_async (nm_client, + NULL, device, specific_object_path, + NULL, add_and_activate_callback, &op); } nmt_newt_form_show (form); @@ -221,7 +228,7 @@ listbox_activated (NmtNewtListbox *listbox, return; if (ac) - nm_client_deactivate_connection (nm_client, ac); + nm_client_deactivate_connection (nm_client, ac, NULL, NULL); else activate_connection (connection, device, specific_object); } diff --git a/clients/tui/nmtui-edit.c b/clients/tui/nmtui-edit.c index 1757ff4961..7065cbe4c3 100644 --- a/clients/tui/nmtui-edit.c +++ b/clients/tui/nmtui-edit.c @@ -430,13 +430,14 @@ typedef struct { } ConnectionDeleteData; static void -connection_deleted_callback (NMRemoteConnection *connection, - GError *error, - gpointer user_data) +connection_deleted_callback (GObject *connection, + GAsyncResult *result, + gpointer user_data) { ConnectionDeleteData *data = user_data; + GError *error = NULL; - if (error) { + if (!nm_remote_connection_delete_finish (data->connection, result, NULL)) { nmt_newt_message_dialog (_("Unable to delete connection: %s"), error->message); } else @@ -444,6 +445,7 @@ connection_deleted_callback (NMRemoteConnection *connection, if (error || (data->got_callback && data->got_signal)) nmt_sync_op_complete_boolean (&data->op, error == NULL, error); + g_clear_error (&error); } static void @@ -480,7 +482,7 @@ nmt_remove_connection (NMRemoteConnection *connection) data.connection = connection; g_signal_connect (nm_settings, NM_REMOTE_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed_signal), &data); - nm_remote_connection_delete (connection, connection_deleted_callback, &data); + nm_remote_connection_delete_async (connection, NULL, connection_deleted_callback, &data); if (!nmt_sync_op_wait_boolean (&data.op, &error)) { nmt_newt_message_dialog (_("Could not delete connection: %s"), diff --git a/clients/tui/nmtui-hostname.c b/clients/tui/nmtui-hostname.c index 7c8aff3a85..92e493d92b 100644 --- a/clients/tui/nmtui-hostname.c +++ b/clients/tui/nmtui-hostname.c @@ -86,11 +86,15 @@ nmtui_hostname_run_dialog (void) } static void -hostname_set (NMRemoteSettings *settings, - GError *error, - gpointer op) +hostname_set (GObject *object, + GAsyncResult *result, + gpointer op) { + GError *error = NULL; + + nm_remote_settings_save_hostname_finish (NM_REMOTE_SETTINGS (object), result, &error); nmt_sync_op_complete_boolean (op, error == NULL, error); + g_clear_error (&error); } NmtNewtForm * @@ -108,7 +112,7 @@ nmtui_hostname (int argc, char **argv) if (hostname) { nmt_sync_op_init (&op); - nm_remote_settings_save_hostname (nm_settings, hostname, hostname_set, &op); + nm_remote_settings_save_hostname_async (nm_settings, hostname, NULL, hostname_set, &op); if (nmt_sync_op_wait_boolean (&op, &error)) { /* Translators: this indicates the result. ie, "I have set the hostname to ..." */ nmt_newt_message_dialog (_("Set hostname to '%s'"), hostname); diff --git a/examples/C/glib/add-connection-libnm.c b/examples/C/glib/add-connection-libnm.c index 59632955b8..c680f420ff 100644 --- a/examples/C/glib/add-connection-libnm.c +++ b/examples/C/glib/add-connection-libnm.c @@ -31,27 +31,33 @@ #include <NetworkManager.h> static void -added_cb (NMRemoteSettings *settings, - NMRemoteConnection *remote, - GError *error, +added_cb (GObject *settings, + GAsyncResult *result, gpointer user_data) { GMainLoop *loop = user_data; + NMRemoteConnection *remote; + GError *error; /* NM responded to our request; either handle the resulting error or * print out the object path of the connection we just added. */ + remote = nm_remote_settings_add_connection_finish (NM_REMOTE_SETTINGS (settings), + result, &error); - if (error) + if (error) { g_print ("Error adding connection: %s", error->message); - else + g_error_free (error); + } else { g_print ("Added: %s\n", nm_connection_get_path (NM_CONNECTION (remote))); + g_object_unref (remote); + } /* Tell the mainloop we're done and we can quit now */ g_main_loop_quit (loop); } -static gboolean +static void add_connection (NMRemoteSettings *settings, GMainLoop *loop, const char *con_name) { NMConnection *connection; @@ -59,7 +65,6 @@ add_connection (NMRemoteSettings *settings, GMainLoop *loop, const char *con_nam NMSettingWired *s_wired; NMSettingIP4Config *s_ip4; char *uuid; - gboolean success; /* Create a new connection object */ connection = nm_simple_connection_new (); @@ -89,12 +94,8 @@ add_connection (NMRemoteSettings *settings, GMainLoop *loop, const char *con_nam /* Ask the settings service to add the new connection; we'll quit the * mainloop and exit when the callback is called. */ - success = nm_remote_settings_add_connection (settings, connection, TRUE, added_cb, loop); - if (!success) - g_print ("Error adding connection\n"); - + nm_remote_settings_add_connection_async (settings, connection, TRUE, NULL, added_cb, loop); g_object_unref (connection); - return success; } @@ -121,11 +122,9 @@ main (int argc, char *argv[]) } /* Ask the settings service to add the new connection */ - if (add_connection (settings, loop, "__Test connection__")) { - /* Wait for the connection to be added */ - g_main_loop_run (loop); - } else - g_print ("Error adding connection to NetworkManager\n"); + add_connection (settings, loop, "__Test connection__"); + /* Wait for the connection to be added */ + g_main_loop_run (loop); /* Clean up */ g_object_unref (settings); diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 3fe542932e..36a6d09a33 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -33,8 +33,10 @@ global: nm_active_connection_get_vpn; nm_active_connection_state_get_type; nm_bluetooth_capabilities_get_type; - nm_client_activate_connection; - nm_client_add_and_activate_connection; + nm_client_activate_connection_async; + nm_client_activate_connection_finish; + nm_client_add_and_activate_connection_async; + nm_client_add_and_activate_connection_finish; nm_client_check_connectivity; nm_client_check_connectivity_async; nm_client_check_connectivity_finish; @@ -155,9 +157,11 @@ global: nm_device_capabilities_get_type; nm_device_connection_compatible; nm_device_connection_valid; - nm_device_delete; + nm_device_delete_async; + nm_device_delete_finish; nm_device_disambiguate_names; - nm_device_disconnect; + nm_device_disconnect_async; + nm_device_disconnect_finish; nm_device_error_get_type; nm_device_error_quark; nm_device_ethernet_error_get_type; @@ -246,7 +250,8 @@ global: nm_device_wifi_get_mode; nm_device_wifi_get_permanent_hw_address; nm_device_wifi_get_type; - nm_device_wifi_request_scan_simple; + nm_device_wifi_request_scan_async; + nm_device_wifi_request_scan_finish; nm_device_wimax_error_get_type; nm_device_wimax_error_quark; nm_device_wimax_get_active_nsp; @@ -336,16 +341,21 @@ global: nm_object_error_quark; nm_object_get_path; nm_object_get_type; - nm_remote_connection_commit_changes; - nm_remote_connection_delete; + nm_remote_connection_commit_changes_async; + nm_remote_connection_commit_changes_finish; + nm_remote_connection_delete_async; + nm_remote_connection_delete_finish; nm_remote_connection_error_get_type; nm_remote_connection_error_quark; - nm_remote_connection_get_secrets; + nm_remote_connection_get_secrets_async; + nm_remote_connection_get_secrets_finish; nm_remote_connection_get_type; nm_remote_connection_get_unsaved; nm_remote_connection_get_visible; - nm_remote_connection_save; - nm_remote_settings_add_connection; + nm_remote_connection_save_async; + nm_remote_connection_save_finish; + nm_remote_settings_add_connection_async; + nm_remote_settings_add_connection_finish; nm_remote_settings_error_get_type; nm_remote_settings_error_quark; nm_remote_settings_get_connection_by_id; @@ -358,7 +368,8 @@ global: nm_remote_settings_new_async; nm_remote_settings_new_finish; nm_remote_settings_reload_connections; - nm_remote_settings_save_hostname; + nm_remote_settings_save_hostname_async; + nm_remote_settings_save_hostname_finish; nm_secret_agent_capabilities_get_type; nm_secret_agent_delete_secrets; nm_secret_agent_error_get_type; diff --git a/libnm/nm-client.c b/libnm/nm-client.c index 54eacab12f..3f24433cd9 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -473,44 +473,37 @@ nm_client_get_device_by_iface (NMClient *client, const char *iface) typedef struct { NMClient *client; - NMClientActivateFn act_fn; - NMClientAddActivateFn add_act_fn; + GSimpleAsyncResult *simple; + GCancellable *cancellable; + gulong cancelled_id; char *active_path; char *new_connection_path; - guint idle_id; - gpointer user_data; } ActivateInfo; static void -activate_info_free (ActivateInfo *info) -{ - if (info->idle_id) - g_source_remove (info->idle_id); - g_free (info->active_path); - g_free (info->new_connection_path); - memset (info, 0, sizeof (*info)); - g_slice_free (ActivateInfo, info); -} - -static void activate_info_complete (ActivateInfo *info, NMActiveConnection *active, GError *error) { NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (info->client); - if (info->act_fn) - info->act_fn (info->client, error ? NULL : active, error, info->user_data); - else if (info->add_act_fn) { - info->add_act_fn (info->client, - error ? NULL : active, - error ? NULL : info->new_connection_path, - error, - info->user_data); - } else if (error) - g_warning ("Device activation failed: (%d) %s", error->code, error->message); + if (active) + g_simple_async_result_set_op_res_gpointer (info->simple, g_object_ref (active), g_object_unref); + else + g_simple_async_result_set_from_error (info->simple, error); + g_simple_async_result_complete (info->simple); priv->pending_activations = g_slist_remove (priv->pending_activations, info); + + g_free (info->active_path); + g_free (info->new_connection_path); + g_object_unref (info->simple); + if (info->cancellable) { + if (info->cancelled_id) + g_signal_handler_disconnect (info->cancellable, info->cancelled_id); + g_object_unref (info->cancellable); + } + g_slice_free (ActivateInfo, info); } static void @@ -552,7 +545,6 @@ recheck_pending_activations (NMClient *self, const char *failed_path, GError *er if (g_strcmp0 (info->active_path, active_path) == 0) { /* Call the pending activation's callback and it all up */ activate_info_complete (info, active, NULL); - activate_info_free (info); break; } } @@ -564,11 +556,24 @@ recheck_pending_activations (NMClient *self, const char *failed_path, GError *er * callback gets called. */ activate_info_complete (ainfo, NULL, error); - activate_info_free (ainfo); } } static void +activation_cancelled (GCancellable *cancellable, + gpointer user_data) +{ + ActivateInfo *info = user_data; + GError *error = NULL; + + if (!g_cancellable_set_error_if_cancelled (cancellable, &error)) + return; + + activate_info_complete (info, NULL, error); + g_clear_error (&error); +} + +static void activate_cb (GObject *object, GAsyncResult *result, gpointer user_data) @@ -579,33 +584,20 @@ activate_cb (GObject *object, if (nmdbus_manager_call_activate_connection_finish (NMDBUS_MANAGER (object), &info->active_path, result, &error)) { + if (info->cancellable) { + info->cancelled_id = g_signal_connect (info->cancellable, "cancelled", + G_CALLBACK (activation_cancelled), info); + } + recheck_pending_activations (info->client, NULL, NULL); } else { activate_info_complete (info, NULL, error); - activate_info_free (info); g_clear_error (&error); } } -static gboolean -activate_nm_not_running (gpointer user_data) -{ - ActivateInfo *info = user_data; - GError *error; - - info->idle_id = 0; - - error = g_error_new_literal (NM_CLIENT_ERROR, - NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, - "NetworkManager is not running"); - activate_info_complete (info, NULL, error); - activate_info_free (info); - g_clear_error (&error); - return FALSE; -} - /** - * nm_client_activate_connection: + * nm_client_activate_connection_async: * @client: a #NMClient * @connection: (allow-none): an #NMConnection * @device: (allow-none): the #NMDevice @@ -616,27 +608,34 @@ activate_nm_not_running (gpointer user_data) * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can * get using nm_object_get_path(), and which will be used to complete the * details of the newly added connection. - * @callback: (scope async) (allow-none): the function to call when the call is done - * @user_data: (closure): user data to pass to the callback function - * - * Starts a connection to a particular network using the configuration settings - * from @connection and the network device @device. Certain connection types - * also take a "specific object" which is the object path of a connection- - * specific object, like an #NMAccessPoint for Wi-Fi connections, or an - * #NMWimaxNsp for WiMAX connections, to which you wish to connect. If the - * specific object is not given, NetworkManager can, in some cases, automatically - * determine which network to connect to given the settings in @connection. + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the activation has started + * @user_data: caller-specific data passed to @callback + * + * Asynchronously starts a connection to a particular network using the + * configuration settings from @connection and the network device @device. + * Certain connection types also take a "specific object" which is the object + * path of a connection- specific object, like an #NMAccessPoint for Wi-Fi + * connections, or an #NMWimaxNsp for WiMAX connections, to which you wish to + * connect. If the specific object is not given, NetworkManager can, in some + * cases, automatically determine which network to connect to given the settings + * in @connection. * * If @connection is not given for a device-based activation, NetworkManager * picks the best available connection for the device and activates it. + * + * Note that the callback is invoked when NetworkManager has started activating + * the new connection, not when it finishes. You can used the returned + * #NMActiveConnection object to track the activation to its completion. **/ void -nm_client_activate_connection (NMClient *client, - NMConnection *connection, - NMDevice *device, - const char *specific_object, - NMClientActivateFn callback, - gpointer user_data) +nm_client_activate_connection_async (NMClient *client, + NMConnection *connection, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { NMClientPrivate *priv; ActivateInfo *info; @@ -647,27 +646,58 @@ nm_client_activate_connection (NMClient *client, if (connection) g_return_if_fail (NM_IS_CONNECTION (connection)); + if (!nm_client_get_nm_running (client)) { + g_simple_async_report_error_in_idle (G_OBJECT (client), callback, user_data, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); + return; + } + info = g_slice_new0 (ActivateInfo); - info->act_fn = callback; - info->user_data = user_data; info->client = client; + info->simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_activate_connection_async); + info->cancellable = cancellable ? g_object_ref (cancellable) : NULL; priv = NM_CLIENT_GET_PRIVATE (client); priv->pending_activations = g_slist_prepend (priv->pending_activations, info); - if (!nm_client_get_nm_running (client)) { - info->idle_id = g_idle_add (activate_nm_not_running, info); - return; - } - nmdbus_manager_call_activate_connection (priv->manager_proxy, connection ? nm_connection_get_path (connection) : "/", device ? nm_object_get_path (NM_OBJECT (device)) : "/", specific_object ? specific_object : "/", - NULL, + cancellable, activate_cb, info); } +/** + * nm_client_activate_connection_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_activate_connection_async(). + * + * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMActiveConnection * +nm_client_activate_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), nm_client_activate_connection_async), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + static void add_activate_cb (GObject *object, GAsyncResult *result, @@ -677,19 +707,23 @@ add_activate_cb (GObject *object, GError *error = NULL; if (nmdbus_manager_call_add_and_activate_connection_finish (NMDBUS_MANAGER (object), - &info->new_connection_path, + NULL, &info->active_path, result, &error)) { + if (info->cancellable) { + info->cancelled_id = g_signal_connect (info->cancellable, "cancelled", + G_CALLBACK (activation_cancelled), info); + } + recheck_pending_activations (info->client, NULL, NULL); } else { activate_info_complete (info, NULL, error); - activate_info_free (info); g_clear_error (&error); } } /** - * nm_client_add_and_activate_connection: + * nm_client_add_and_activate_connection_async: * @client: a #NMClient * @partial: (allow-none): an #NMConnection to add; the connection may be * partially filled (or even %NULL) and will be completed by NetworkManager @@ -702,51 +736,96 @@ add_activate_cb (GObject *object, * path of a #NMAccessPoint or #NMWimaxNsp owned by @device, which you can * get using nm_object_get_path(), and which will be used to complete the * details of the newly added connection. - * @callback: (scope async) (allow-none): the function to call when the call is done - * @user_data: (closure): user data to pass to the callback function + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the activation has started + * @user_data: caller-specific data passed to @callback * * Adds a new connection using the given details (if any) as a template, - * automatically filling in missing settings with the capabilities of the - * given device and specific object. The new connection is then activated. - * Cannot be used for VPN connections at this time. + * automatically filling in missing settings with the capabilities of the given + * device and specific object. The new connection is then asynchronously + * activated as with nm_client_activate_connection_async(). Cannot be used for + * VPN connections at this time. + * + * Note that the callback is invoked when NetworkManager has started activating + * the new connection, not when it finishes. You can used the returned + * #NMActiveConnection object to track the activation to its completion. **/ void -nm_client_add_and_activate_connection (NMClient *client, - NMConnection *partial, - NMDevice *device, - const char *specific_object, - NMClientAddActivateFn callback, - gpointer user_data) +nm_client_add_and_activate_connection_async (NMClient *client, + NMConnection *partial, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { NMClientPrivate *priv; - ActivateInfo *info; GVariant *dict = NULL; + ActivateInfo *info; g_return_if_fail (NM_IS_CLIENT (client)); g_return_if_fail (NM_IS_DEVICE (device)); + if (partial) + g_return_if_fail (NM_IS_CONNECTION (partial)); + + if (!nm_client_get_nm_running (client)) { + g_simple_async_report_error_in_idle (G_OBJECT (client), callback, user_data, + NM_CLIENT_ERROR, + NM_CLIENT_ERROR_MANAGER_NOT_RUNNING, + "NetworkManager is not running"); + return; + } info = g_slice_new0 (ActivateInfo); - info->add_act_fn = callback; - info->user_data = user_data; info->client = client; + info->simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data, + nm_client_add_and_activate_connection_async); + info->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + + priv = NM_CLIENT_GET_PRIVATE (client); + priv->pending_activations = g_slist_prepend (priv->pending_activations, info); if (partial) dict = nm_connection_to_dbus (partial, NM_CONNECTION_SERIALIZE_ALL); if (!dict) dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); - priv = NM_CLIENT_GET_PRIVATE (client); - priv->pending_activations = g_slist_prepend (priv->pending_activations, info); + nmdbus_manager_call_add_and_activate_connection (priv->manager_proxy, + dict, + nm_object_get_path (NM_OBJECT (device)), + specific_object ? specific_object : "/", + cancellable, + add_activate_cb, info); +} - if (nm_client_get_nm_running (client)) { - nmdbus_manager_call_add_and_activate_connection (priv->manager_proxy, - dict, - nm_object_get_path (NM_OBJECT (device)), - specific_object ? specific_object : "/", - NULL, - add_activate_cb, info); - } else - info->idle_id = g_idle_add (activate_nm_not_running, info); +/** + * nm_client_add_and_activate_connection_finish: + * @client: an #NMClient + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_client_add_and_activate_connection_async(). + * + * You can call nm_active_connection_get_connection() on the returned + * #NMActiveConnection to find the path of the created #NMConnection. + * + * Returns: (transfer full): the new #NMActiveConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMActiveConnection * +nm_client_add_and_activate_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), nm_client_add_and_activate_connection_async), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); } static void @@ -766,30 +845,33 @@ object_creation_failed_cb (GObject *object, GError *error, char *failed_path) * nm_client_deactivate_connection: * @client: a #NMClient * @active: the #NMActiveConnection to deactivate + * @cancellable: a #GCancellable, or %NULL + * @error: location for a #GError, or %NULL * * Deactivates an active #NMActiveConnection. + * + * Returns: success or failure **/ -void -nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active) +gboolean +nm_client_deactivate_connection (NMClient *client, + NMActiveConnection *active, + GCancellable *cancellable, + GError **error) { NMClientPrivate *priv; const char *path; - GError *error = NULL; - g_return_if_fail (NM_IS_CLIENT (client)); - g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active)); + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE); priv = NM_CLIENT_GET_PRIVATE (client); if (!nm_client_get_nm_running (client)) - return; + return TRUE; path = nm_object_get_path (NM_OBJECT (active)); - if (!nmdbus_manager_call_deactivate_connection_sync (priv->manager_proxy, - path, - NULL, &error)) { - g_warning ("Could not deactivate connection '%s': %s", path, error->message); - g_error_free (error); - } + return nmdbus_manager_call_deactivate_connection_sync (priv->manager_proxy, + path, + cancellable, error); } /** @@ -1765,8 +1847,10 @@ dispose (GObject *object) g_clear_object (&priv->primary_connection); g_clear_object (&priv->activating_connection); - g_slist_free_full (priv->pending_activations, (GDestroyNotify) activate_info_free); - priv->pending_activations = NULL; + /* Each activation should hold a ref on @client, so if we're being disposed, + * there shouldn't be any pending. + */ + g_warn_if_fail (priv->pending_activations == NULL); g_hash_table_destroy (priv->permissions); priv->permissions = NULL; diff --git a/libnm/nm-client.h b/libnm/nm-client.h index 1073553275..2c9de43677 100644 --- a/libnm/nm-client.h +++ b/libnm/nm-client.h @@ -176,32 +176,32 @@ const GPtrArray *nm_client_get_devices (NMClient *client); NMDevice *nm_client_get_device_by_path (NMClient *client, const char *object_path); NMDevice *nm_client_get_device_by_iface (NMClient *client, const char *iface); -typedef void (*NMClientActivateFn) (NMClient *client, - NMActiveConnection *active_connection, - GError *error, - gpointer user_data); - -void nm_client_activate_connection (NMClient *client, - NMConnection *connection, - NMDevice *device, - const char *specific_object, - NMClientActivateFn callback, - gpointer user_data); - -typedef void (*NMClientAddActivateFn) (NMClient *client, - NMActiveConnection *connection, - const char *new_connection_path, - GError *error, - gpointer user_data); - -void nm_client_add_and_activate_connection (NMClient *client, - NMConnection *partial, - NMDevice *device, - const char *specific_object, - NMClientAddActivateFn callback, - gpointer user_data); - -void nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active); +void nm_client_activate_connection_async (NMClient *client, + NMConnection *connection, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMActiveConnection *nm_client_activate_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +void nm_client_add_and_activate_connection_async (NMClient *client, + NMConnection *partial, + NMDevice *device, + const char *specific_object, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMActiveConnection *nm_client_add_and_activate_connection_finish (NMClient *client, + GAsyncResult *result, + GError **error); + +gboolean nm_client_deactivate_connection (NMClient *client, + NMActiveConnection *active, + GCancellable *cancellable, + GError **error); gboolean nm_client_networking_get_enabled (NMClient *client); void nm_client_networking_set_enabled (NMClient *client, gboolean enabled); diff --git a/libnm/nm-device-wifi.c b/libnm/nm-device-wifi.c index 677eeebdf9..0edede58fc 100644 --- a/libnm/nm-device-wifi.c +++ b/libnm/nm-device-wifi.c @@ -47,9 +47,7 @@ static void state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user typedef struct { NMDeviceWifi *device; - GCancellable *cancellable; - NMDeviceWifiRequestScanFn callback; - gpointer user_data; + GSimpleAsyncResult *simple; } RequestScanInfo; typedef struct { @@ -293,59 +291,91 @@ request_scan_cb (GObject *source, gpointer user_data) { RequestScanInfo *info = user_data; + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (info->device); + GError *error = NULL; - if (info->callback) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (info->device); - GError *error = NULL; - - nmdbus_device_wifi_call_request_scan_finish (NMDBUS_DEVICE_WIFI (source), - result, &error); - - info->callback (info->device, error, info->user_data); + priv->scan_info = NULL; - g_clear_error (&error); - priv->scan_info = NULL; - } + if (nmdbus_device_wifi_call_request_scan_finish (NMDBUS_DEVICE_WIFI (source), + result, &error)) + g_simple_async_result_set_op_res_gboolean (info->simple, TRUE); + else + g_simple_async_result_take_error (info->simple, error); - g_clear_object (&info->cancellable); + g_simple_async_result_complete (info->simple); + g_object_unref (info->simple); g_slice_free (RequestScanInfo, info); } /** - * nm_device_wifi_request_scan_simple: + * nm_device_wifi_request_scan_async: * @device: a #NMDeviceWifi - * @callback: (scope async) (allow-none): the function to call when the call is done - * @user_data: (closure): user data to pass to the callback function + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the scan has been requested + * @user_data: caller-specific data passed to @callback * - * Request NM to scan for access points on the #NMDeviceWifi. This function only - * instructs NM to perform scanning. Use nm_device_wifi_get_access_points() - * to get available access points. + * Request NM to scan for access points on @device. Note that @callback will be + * called immediately after requesting the scan, and it may take some time after + * that for the scan to complete. **/ void -nm_device_wifi_request_scan_simple (NMDeviceWifi *device, - NMDeviceWifiRequestScanFn callback, - gpointer user_data) +nm_device_wifi_request_scan_async (NMDeviceWifi *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - RequestScanInfo *info; NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device); + RequestScanInfo *info; + GSimpleAsyncResult *simple; g_return_if_fail (NM_IS_DEVICE_WIFI (device)); + simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data, + nm_device_wifi_request_scan_async); + /* If a scan is in progress, just return */ - if (priv->scan_info) + if (priv->scan_info) { + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); return; + } info = g_slice_new0 (RequestScanInfo); info->device = device; - info->cancellable = g_cancellable_new (); - info->callback = callback; - info->user_data = user_data; + info->simple = simple; priv->scan_info = info; nmdbus_device_wifi_call_request_scan (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy, g_variant_new_array (G_VARIANT_TYPE_VARDICT, NULL, 0), - info->cancellable, - request_scan_cb, info); + cancellable, request_scan_cb, info); +} + +/** + * nm_device_wifi_request_scan_finish: + * @device: a #NMDeviceWifi + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_wifi_request_scan_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be + * set. + **/ +gboolean +nm_device_wifi_request_scan_finish (NMDeviceWifi *device, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_wifi_request_scan_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); } static void @@ -620,25 +650,6 @@ static void dispose (GObject *object) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object); - GError *error = NULL; - - if (priv->scan_info) { - RequestScanInfo *scan_info; - - scan_info = priv->scan_info; - priv->scan_info = NULL; - - if (scan_info->callback) { - g_set_error_literal (&error, NM_DEVICE_WIFI_ERROR, NM_DEVICE_WIFI_ERROR_UNKNOWN, - "Wi-Fi device was destroyed"); - scan_info->callback (NULL, error, scan_info->user_data); - scan_info->callback = NULL; - g_clear_error (&error); - } - - g_cancellable_cancel (scan_info->cancellable); - /* request_scan_cb() will free scan_info */ - } if (priv->aps) clean_up_aps (NM_DEVICE_WIFI (object), TRUE); diff --git a/libnm/nm-device-wifi.h b/libnm/nm-device-wifi.h index c56de3092c..bd7b7d7210 100644 --- a/libnm/nm-device-wifi.h +++ b/libnm/nm-device-wifi.h @@ -100,12 +100,13 @@ NMAccessPoint * nm_device_wifi_get_access_point_by_path (NMDeviceWifi * const GPtrArray * nm_device_wifi_get_access_points (NMDeviceWifi *device); -typedef void (*NMDeviceWifiRequestScanFn) (NMDeviceWifi *device, - GError *error, - gpointer user_data); -void nm_device_wifi_request_scan_simple (NMDeviceWifi *device, - NMDeviceWifiRequestScanFn callback, +void nm_device_wifi_request_scan_async (NMDeviceWifi *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); +gboolean nm_device_wifi_request_scan_finish (NMDeviceWifi *device, + GAsyncResult *result, + GError **error); G_END_DECLS diff --git a/libnm/nm-device.c b/libnm/nm-device.c index 187a298b5c..11747e5a76 100644 --- a/libnm/nm-device.c +++ b/libnm/nm-device.c @@ -1892,63 +1892,77 @@ nm_device_is_software (NMDevice *device) return !!(NM_DEVICE_GET_PRIVATE (device)->capabilities & NM_DEVICE_CAP_IS_SOFTWARE); } -typedef struct { - NMDevice *device; - NMDeviceCallbackFn fn; - gpointer user_data; -} DeviceCallbackInfo; - static void device_disconnect_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { - DeviceCallbackInfo *info = user_data; + GSimpleAsyncResult *simple = user_data; GError *error = NULL; - nmdbus_device_call_disconnect_finish (NMDBUS_DEVICE (proxy), result, &error); - if (info->fn) - info->fn (info->device, error, info->user_data); - else if (error) { - g_warning ("%s: device %s disconnect failed: %s", - __func__, - nm_object_get_path (NM_OBJECT (info->device)), - error->message); - } - g_clear_error (&error); + if (nmdbus_device_call_disconnect_finish (NMDBUS_DEVICE (proxy), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else + g_simple_async_result_take_error (simple, error); - g_object_unref (info->device); - g_slice_free (DeviceCallbackInfo, info); + g_simple_async_result_complete (simple); + g_object_unref (simple); } /** - * nm_device_disconnect: + * nm_device_disconnect_async: * @device: a #NMDevice - * @callback: (scope async) (allow-none): callback to be called when disconnect - * operation completes - * @user_data: (closure): caller-specific data passed to @callback + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the disconnect operation completes + * @user_data: caller-specific data passed to @callback * - * Disconnects the device if currently connected, and prevents the device from - * automatically connecting to networks until the next manual network connection - * request. + * Asynchronously begins disconnecting the device if currently connected, and + * prevents the device from automatically connecting to networks until the next + * manual network connection request. **/ void -nm_device_disconnect (NMDevice *device, - NMDeviceCallbackFn callback, - gpointer user_data) +nm_device_disconnect_async (NMDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - DeviceCallbackInfo *info; + GSimpleAsyncResult *simple; g_return_if_fail (NM_IS_DEVICE (device)); - info = g_slice_new (DeviceCallbackInfo); - info->fn = callback; - info->user_data = user_data; - info->device = g_object_ref (device); + simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data, + nm_device_disconnect_async); nmdbus_device_call_disconnect (NM_DEVICE_GET_PRIVATE (device)->proxy, - NULL, - device_disconnect_cb, info); + cancellable, + device_disconnect_cb, simple); +} + +/** + * nm_device_disconnect_finish: + * @device: a #NMDevice + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_disconnect_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + **/ +gboolean +nm_device_disconnect_finish (NMDevice *device, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_disconnect_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); } static void @@ -1956,50 +1970,71 @@ device_delete_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { - DeviceCallbackInfo *info = user_data; + GSimpleAsyncResult *simple = user_data; GError *error = NULL; - nmdbus_device_call_delete_finish (NMDBUS_DEVICE (proxy), result, &error); - if (info->fn) - info->fn (info->device, error, info->user_data); - else if (error) { - g_warning ("%s: device %s delete failed: %s", - __func__, - nm_object_get_path (NM_OBJECT (info->device)), - error->message); - } - g_clear_error (&error); + if (nmdbus_device_call_delete_finish (NMDBUS_DEVICE (proxy), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else + g_simple_async_result_take_error (simple, error); - g_object_unref (info->device); - g_slice_free (DeviceCallbackInfo, info); + g_simple_async_result_complete (simple); + g_object_unref (simple); } /** - * nm_device_delete: + * nm_device_delete_async: * @device: a #NMDevice - * @callback: (scope async) (allow-none): callback to be called when delete - * operation completes - * @user_data: (closure): caller-specific data passed to @callback + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when delete operation completes + * @user_data: caller-specific data passed to @callback * - * Deletes the software device. Hardware devices can't be deleted. + * Asynchronously begins deleteing the software device. Hardware devices can't + * be deleted. **/ void -nm_device_delete (NMDevice *device, - NMDeviceCallbackFn callback, - gpointer user_data) +nm_device_delete_async (NMDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { - DeviceCallbackInfo *info; + GSimpleAsyncResult *simple; g_return_if_fail (NM_IS_DEVICE (device)); - info = g_slice_new (DeviceCallbackInfo); - info->fn = callback; - info->user_data = user_data; - info->device = g_object_ref (device); + simple = g_simple_async_result_new (G_OBJECT (device), callback, user_data, + nm_device_delete_async); nmdbus_device_call_delete (NM_DEVICE_GET_PRIVATE (device)->proxy, - NULL, - device_delete_cb, info); + cancellable, + device_delete_cb, simple); +} + +/** + * nm_device_delete_finish: + * @device: a #NMDevice + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_delete_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + **/ +gboolean +nm_device_delete_finish (NMDevice *device, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (device), nm_device_delete_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); } /** diff --git a/libnm/nm-device.h b/libnm/nm-device.h index 510589f732..db55c275e1 100644 --- a/libnm/nm-device.h +++ b/libnm/nm-device.h @@ -145,15 +145,21 @@ const char * nm_device_get_description (NMDevice *device); char ** nm_device_disambiguate_names (NMDevice **devices, int num_devices); -typedef void (*NMDeviceCallbackFn) (NMDevice *device, GError *error, gpointer user_data); - -void nm_device_disconnect (NMDevice *device, - NMDeviceCallbackFn callback, +void nm_device_disconnect_async (NMDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); +gboolean nm_device_disconnect_finish (NMDevice *device, + GAsyncResult *result, + GError **error); -void nm_device_delete (NMDevice *device, - NMDeviceCallbackFn callback, +void nm_device_delete_async (NMDevice *device, + GCancellable *cancellable, + GAsyncReadyCallback callback, gpointer user_data); +gboolean nm_device_delete_finish (NMDevice *device, + GAsyncResult *result, + GError **error); GSList * nm_device_filter_connections (NMDevice *device, const GSList *connections); diff --git a/libnm/nm-remote-connection.c b/libnm/nm-remote-connection.c index 6da5e180a9..27f1c4746b 100644 --- a/libnm/nm-remote-connection.c +++ b/libnm/nm-remote-connection.c @@ -54,18 +54,6 @@ enum { LAST_PROP }; -typedef struct RemoteCall RemoteCall; -typedef void (*RemoteCallFetchResultCb) (RemoteCall *call, GAsyncResult *result); - - -struct RemoteCall { - NMRemoteConnection *self; - RemoteCallFetchResultCb fetch_result_cb; - GFunc callback; - gpointer user_data; - gpointer call_data; -}; - typedef struct { NMDBusSettingsConnection *proxy; @@ -96,240 +84,308 @@ nm_remote_connection_error_quark (void) /****************************************************************/ static void -remote_call_dbus_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) -{ - RemoteCall *call = user_data; - - call->fetch_result_cb (call, result); - - g_object_unref (call->self); - g_free (call); -} - -static RemoteCall * -remote_call_new (NMRemoteConnection *self, - RemoteCallFetchResultCb fetch_result_cb, - GFunc callback, - gpointer user_data) -{ - RemoteCall *call; - - g_assert (fetch_result_cb); - - call = g_malloc0 (sizeof (RemoteCall)); - call->self = g_object_ref (self); - call->fetch_result_cb = fetch_result_cb; - call->user_data = user_data; - call->callback = callback; - - return call; -} - -/****************************************************************/ - -static void -update_result_cb (RemoteCall *call, GAsyncResult *result) +update_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); - NMRemoteConnectionResultFunc func = (NMRemoteConnectionResultFunc) call->callback; - gboolean save_to_disk = GPOINTER_TO_INT (call->call_data); + GSimpleAsyncResult *simple = user_data; + gboolean (*finish_func) (NMDBusSettingsConnection *, GAsyncResult *, GError **); GError *error = NULL; - if (save_to_disk) - nmdbus_settings_connection_call_update_finish (priv->proxy, result, &error); + finish_func = g_object_get_data (G_OBJECT (simple), "finish_func"); + if (finish_func (NMDBUS_SETTINGS_CONNECTION (proxy), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); else - nmdbus_settings_connection_call_update_unsaved_finish (priv->proxy, result, &error); - if (func) - (*func) (call->self, error, call->user_data); - g_clear_error (&error); + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); } /** - * nm_remote_connection_commit_changes: + * nm_remote_connection_commit_changes_async: * @connection: the #NMRemoteConnection - * @save_to_disk: whether to persist the changes to disk - * @callback: (scope async) (allow-none): a function to be called when the - * commit completes - * @user_data: (closure): caller-specific data to be passed to @callback - * - * Send any local changes to the settings and properties of this connection to - * NetworkManager. + * @save_to_disk: whether to save the changes to persistent storage + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the commit operation completes + * @user_data: caller-specific data passed to @callback * - * If @save_to_disk is %TRUE, the changes will immediately be saved to disk. - * If %FALSE, then only the in-memory version is changed. (It can be saved to - * disk later with nm_remote_connection_save().) + * Asynchronously sends any local changes to the settings and properties of + * @connection to NetworkManager. If @save is %TRUE, the updated connection will + * be saved to disk; if %FALSE, then only the in-memory representation will be + * changed. **/ void -nm_remote_connection_commit_changes (NMRemoteConnection *self, - gboolean save_to_disk, - NMRemoteConnectionResultFunc callback, - gpointer user_data) +nm_remote_connection_commit_changes_async (NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { NMRemoteConnectionPrivate *priv; - RemoteCall *call; + GSimpleAsyncResult *simple; GVariant *settings; - g_return_if_fail (NM_IS_REMOTE_CONNECTION (self)); - - priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); - call = remote_call_new (self, update_result_cb, (GFunc) callback, user_data); - if (!call) - return; - call->call_data = GINT_TO_POINTER (save_to_disk); + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); - settings = nm_connection_to_dbus (NM_CONNECTION (self), NM_CONNECTION_SERIALIZE_ALL); + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_commit_changes_async); + settings = nm_connection_to_dbus (NM_CONNECTION (connection), NM_CONNECTION_SERIALIZE_ALL); if (save_to_disk) { + g_object_set_data (G_OBJECT (simple), "finish_func", + nmdbus_settings_connection_call_update_finish); nmdbus_settings_connection_call_update (priv->proxy, settings, - NULL, - remote_call_dbus_cb, call); + cancellable, + update_cb, simple); } else { + g_object_set_data (G_OBJECT (simple), "finish_func", + nmdbus_settings_connection_call_update_unsaved_finish); nmdbus_settings_connection_call_update_unsaved (priv->proxy, settings, - NULL, - remote_call_dbus_cb, call); + cancellable, + update_cb, simple); } } +/** + * nm_remote_connection_commit_changes_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_commit_changes_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_commit_changes_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_commit_changes_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + static void -save_result_cb (RemoteCall *call, GAsyncResult *result) +save_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); - NMRemoteConnectionResultFunc func = (NMRemoteConnectionResultFunc) call->callback; + GSimpleAsyncResult *simple = user_data; GError *error = NULL; - nmdbus_settings_connection_call_save_finish (priv->proxy, result, &error); - if (func) - (*func) (call->self, error, call->user_data); - g_clear_error (&error); + if (nmdbus_settings_connection_call_save_finish (NMDBUS_SETTINGS_CONNECTION (proxy), + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); } /** - * nm_remote_connection_save: + * nm_remote_connection_save_async: * @connection: the #NMRemoteConnection - * @callback: (scope async) (allow-none): a function to be called when the - * save completes - * @user_data: (closure): caller-specific data to be passed to @callback + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the save operation completes + * @user_data: caller-specific data passed to @callback * * Saves the connection to disk if the connection has changes that have not yet * been written to disk, or if the connection has never been saved. **/ void -nm_remote_connection_save (NMRemoteConnection *connection, - NMRemoteConnectionResultFunc callback, - gpointer user_data) +nm_remote_connection_save_async (NMRemoteConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { NMRemoteConnectionPrivate *priv; - RemoteCall *call; + GSimpleAsyncResult *simple; g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); - call = remote_call_new (connection, save_result_cb, (GFunc) callback, user_data); - if (!call) - return; + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_save_async); + nmdbus_settings_connection_call_save (priv->proxy, cancellable, save_cb, simple); +} - nmdbus_settings_connection_call_save (priv->proxy, - NULL, - remote_call_dbus_cb, call); +/** + * nm_remote_connection_save_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_save_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_save_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_save_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); } static void -delete_result_cb (RemoteCall *call, GAsyncResult *result) +delete_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); - NMRemoteConnectionResultFunc func = (NMRemoteConnectionResultFunc) call->callback; + GSimpleAsyncResult *simple = user_data; GError *error = NULL; - nmdbus_settings_connection_call_delete_finish (priv->proxy, result, &error); - if (func) - (*func) (call->self, error, call->user_data); - g_clear_error (&error); + if (nmdbus_settings_connection_call_delete_finish (NMDBUS_SETTINGS_CONNECTION (proxy), + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); } /** - * nm_remote_connection_delete: + * nm_remote_connection_delete_async: * @connection: the #NMRemoteConnection - * @callback: (scope async) (allow-none): a function to be called when the delete completes - * @user_data: (closure): caller-specific data to be passed to @callback + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the delete operation completes + * @user_data: caller-specific data passed to @callback * - * Delete the connection. + * Asynchronously deletes the connection. **/ void -nm_remote_connection_delete (NMRemoteConnection *self, - NMRemoteConnectionResultFunc callback, - gpointer user_data) +nm_remote_connection_delete_async (NMRemoteConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { NMRemoteConnectionPrivate *priv; - RemoteCall *call; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); - g_return_if_fail (NM_IS_REMOTE_CONNECTION (self)); + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); - priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_delete_async); + nmdbus_settings_connection_call_delete (priv->proxy, cancellable, delete_cb, simple); +} - call = remote_call_new (self, delete_result_cb, (GFunc) callback, user_data); - if (!call) - return; +/** + * nm_remote_connection_delete_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_delete_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error will be set. + **/ +gboolean +nm_remote_connection_delete_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_delete_async), FALSE); - nmdbus_settings_connection_call_delete (priv->proxy, - NULL, - remote_call_dbus_cb, call); + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); } static void -get_secrets_cb (RemoteCall *call, GAsyncResult *result) +get_secrets_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (call->self); - NMRemoteConnectionGetSecretsFunc func = (NMRemoteConnectionGetSecretsFunc) call->callback; + GSimpleAsyncResult *simple = user_data; GVariant *secrets = NULL; GError *error = NULL; - if (!nmdbus_settings_connection_call_get_secrets_finish (priv->proxy, &secrets, - result, &error)) - secrets = NULL; - if (func) - (*func) (call->self, error ? NULL : secrets, error, call->user_data); - g_clear_error (&error); - if (secrets) - g_variant_unref (secrets); -} + if (nmdbus_settings_connection_call_get_secrets_finish (NMDBUS_SETTINGS_CONNECTION (proxy), + &secrets, result, &error)) + g_simple_async_result_set_op_res_gpointer (simple, secrets, (GDestroyNotify) g_variant_unref); + else + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} /** - * nm_remote_connection_get_secrets: + * nm_remote_connection_get_secrets_async: * @connection: the #NMRemoteConnection * @setting_name: the #NMSetting object name to get secrets for - * @callback: (scope async): a function to be called when the update completes; - * must not be %NULL - * @user_data: (closure): caller-specific data to be passed to @callback + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the secret request completes + * @user_data: caller-specific data passed to @callback * - * Request the connection's secrets. + * Asynchronously requests the connection's secrets. **/ void -nm_remote_connection_get_secrets (NMRemoteConnection *self, - const char *setting_name, - NMRemoteConnectionGetSecretsFunc callback, - gpointer user_data) +nm_remote_connection_get_secrets_async (NMRemoteConnection *connection, + const char *setting_name, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { NMRemoteConnectionPrivate *priv; - RemoteCall *call; + GSimpleAsyncResult *simple; - g_return_if_fail (NM_IS_REMOTE_CONNECTION (self)); - g_return_if_fail (callback != NULL); + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); - priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); - call = remote_call_new (self, get_secrets_cb, (GFunc) callback, user_data); - if (!call) - return; + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_get_secrets_async); nmdbus_settings_connection_call_get_secrets (priv->proxy, setting_name, - NULL, - remote_call_dbus_cb, call); + cancellable, + get_secrets_cb, simple); +} + +/** + * nm_remote_connection_get_secrets_finish: + * @connection: the #NMRemoteConnection + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_connection_get_secrets_async(). + * + * Returns: (transfer full): a #GVariant of type %NM_VARIANT_TYPE_CONNECTION + * containing @connection's secrets, or %NULL on error. + **/ +GVariant * +nm_remote_connection_get_secrets_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_get_secrets_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_variant_ref (g_simple_async_result_get_op_res_gpointer (simple)); } /** diff --git a/libnm/nm-remote-connection.h b/libnm/nm-remote-connection.h index 5c6bebf65a..a6cdf79aef 100644 --- a/libnm/nm-remote-connection.h +++ b/libnm/nm-remote-connection.h @@ -69,58 +69,41 @@ typedef struct { gpointer padding[8]; } NMRemoteConnectionClass; -/** - * NMRemoteConnectionResultFunc: - * @connection: the connection for which an operation was performed - * @error: on failure, a descriptive error - * @user_data: user data passed to function which began the operation - * - * Called when NetworkManager has finished an asynchronous operation on a - * connection, like commit changes, deleting, saving, etc. - */ -typedef void (*NMRemoteConnectionResultFunc) (NMRemoteConnection *connection, - GError *error, - gpointer user_data); - -/* Backwards compatibility */ -typedef NMRemoteConnectionResultFunc NMRemoteConnectionCommitFunc; -typedef NMRemoteConnectionResultFunc NMRemoteConnectionDeleteFunc; - -/** - * NMRemoteConnectionGetSecretsFunc: - * @connection: the connection for which secrets were requested - * @secrets: on success, a #GVariant of type %NM_VARIANT_TYPE_CONNECTION - * containing secrets. - * @error: on failure, a descriptive error - * @user_data: user data passed to nm_remote_connection_get_secrets() - * - * Called when NetworkManager returns secrets in response to a request for - * secrets via nm_remote_connection_get_secrets(). - */ -typedef void (*NMRemoteConnectionGetSecretsFunc) (NMRemoteConnection *connection, - GVariant *secrets, - GError *error, - gpointer user_data); - GType nm_remote_connection_get_type (void); -void nm_remote_connection_commit_changes (NMRemoteConnection *connection, - gboolean save_to_disk, - NMRemoteConnectionResultFunc callback, - gpointer user_data); - -void nm_remote_connection_save (NMRemoteConnection *connection, - NMRemoteConnectionResultFunc callback, - gpointer user_data); - -void nm_remote_connection_delete (NMRemoteConnection *connection, - NMRemoteConnectionResultFunc callback, - gpointer user_data); - -void nm_remote_connection_get_secrets (NMRemoteConnection *connection, - const char *setting_name, - NMRemoteConnectionGetSecretsFunc callback, - gpointer user_data); +void nm_remote_connection_commit_changes_async (NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_connection_commit_changes_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error); + +void nm_remote_connection_save_async (NMRemoteConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_connection_save_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error); + +void nm_remote_connection_delete_async (NMRemoteConnection *connection, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_connection_delete_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error); + +void nm_remote_connection_get_secrets_async (NMRemoteConnection *connection, + const char *setting_name, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GVariant *nm_remote_connection_get_secrets_finish (NMRemoteConnection *connection, + GAsyncResult *result, + GError **error); gboolean nm_remote_connection_get_unsaved (NMRemoteConnection *connection); diff --git a/libnm/nm-remote-settings.c b/libnm/nm-remote-settings.c index a867f638b3..b0cd55a07a 100644 --- a/libnm/nm-remote-settings.c +++ b/libnm/nm-remote-settings.c @@ -59,14 +59,19 @@ * * |[<!-- language="C" --> * static void - * added_cb (NMRemoteSettings *settings, - * NMRemoteConnection *remote, - * GError *error, + * added_cb (GObject *object, + * GAsyncResult *result, * gpointer user_data) * { - * if (error) + * NMRemoteConnection *remote; + * GError *error = NULL; + * + * remote = nm_remote_settings_add_connection_finish (NM_REMOTE_SETTINGS (object), + * result, &error); + * if (error) { * g_print ("Error adding connection: %s", error->message); - * else { + * g_clear_error (&error); + * } else { * g_print ("Added: %s\n", nm_connection_get_path (NM_CONNECTION (remote))); * /* Use 'remote' with nm_remote_connection_commit_changes() to save * * changes and nm_remote_connection_delete() to delete the connection */ @@ -106,7 +111,8 @@ * nm_connection_add_setting (connection, NM_SETTING (s_ip4)); * * /* Ask NetworkManager to store the connection */ - * success = nm_remote_settings_add_connection (settings, connection, added_cb, loop); + * success = nm_remote_settings_add_connection_async (settings, connection, + * NULL, added_cb, NULL); * * /* Release the template connection; the actual stored connection will * * be returned in added_cb() */ @@ -178,8 +184,7 @@ nm_remote_settings_error_quark (void) typedef struct { NMRemoteSettings *self; - NMRemoteSettingsAddConnectionFunc callback; - gpointer callback_data; + GSimpleAsyncResult *simple; char *path; gboolean saved; } AddConnectionInfo; @@ -201,26 +206,28 @@ add_connection_info_find (NMRemoteSettings *self, const char *path) } static void -add_connection_info_dispose (NMRemoteSettings *self, AddConnectionInfo *info) -{ - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - - priv->add_list = g_slist_remove (priv->add_list, info); - - g_free (info->path); - g_free (info); -} - -static void add_connection_info_complete (NMRemoteSettings *self, AddConnectionInfo *info, NMRemoteConnection *connection, GError *error) { + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + g_return_if_fail (info != NULL); - info->callback (info->self, connection, error, info->callback_data); - add_connection_info_dispose (self, info); + if (connection) { + g_simple_async_result_set_op_res_gpointer (info->simple, + g_object_ref (connection), + g_object_unref); + } else + g_simple_async_result_set_from_error (info->simple, error); + g_simple_async_result_complete (info->simple); + + g_object_unref (info->simple); + priv->add_list = g_slist_remove (priv->add_list, info); + + g_free (info->path); + g_slice_free (AddConnectionInfo, info); } typedef const char * (*ConnectionStringGetter) (NMConnection *); @@ -425,6 +432,18 @@ nm_remote_settings_list_connections (NMRemoteSettings *settings) return list; } +static gboolean +settings_service_is_running (NMRemoteSettings *settings, GError **error) +{ + if (!_nm_object_get_nm_running (NM_OBJECT (settings))) { + g_set_error_literal (error, NM_REMOTE_SETTINGS_ERROR, + NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE, + "NetworkManager is not running."); + return FALSE; + } else + return TRUE; +} + static void add_connection_done (GObject *proxy, GAsyncResult *result, gpointer user_data) { @@ -452,11 +471,12 @@ add_connection_done (GObject *proxy, GAsyncResult *result, gpointer user_data) } /** - * nm_remote_settings_add_connection: + * nm_remote_settings_add_connection_async: * @settings: the %NMRemoteSettings * @connection: the connection to add. Note that this object's settings will be * added, not the object itself * @save_to_disk: whether to immediately save the connection to disk + * @cancellable: a #GCancellable, or %NULL * @callback: (scope async): callback to be called when the add operation completes * @user_data: (closure): caller-specific data passed to @callback * @@ -474,33 +494,34 @@ add_connection_done (GObject *proxy, GAsyncResult *result, gpointer user_data) * Note that the #NMRemoteConnection returned in @callback may not contain * identical settings to @connection as NetworkManager may perform automatic * completion and/or normalization of connection properties. - * - * Returns: %TRUE if the request was successful, %FALSE if it failed **/ -gboolean -nm_remote_settings_add_connection (NMRemoteSettings *settings, - NMConnection *connection, - gboolean save_to_disk, - NMRemoteSettingsAddConnectionFunc callback, - gpointer user_data) +void +nm_remote_settings_add_connection_async (NMRemoteSettings *settings, + NMConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { NMRemoteSettingsPrivate *priv; AddConnectionInfo *info; GVariant *new_settings; + GError *error = NULL; g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - g_return_val_if_fail (callback != NULL, FALSE); priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); - if (!_nm_object_get_nm_running (NM_OBJECT (settings))) - return FALSE; + if (!settings_service_is_running (settings, &error)) { + g_simple_async_report_take_gerror_in_idle (G_OBJECT (settings), callback, user_data, error); + return; + } - info = g_malloc0 (sizeof (AddConnectionInfo)); + info = g_slice_new0 (AddConnectionInfo); info->self = settings; - info->callback = callback; - info->callback_data = user_data; + info->simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data, + nm_remote_settings_add_connection_async); info->saved = save_to_disk; new_settings = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); @@ -518,10 +539,34 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, } priv->add_list = g_slist_append (priv->add_list, info); - - return TRUE; } +/** + * nm_remote_settings_add_connection_finish: + * @settings: an #NMRemoteSettings + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_remote_settings_add_connection_async(). + * + * Returns: (transfer full): the new #NMRemoteConnection on success, %NULL on + * failure, in which case @error will be set. + **/ +NMRemoteConnection * +nm_remote_settings_add_connection_finish (NMRemoteSettings *settings, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_add_connection_async), NULL); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} /** * nm_remote_settings_load_connections: @@ -529,6 +574,7 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, * @filenames: %NULL-terminated array of filenames to load * @failures: (out) (transfer full): on return, a %NULL-terminated array of * filenames that failed to load + * @cancellable: a #GCancellable, or %NULL * @error: return location for #GError * * Requests that the remote settings service load or reload the given files, @@ -542,7 +588,7 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, * NetworkManager tried to load the files, but some (or all) failed, * then @failures will be set to a %NULL-terminated array of the * filenames that failed to load. - + * * Returns: %TRUE if NetworkManager at least tried to load @filenames, * %FALSE if an error occurred (eg, permission denied). **/ @@ -550,6 +596,7 @@ gboolean nm_remote_settings_load_connections (NMRemoteSettings *settings, char **filenames, char ***failures, + GCancellable *cancellable, GError **error) { NMRemoteSettingsPrivate *priv; @@ -560,18 +607,14 @@ nm_remote_settings_load_connections (NMRemoteSettings *settings, priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); - if (!_nm_object_get_nm_running (NM_OBJECT (settings))) { - g_set_error_literal (error, NM_REMOTE_SETTINGS_ERROR, - NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE, - "NetworkManager is not running."); + if (!settings_service_is_running (settings, error)) return FALSE; - } if (!nmdbus_settings_call_load_connections_sync (priv->proxy, (const char * const *) filenames, &success, failures, - NULL, error)) + cancellable, error)) success = FALSE; return success; @@ -580,6 +623,7 @@ nm_remote_settings_load_connections (NMRemoteSettings *settings, /** * nm_remote_settings_reload_connections: * @settings: the #NMRemoteSettings + * @cancellable: a #GCancellable, or %NULL * @error: return location for #GError * * Requests that the remote settings service reload all connection @@ -590,6 +634,7 @@ nm_remote_settings_load_connections (NMRemoteSettings *settings, **/ gboolean nm_remote_settings_reload_connections (NMRemoteSettings *settings, + GCancellable *cancellable, GError **error) { NMRemoteSettingsPrivate *priv; @@ -599,82 +644,98 @@ nm_remote_settings_reload_connections (NMRemoteSettings *settings, priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); - if (!_nm_object_get_nm_running (NM_OBJECT (settings))) { - g_set_error_literal (error, NM_REMOTE_SETTINGS_ERROR, - NM_REMOTE_SETTINGS_ERROR_SERVICE_UNAVAILABLE, - "NetworkManager is not running."); + if (!settings_service_is_running (settings, error)) return FALSE; - } if (!nmdbus_settings_call_reload_connections_sync (priv->proxy, &success, - NULL, error)) + cancellable, error)) success = FALSE; return success; } -typedef struct { - NMRemoteSettings *settings; - NMRemoteSettingsSaveHostnameFunc callback; - gpointer callback_data; -} SaveHostnameInfo; - static void save_hostname_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) { - SaveHostnameInfo *info = user_data; + GSimpleAsyncResult *simple = user_data; GError *error = NULL; - nmdbus_settings_call_save_hostname_finish (NMDBUS_SETTINGS (proxy), result, &error); - if (info->callback != NULL) - info->callback (info->settings, error, info->callback_data); - g_clear_error (&error); + if (nmdbus_settings_call_save_hostname_finish (NMDBUS_SETTINGS (proxy), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); } /** - * nm_remote_settings_save_hostname: + * nm_remote_settings_save_hostname_async: * @settings: the %NMRemoteSettings - * @hostname: the new persistent hostname to set, or %NULL to clear any existing - * persistent hostname - * @callback: (scope async) (allow-none): callback to be called when the - * hostname operation completes + * @hostname: (allow-none): the new persistent hostname to set, or %NULL to + * clear any existing persistent hostname + * @cancellable: a #GCancellable, or %NULL + * @callback: (scope async): callback to be called when the operation completes * @user_data: (closure): caller-specific data passed to @callback * * Requests that the machine's persistent hostname be set to the specified value * or cleared. - * - * Returns: %TRUE if the request was successful, %FALSE if it failed **/ -gboolean -nm_remote_settings_save_hostname (NMRemoteSettings *settings, - const char *hostname, - NMRemoteSettingsSaveHostnameFunc callback, - gpointer user_data) +void +nm_remote_settings_save_hostname_async (NMRemoteSettings *settings, + const char *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { NMRemoteSettingsPrivate *priv; - SaveHostnameInfo *info; + GSimpleAsyncResult *simple; + GError *error = NULL; g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); - g_return_val_if_fail (hostname != NULL, FALSE); - g_return_val_if_fail (callback != NULL, FALSE); priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); - if (!_nm_object_get_nm_running (NM_OBJECT (settings))) - return FALSE; + simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data, + nm_remote_settings_save_hostname_async); - info = g_malloc0 (sizeof (SaveHostnameInfo)); - info->settings = settings; - info->callback = callback; - info->callback_data = user_data; + if (!settings_service_is_running (settings, &error)) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); + return; + } nmdbus_settings_call_save_hostname (priv->proxy, hostname ? hostname : "", - NULL, - save_hostname_cb, info); - return TRUE; + cancellable, save_hostname_cb, simple); +} + +/** + * nm_remote_settings_save_hostname_finish: + * @settings: the %NMRemoteSettings + * @result: the result passed to the #GAsyncReadyCallback + * @error: return location for #GError + * + * Gets the result of an nm_remote_settings_save_hostname_async() call. + * + * Returns: %TRUE if the request was successful, %FALSE if it failed + **/ +gboolean +nm_remote_settings_save_hostname_finish (NMRemoteSettings *settings, + GAsyncResult *result, + GError **error) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_save_hostname_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); } static void @@ -867,9 +928,6 @@ dispose (GObject *object) NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); int i; - while (g_slist_length (priv->add_list)) - add_connection_info_dispose (self, (AddConnectionInfo *) priv->add_list->data); - if (priv->all_connections) { for (i = 0; i < priv->all_connections->len; i++) cleanup_connection (self, priv->all_connections->pdata[i]); diff --git a/libnm/nm-remote-settings.h b/libnm/nm-remote-settings.h index 11c4955bb2..673b0457df 100644 --- a/libnm/nm-remote-settings.h +++ b/libnm/nm-remote-settings.h @@ -74,22 +74,6 @@ GQuark nm_remote_settings_error_quark (void); typedef struct _NMRemoteSettings NMRemoteSettings; typedef struct _NMRemoteSettingsClass NMRemoteSettingsClass; - -typedef void (*NMRemoteSettingsAddConnectionFunc) (NMRemoteSettings *settings, - NMRemoteConnection *connection, - GError *error, - gpointer user_data); - -typedef void (*NMRemoteSettingsLoadConnectionsFunc) (NMRemoteSettings *settings, - char **failures, - GError *error, - gpointer user_data); - -typedef void (*NMRemoteSettingsSaveHostnameFunc) (NMRemoteSettings *settings, - GError *error, - gpointer user_data); - - struct _NMRemoteSettings { NMObject parent; }; @@ -129,24 +113,34 @@ NMRemoteConnection * nm_remote_settings_get_connection_by_path (NMRemoteSettings NMRemoteConnection *nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings, const char *uuid); -gboolean nm_remote_settings_add_connection (NMRemoteSettings *settings, - NMConnection *connection, - gboolean save_to_disk, - NMRemoteSettingsAddConnectionFunc callback, - gpointer user_data); +void nm_remote_settings_add_connection_async (NMRemoteSettings *settings, + NMConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +NMRemoteConnection *nm_remote_settings_add_connection_finish (NMRemoteSettings *settings, + GAsyncResult *result, + GError **error); gboolean nm_remote_settings_load_connections (NMRemoteSettings *settings, char **filenames, char ***failures, + GCancellable *cancellable, GError **error); gboolean nm_remote_settings_reload_connections (NMRemoteSettings *settings, + GCancellable *cancellable, GError **error); -gboolean nm_remote_settings_save_hostname (NMRemoteSettings *settings, - const char *hostname, - NMRemoteSettingsSaveHostnameFunc callback, - gpointer user_data); +void nm_remote_settings_save_hostname_async (NMRemoteSettings *settings, + const char *hostname, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean nm_remote_settings_save_hostname_finish (NMRemoteSettings *settings, + GAsyncResult *result, + GError **error); G_END_DECLS diff --git a/libnm/tests/test-remote-settings-client.c b/libnm/tests/test-remote-settings-client.c index 4f8d873bbc..1561ef9e42 100644 --- a/libnm/tests/test-remote-settings-client.c +++ b/libnm/tests/test-remote-settings-client.c @@ -37,16 +37,24 @@ NMRemoteConnection *remote = NULL; /*******************************************************************/ static void -add_cb (NMRemoteSettings *s, - NMRemoteConnection *connection, - GError *error, +add_cb (GObject *s, + GAsyncResult *result, gpointer user_data) { + gboolean *done = user_data; + GError *error = NULL; + + remote = nm_remote_settings_add_connection_finish (settings, result, &error); g_assert_no_error (error); - *((gboolean *) user_data) = TRUE; - remote = connection; - g_object_add_weak_pointer (G_OBJECT (connection), (void **) &remote); + *done = TRUE; + g_object_add_weak_pointer (G_OBJECT (remote), (void **) &remote); + + /* nm_remote_settings_add_connection_finish() adds a ref to @remote, but we + * want the weak pointer to be cleared as soon as @settings drops its own ref. + * So drop ours. + */ + g_object_unref (remote); } #define TEST_CON_ID "blahblahblah" @@ -55,18 +63,17 @@ static void test_add_connection (void) { NMConnection *connection; - gboolean success; time_t start, now; gboolean done = FALSE; connection = nmtst_create_minimal_connection (TEST_CON_ID, NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); - success = nm_remote_settings_add_connection (settings, - connection, - TRUE, - add_cb, - &done); - g_assert (success == TRUE); + nm_remote_settings_add_connection_async (settings, + connection, + TRUE, + NULL, + add_cb, + &done); start = time (NULL); do { @@ -352,15 +359,19 @@ test_remove_connection (void) #define TEST_ADD_REMOVE_ID "add-remove-test-connection" static void -add_remove_cb (NMRemoteSettings *s, - NMRemoteConnection *connection, - GError *error, +add_remove_cb (GObject *s, + GAsyncResult *result, gpointer user_data) { + NMRemoteConnection *connection; + gboolean *done = user_data; + GError *error = NULL; + + connection = nm_remote_settings_add_connection_finish (settings, result, &error); g_assert_error (error, NM_REMOTE_SETTINGS_ERROR, NM_REMOTE_SETTINGS_ERROR_CONNECTION_REMOVED); g_assert (connection == NULL); - *((gboolean *) user_data) = TRUE; + *done = TRUE; } static void @@ -369,7 +380,6 @@ test_add_remove_connection (void) GVariant *ret; GError *error = NULL; NMConnection *connection; - gboolean success; time_t start, now; gboolean done = FALSE; @@ -386,12 +396,12 @@ test_add_remove_connection (void) g_variant_unref (ret); connection = nmtst_create_minimal_connection (TEST_ADD_REMOVE_ID, NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); - success = nm_remote_settings_add_connection (settings, - connection, - TRUE, - add_remove_cb, - &done); - g_assert (success == TRUE); + nm_remote_settings_add_connection_async (settings, + connection, + TRUE, + NULL, + add_remove_cb, + &done); start = time (NULL); do { diff --git a/libnm/tests/test-secret-agent.c b/libnm/tests/test-secret-agent.c index 4bb99a7a24..c4eafd7a40 100644 --- a/libnm/tests/test-secret-agent.c +++ b/libnm/tests/test-secret-agent.c @@ -219,12 +219,15 @@ device_added_cb (NMClient *c, } static void -connection_added_cb (NMRemoteSettings *s, - NMRemoteConnection *connection, - GError *error, +connection_added_cb (GObject *s, + GAsyncResult *result, gpointer user_data) { TestSecretAgentData *sadata = user_data; + NMRemoteConnection *connection; + GError *error = NULL; + + connection = nm_remote_settings_add_connection_finish (sadata->settings, result, &error); g_assert_no_error (error); g_assert_cmpstr (nm_connection_get_id (NM_CONNECTION (connection)), ==, sadata->con_id); @@ -258,7 +261,6 @@ test_setup (TestSecretAgentData *sadata, gconstpointer test_data) NMSettingWireless *s_wireless; GBytes *ssid; NMSetting *s_wsec; - gboolean success; GError *error = NULL; GVariant *ret; gulong handler; @@ -314,12 +316,12 @@ test_setup (TestSecretAgentData *sadata, gconstpointer test_data) NULL); nm_connection_add_setting (connection, s_wsec); - success = nm_remote_settings_add_connection (sadata->settings, - connection, - TRUE, - connection_added_cb, - sadata); - g_assert (success == TRUE); + nm_remote_settings_add_connection_async (sadata->settings, + connection, + TRUE, + NULL, + connection_added_cb, + sadata); g_object_unref (connection); g_main_loop_run (sadata->loop); @@ -354,6 +356,7 @@ test_cleanup (TestSecretAgentData *sadata, gconstpointer test_data) g_object_unref (sadata->agent); } + g_object_unref (sadata->connection); g_object_unref (sadata->client); g_object_unref (sadata->settings); @@ -380,12 +383,15 @@ test_cleanup (TestSecretAgentData *sadata, gconstpointer test_data) /*******************************************************************/ static void -connection_activated_none_cb (NMClient *c, - NMActiveConnection *ac, - GError *error, +connection_activated_none_cb (GObject *c, + GAsyncResult *result, gpointer user_data) { TestSecretAgentData *sadata = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_client_activate_connection_finish (sadata->client, result, &error); g_assert (error != NULL); g_dbus_error_strip_remote_error (error); @@ -397,12 +403,13 @@ connection_activated_none_cb (NMClient *c, static void test_secret_agent_none (TestSecretAgentData *sadata, gconstpointer test_data) { - nm_client_activate_connection (sadata->client, - sadata->connection, - sadata->device, - NULL, - connection_activated_none_cb, - sadata); + nm_client_activate_connection_async (sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_none_cb, + sadata); g_main_loop_run (sadata->loop); } @@ -425,12 +432,15 @@ secrets_requested_no_secrets_cb (TestSecretAgent *agent, } static void -connection_activated_no_secrets_cb (NMClient *c, - NMActiveConnection *ac, - GError *error, +connection_activated_no_secrets_cb (GObject *c, + GAsyncResult *result, gpointer user_data) { TestSecretAgentData *sadata = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_client_activate_connection_finish (sadata->client, result, &error); g_assert (error != NULL); g_dbus_error_strip_remote_error (error); @@ -446,12 +456,13 @@ test_secret_agent_no_secrets (TestSecretAgentData *sadata, gconstpointer test_da G_CALLBACK (secrets_requested_no_secrets_cb), sadata); - nm_client_activate_connection (sadata->client, - sadata->connection, - sadata->device, - NULL, - connection_activated_no_secrets_cb, - sadata); + nm_client_activate_connection_async (sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_no_secrets_cb, + sadata); g_main_loop_run (sadata->loop); g_assert_cmpint (sadata->secrets_requested, ==, 1); @@ -460,12 +471,15 @@ test_secret_agent_no_secrets (TestSecretAgentData *sadata, gconstpointer test_da /*******************************************************************/ static void -connection_activated_cancel_cb (NMClient *c, - NMActiveConnection *ac, - GError *error, +connection_activated_cancel_cb (GObject *c, + GAsyncResult *result, gpointer user_data) { TestSecretAgentData *sadata = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_client_activate_connection_finish (sadata->client, result, &error); g_assert (error != NULL); g_dbus_error_strip_remote_error (error); @@ -497,12 +511,13 @@ test_secret_agent_cancel (TestSecretAgentData *sadata, gconstpointer test_data) G_CALLBACK (secrets_requested_cancel_cb), sadata); - nm_client_activate_connection (sadata->client, - sadata->connection, - sadata->device, - NULL, - connection_activated_cancel_cb, - sadata); + nm_client_activate_connection_async (sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_cancel_cb, + sadata); g_main_loop_run (sadata->loop); g_assert_cmpint (sadata->secrets_requested, ==, 1); @@ -511,12 +526,15 @@ test_secret_agent_cancel (TestSecretAgentData *sadata, gconstpointer test_data) /*******************************************************************/ static void -connection_activated_good_cb (NMClient *c, - NMActiveConnection *ac, - GError *error, +connection_activated_good_cb (GObject *c, + GAsyncResult *result, gpointer user_data) { TestSecretAgentData *sadata = user_data; + NMActiveConnection *ac; + GError *error = NULL; + + ac = nm_client_activate_connection_finish (sadata->client, result, &error); /* test-networkmanager-service.py doesn't implement activation, but * we should at least get as far as the error telling us that (which the @@ -552,12 +570,13 @@ test_secret_agent_good (TestSecretAgentData *sadata, gconstpointer test_data) G_CALLBACK (secrets_requested_good_cb), sadata); - nm_client_activate_connection (sadata->client, - sadata->connection, - sadata->device, - NULL, - connection_activated_good_cb, - sadata); + nm_client_activate_connection_async (sadata->client, + sadata->connection, + sadata->device, + NULL, + NULL, + connection_activated_good_cb, + sadata); g_main_loop_run (sadata->loop); g_assert_cmpint (sadata->secrets_requested, ==, 1); |