mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-01 13:55:36 +00:00
libnm: implement nm_client_activate_connection()/nm_client_add_and_activate_connection*() by using GDBusConnection directly
We still need the bits in "nm-manager.c", to wait until the NMActiveConnection instance is ready. This is now done by nm_manager_complete_active_connection().
This commit is contained in:
parent
eaddc22775
commit
90d0ae0faf
|
@ -1108,22 +1108,32 @@ nm_client_get_activating_connection (NMClient *client)
|
|||
}
|
||||
|
||||
static void
|
||||
activate_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
activate_connection_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *simple = user_data;
|
||||
NMActiveConnection *ac;
|
||||
NMClient *self;
|
||||
gs_unref_object GTask *task = user_data;
|
||||
gs_unref_variant GVariant *ret = NULL;
|
||||
const char *v_active_connection;
|
||||
GError *error = NULL;
|
||||
|
||||
ac = nm_manager_activate_connection_finish (NM_MANAGER (object), result, &error);
|
||||
if (ac)
|
||||
g_simple_async_result_set_op_res_gpointer (simple, ac, g_object_unref);
|
||||
else
|
||||
g_simple_async_result_take_error (simple, error);
|
||||
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
|
||||
if (!ret) {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_simple_async_result_complete (simple);
|
||||
g_object_unref (simple);
|
||||
self = g_task_get_source_object (task);
|
||||
|
||||
g_variant_get (ret, "(&o)", &v_active_connection);
|
||||
|
||||
nm_manager_wait_for_active_connection (NM_CLIENT_GET_PRIVATE (self)->manager,
|
||||
v_active_connection,
|
||||
NULL,
|
||||
NULL,
|
||||
g_steal_pointer (&task));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1168,27 +1178,39 @@ nm_client_activate_connection_async (NMClient *client,
|
|||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
GError *error = NULL;
|
||||
const char *arg_connection = NULL;
|
||||
const char *arg_device = NULL;
|
||||
|
||||
g_return_if_fail (NM_IS_CLIENT (client));
|
||||
if (device)
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
if (connection)
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
|
||||
if (!_nm_client_check_nm_running (client, &error)) {
|
||||
g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
|
||||
return;
|
||||
if (connection) {
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
arg_connection = nm_connection_get_path (connection);
|
||||
g_return_if_fail (arg_connection);
|
||||
}
|
||||
|
||||
simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
|
||||
nm_client_activate_connection_async);
|
||||
if (cancellable)
|
||||
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
||||
nm_manager_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager,
|
||||
connection, device, specific_object,
|
||||
cancellable, activate_cb, simple);
|
||||
if (device) {
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
arg_device = nm_object_get_path (NM_OBJECT (device));
|
||||
g_return_if_fail (arg_device);
|
||||
}
|
||||
|
||||
_nm_object_dbus_call (client,
|
||||
nm_client_activate_connection_async,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data,
|
||||
NM_DBUS_PATH,
|
||||
NM_DBUS_INTERFACE,
|
||||
"ActivateConnection",
|
||||
g_variant_new ("(ooo)",
|
||||
arg_connection ?: "/",
|
||||
arg_device ?: "/",
|
||||
specific_object ?: "/"),
|
||||
G_VARIANT_TYPE ("(o)"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
NM_DBUS_DEFAULT_TIMEOUT_MSEC,
|
||||
activate_connection_cb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1207,37 +1229,153 @@ nm_client_activate_connection_finish (NMClient *client,
|
|||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
nm_auto_free_activate_result _NMActivateResult *r = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
|
||||
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
|
||||
g_return_val_if_fail (nm_g_task_is_valid (result, client, nm_client_activate_connection_async), NULL);
|
||||
|
||||
simple = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (simple, error))
|
||||
r = g_task_propagate_pointer (G_TASK (result), error);
|
||||
if (!r)
|
||||
return NULL;
|
||||
else
|
||||
return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
|
||||
return g_steal_pointer (&r->active);
|
||||
}
|
||||
|
||||
static void
|
||||
add_activate_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
_add_and_activate_connection_done (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gboolean use_add_and_activate_v2,
|
||||
GTask *task_take)
|
||||
{
|
||||
gs_unref_object GSimpleAsyncResult *simple = user_data;
|
||||
gs_unref_variant GVariant *result_data = NULL;
|
||||
gs_unref_object NMActiveConnection *ac = NULL;
|
||||
_nm_unused gs_unref_object GTask *task = task_take;
|
||||
NMClient *self;
|
||||
gs_unref_variant GVariant *ret = NULL;
|
||||
GError *error = NULL;
|
||||
const char *v_path;
|
||||
const char *v_active_connection;
|
||||
gs_unref_variant GVariant *v_result = NULL;
|
||||
|
||||
ac = nm_manager_add_and_activate_connection_finish (NM_MANAGER (object), result, &result_data, &error);
|
||||
if (ac) {
|
||||
g_simple_async_result_set_op_res_gpointer (simple,
|
||||
_nm_activate_result_new (ac, result_data),
|
||||
(GDestroyNotify) _nm_activate_result_free);
|
||||
} else
|
||||
g_simple_async_result_take_error (simple, error);
|
||||
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
|
||||
if (!ret) {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_simple_async_result_complete (simple);
|
||||
self = g_task_get_source_object (task);
|
||||
|
||||
if (use_add_and_activate_v2) {
|
||||
g_variant_get (ret,
|
||||
"(&o&o@a{sv})",
|
||||
&v_path,
|
||||
&v_active_connection,
|
||||
&v_result);
|
||||
} else {
|
||||
g_variant_get (ret,
|
||||
"(&o&o)",
|
||||
&v_path,
|
||||
&v_active_connection);
|
||||
}
|
||||
|
||||
nm_manager_wait_for_active_connection (NM_CLIENT_GET_PRIVATE (self)->manager,
|
||||
v_active_connection,
|
||||
v_path,
|
||||
g_steal_pointer (&v_result),
|
||||
g_steal_pointer (&task));
|
||||
}
|
||||
|
||||
static void
|
||||
_add_and_activate_connection_v1_cb (GObject *object, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
_add_and_activate_connection_done (object, result, FALSE, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
_add_and_activate_connection_v2_cb (GObject *object, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
_add_and_activate_connection_done (object, result, TRUE, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
_add_and_activate_connection (NMClient *client,
|
||||
gboolean is_v2,
|
||||
NMConnection *partial,
|
||||
NMDevice *device,
|
||||
const char *specific_object,
|
||||
GVariant *options,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GVariant *arg_connection = NULL;
|
||||
gboolean use_add_and_activate_v2 = FALSE;
|
||||
const char *arg_device = NULL;
|
||||
gpointer source_tag;
|
||||
|
||||
g_return_if_fail (NM_IS_CLIENT (client));
|
||||
g_return_if_fail (!partial || NM_IS_CONNECTION (partial));
|
||||
|
||||
if (device) {
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
arg_device = nm_object_get_path (NM_OBJECT (device));
|
||||
g_return_if_fail (arg_device);
|
||||
}
|
||||
|
||||
if (partial)
|
||||
arg_connection = nm_connection_to_dbus (partial, NM_CONNECTION_SERIALIZE_ALL);
|
||||
if (!arg_connection)
|
||||
arg_connection = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
|
||||
|
||||
if (is_v2) {
|
||||
if (!options)
|
||||
options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
|
||||
use_add_and_activate_v2 = TRUE;
|
||||
source_tag = nm_client_add_and_activate_connection2;
|
||||
} else {
|
||||
if (options) {
|
||||
if (g_variant_n_children (options) > 0)
|
||||
use_add_and_activate_v2 = TRUE;
|
||||
else
|
||||
nm_clear_pointer (&options, nm_g_variant_unref_floating);
|
||||
}
|
||||
source_tag = nm_client_add_and_activate_connection_async;
|
||||
}
|
||||
|
||||
if (use_add_and_activate_v2) {
|
||||
_nm_object_dbus_call (client,
|
||||
source_tag,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data,
|
||||
NM_DBUS_PATH,
|
||||
NM_DBUS_INTERFACE,
|
||||
"AddAndActivateConnection2",
|
||||
g_variant_new ("(@a{sa{sv}}oo@a{sv})",
|
||||
arg_connection,
|
||||
arg_device ?: "/",
|
||||
specific_object ?: "/",
|
||||
options),
|
||||
G_VARIANT_TYPE ("(ooa{sv})"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
NM_DBUS_DEFAULT_TIMEOUT_MSEC,
|
||||
_add_and_activate_connection_v2_cb);
|
||||
} else {
|
||||
_nm_object_dbus_call (client,
|
||||
source_tag,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data,
|
||||
NM_DBUS_PATH,
|
||||
NM_DBUS_INTERFACE,
|
||||
"AddAndActivateConnection",
|
||||
g_variant_new ("(@a{sa{sv}}oo)",
|
||||
arg_connection,
|
||||
arg_device ?: "/",
|
||||
specific_object ?: "/"),
|
||||
G_VARIANT_TYPE ("(oo)"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
NM_DBUS_DEFAULT_TIMEOUT_MSEC,
|
||||
_add_and_activate_connection_v1_cb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1254,6 +1392,7 @@ 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.
|
||||
* If the variant is floating, it will be consumed.
|
||||
* @cancellable: a #GCancellable, or %NULL
|
||||
* @callback: callback to be called when the activation has started
|
||||
* @user_data: caller-specific data passed to @callback
|
||||
|
@ -1278,32 +1417,15 @@ nm_client_add_and_activate_connection_async (NMClient *client,
|
|||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
GError *error = NULL;
|
||||
|
||||
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_check_nm_running (client, &error)) {
|
||||
g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
|
||||
return;
|
||||
}
|
||||
|
||||
simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
|
||||
nm_client_add_and_activate_connection_async);
|
||||
if (cancellable)
|
||||
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
||||
nm_manager_add_and_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager,
|
||||
partial,
|
||||
device,
|
||||
specific_object,
|
||||
NULL,
|
||||
FALSE,
|
||||
cancellable,
|
||||
add_activate_cb,
|
||||
simple);
|
||||
_add_and_activate_connection (client,
|
||||
FALSE,
|
||||
partial,
|
||||
device,
|
||||
specific_object,
|
||||
NULL,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1325,17 +1447,15 @@ nm_client_add_and_activate_connection_finish (NMClient *client,
|
|||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
_NMActivateResult *r;
|
||||
nm_auto_free_activate_result _NMActivateResult *r = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
|
||||
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
|
||||
g_return_val_if_fail (nm_g_task_is_valid (result, client, nm_client_add_and_activate_connection_async), NULL);
|
||||
|
||||
simple = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (simple, error))
|
||||
r = g_task_propagate_pointer (G_TASK (result), error);
|
||||
if (!r)
|
||||
return NULL;
|
||||
r = g_simple_async_result_get_op_res_gpointer (simple);
|
||||
return g_object_ref (r->active);
|
||||
return g_steal_pointer (&r->active);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1391,32 +1511,15 @@ nm_client_add_and_activate_connection2 (NMClient *client,
|
|||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
GError *error = NULL;
|
||||
|
||||
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_check_nm_running (client, &error)) {
|
||||
g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
|
||||
return;
|
||||
}
|
||||
|
||||
simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
|
||||
nm_client_add_and_activate_connection2);
|
||||
if (cancellable)
|
||||
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
||||
nm_manager_add_and_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->manager,
|
||||
partial,
|
||||
device,
|
||||
specific_object,
|
||||
options,
|
||||
TRUE,
|
||||
cancellable,
|
||||
add_activate_cb,
|
||||
simple);
|
||||
_add_and_activate_connection (client,
|
||||
TRUE,
|
||||
partial,
|
||||
device,
|
||||
specific_object,
|
||||
options,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1442,20 +1545,18 @@ nm_client_add_and_activate_connection2_finish (NMClient *client,
|
|||
GVariant **out_result,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
_NMActivateResult *r;
|
||||
nm_auto_free_activate_result _NMActivateResult *r = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
|
||||
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
|
||||
g_return_val_if_fail (nm_g_task_is_valid (result, client, nm_client_add_and_activate_connection2), NULL);
|
||||
|
||||
simple = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (simple, error)) {
|
||||
r = g_task_propagate_pointer (G_TASK (result), error);
|
||||
if (!r) {
|
||||
NM_SET_OUT (out_result, NULL);
|
||||
return NULL;
|
||||
}
|
||||
r = g_simple_async_result_get_op_res_gpointer (simple);
|
||||
NM_SET_OUT (out_result, nm_g_variant_ref (r->add_and_activate_output));
|
||||
return g_object_ref (r->active);
|
||||
NM_SET_OUT (out_result, g_steal_pointer (&r->add_and_activate_output));
|
||||
return g_steal_pointer (&r->active);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -58,7 +58,7 @@ typedef struct {
|
|||
/* Activations waiting for their NMActiveConnection
|
||||
* to appear and then their callback to be called.
|
||||
*/
|
||||
CList pending_activations;
|
||||
CList wait_for_active_connection_lst_head;
|
||||
|
||||
gboolean networking_enabled;
|
||||
gboolean wireless_enabled;
|
||||
|
@ -170,7 +170,7 @@ nm_manager_init (NMManager *manager)
|
|||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
c_list_init (&priv->pending_activations);
|
||||
c_list_init (&priv->wait_for_active_connection_lst_head);
|
||||
|
||||
priv->state = NM_STATE_UNKNOWN;
|
||||
priv->connectivity = NM_CONNECTIVITY_UNKNOWN;
|
||||
|
@ -850,10 +850,8 @@ typedef enum {
|
|||
typedef struct {
|
||||
CList lst;
|
||||
NMManager *manager;
|
||||
GSimpleAsyncResult *simple;
|
||||
GCancellable *cancellable;
|
||||
GTask *task;
|
||||
char *active_path;
|
||||
char *new_connection_path;
|
||||
GVariant *add_and_activate_output;
|
||||
gulong cancelled_id;
|
||||
ActivateType activate_type;
|
||||
|
@ -871,7 +869,7 @@ _nm_activate_result_new (NMActiveConnection *active,
|
|||
r = g_slice_new (_NMActivateResult);
|
||||
*r = (_NMActivateResult) {
|
||||
.active = g_object_ref (active),
|
||||
.add_and_activate_output = nm_g_variant_ref (add_and_activate_output),
|
||||
.add_and_activate_output = g_steal_pointer (&add_and_activate_output),
|
||||
};
|
||||
return r;
|
||||
}
|
||||
|
@ -879,7 +877,7 @@ _nm_activate_result_new (NMActiveConnection *active,
|
|||
void
|
||||
_nm_activate_result_free (_NMActivateResult *result)
|
||||
{
|
||||
g_object_unref (result->active);
|
||||
nm_g_object_unref (result->active);
|
||||
nm_g_variant_unref (result->add_and_activate_output);
|
||||
g_slice_free (_NMActivateResult, result);
|
||||
}
|
||||
|
@ -889,27 +887,27 @@ activate_info_complete (ActivateInfo *info,
|
|||
NMActiveConnection *active,
|
||||
GError *error)
|
||||
{
|
||||
nm_assert (info);
|
||||
nm_assert (info->task);
|
||||
nm_assert (G_IS_TASK (info->task));
|
||||
nm_assert ((!error) != (!active));
|
||||
|
||||
nm_clear_g_signal_handler (info->cancellable, &info->cancelled_id);
|
||||
|
||||
c_list_unlink_stale (&info->lst);
|
||||
|
||||
if (active) {
|
||||
g_simple_async_result_set_op_res_gpointer (info->simple,
|
||||
_nm_activate_result_new (active,
|
||||
info->add_and_activate_output),
|
||||
(GDestroyNotify) _nm_activate_result_free);
|
||||
} else
|
||||
g_simple_async_result_set_from_error (info->simple, error);
|
||||
nm_clear_g_signal_handler (g_task_get_cancellable (info->task), &info->cancelled_id);
|
||||
|
||||
g_simple_async_result_complete (info->simple);
|
||||
if (error)
|
||||
g_task_return_error (info->task, error);
|
||||
else {
|
||||
g_task_return_pointer (info->task,
|
||||
_nm_activate_result_new (active,
|
||||
g_steal_pointer (&info->add_and_activate_output)),
|
||||
(GDestroyNotify) _nm_activate_result_free);
|
||||
}
|
||||
|
||||
nm_g_variant_unref (info->add_and_activate_output);
|
||||
g_free (info->active_path);
|
||||
g_free (info->new_connection_path);
|
||||
g_object_unref (info->simple);
|
||||
nm_g_object_unref (info->cancellable);
|
||||
g_object_unref (info->task);
|
||||
g_slice_free (ActivateInfo, info);
|
||||
}
|
||||
|
||||
|
@ -931,15 +929,14 @@ find_active_connection_by_path (NMManager *self, const char *ac_path)
|
|||
}
|
||||
|
||||
static void
|
||||
recheck_pending_activations (NMManager *self)
|
||||
_wait_for_active_connections_check (NMManager *self)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
CList *iter, *safe;
|
||||
CList *iter;
|
||||
NMActiveConnection *candidate;
|
||||
const GPtrArray *devices;
|
||||
NMDevice *device;
|
||||
GDBusObjectManager *object_manager = NULL;
|
||||
GError *error;
|
||||
GDBusObjectManager *object_manager;
|
||||
|
||||
object_manager = _nm_object_get_dbus_object_manager (NM_OBJECT (self));
|
||||
|
||||
|
@ -948,23 +945,23 @@ recheck_pending_activations (NMManager *self)
|
|||
* device have both updated their properties to point to each other, and
|
||||
* call the pending connection's callback.
|
||||
*/
|
||||
c_list_for_each_safe (iter, safe, &priv->pending_activations) {
|
||||
again:
|
||||
c_list_for_each (iter, &priv->wait_for_active_connection_lst_head) {
|
||||
ActivateInfo *info = c_list_entry (iter, ActivateInfo, lst);
|
||||
gs_unref_object GDBusObject *dbus_obj = NULL;
|
||||
|
||||
if (!info->active_path)
|
||||
continue;
|
||||
nm_assert (info->active_path);
|
||||
|
||||
/* Check that the object manager still knows about the object.
|
||||
* It could be that it vanished before we even learned its name. */
|
||||
dbus_obj = g_dbus_object_manager_get_object (object_manager, info->active_path);
|
||||
if (!dbus_obj) {
|
||||
error = g_error_new_literal (NM_CLIENT_ERROR,
|
||||
NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
|
||||
_("Active connection removed before it was initialized"));
|
||||
activate_info_complete (info, NULL, error);
|
||||
g_clear_error (&error);
|
||||
break;
|
||||
activate_info_complete (info,
|
||||
NULL,
|
||||
g_error_new_literal (NM_CLIENT_ERROR,
|
||||
NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
|
||||
_("Active connection removed before it was initialized")));
|
||||
goto again;
|
||||
}
|
||||
|
||||
candidate = find_active_connection_by_path (self, info->active_path);
|
||||
|
@ -983,246 +980,72 @@ recheck_pending_activations (NMManager *self)
|
|||
}
|
||||
|
||||
activate_info_complete (info, candidate, NULL);
|
||||
break;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
activation_cancelled (GCancellable *cancellable,
|
||||
gpointer user_data)
|
||||
_wait_for_active_connection_cancelled_cb (GCancellable *cancellable,
|
||||
gpointer user_data)
|
||||
{
|
||||
ActivateInfo *info = user_data;
|
||||
GError *error = NULL;
|
||||
gs_free_error 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)
|
||||
{
|
||||
ActivateInfo *info = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
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->manager);
|
||||
} else {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
activate_info_complete (info, NULL, error);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
activate_info_complete (info, NULL, g_steal_pointer (&error));
|
||||
}
|
||||
|
||||
void
|
||||
nm_manager_activate_connection_async (NMManager *manager,
|
||||
NMConnection *connection,
|
||||
NMDevice *device,
|
||||
const char *specific_object,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
nm_manager_wait_for_active_connection (NMManager *self,
|
||||
const char *active_path,
|
||||
const char *connection_path,
|
||||
GVariant *add_and_activate_output_take,
|
||||
GTask *task_take)
|
||||
{
|
||||
NMManagerPrivate *priv;
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
gs_unref_object GTask *task = task_take;
|
||||
gs_unref_variant GVariant *add_and_activate_output = add_and_activate_output_take;
|
||||
ActivateInfo *info;
|
||||
GCancellable *cancellable;
|
||||
|
||||
g_return_if_fail (NM_IS_MANAGER (manager));
|
||||
if (device)
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
if (connection)
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
nm_assert (NM_IS_MANAGER (self));
|
||||
nm_assert (active_path);
|
||||
nm_assert (G_IS_TASK (task));
|
||||
|
||||
priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||
/* FIXME: there is no timeout for how long we wait. But this entire
|
||||
* code will be reworked, also that we have a suitable GMainContext
|
||||
* where we can schedule the timeout (we shouldn't use g_main_context_default()). */
|
||||
|
||||
info = g_slice_new0 (ActivateInfo);
|
||||
info->activate_type = ACTIVATE_TYPE_ACTIVATE_CONNECTION;
|
||||
info->manager = manager;
|
||||
info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
|
||||
nm_manager_activate_connection_async);
|
||||
if (cancellable)
|
||||
g_simple_async_result_set_check_cancellable (info->simple, cancellable);
|
||||
info->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
|
||||
info = g_slice_new (ActivateInfo);
|
||||
*info = (ActivateInfo) {
|
||||
.manager = g_object_ref (self),
|
||||
.task = g_steal_pointer (&task),
|
||||
.active_path = g_strdup (active_path),
|
||||
.add_and_activate_output = g_steal_pointer (&add_and_activate_output),
|
||||
};
|
||||
c_list_link_tail (&priv->wait_for_active_connection_lst_head, &info->lst);
|
||||
|
||||
c_list_link_tail (&priv->pending_activations, &info->lst);
|
||||
|
||||
nmdbus_manager_call_activate_connection (priv->proxy,
|
||||
connection ? nm_connection_get_path (connection) : "/",
|
||||
device ? nm_object_get_path (NM_OBJECT (device)) : "/",
|
||||
specific_object ?: "/",
|
||||
cancellable,
|
||||
activate_cb, info);
|
||||
}
|
||||
|
||||
NMActiveConnection *
|
||||
nm_manager_activate_connection_finish (NMManager *manager,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
_NMActivateResult *r;
|
||||
|
||||
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_activate_connection_async), NULL);
|
||||
|
||||
simple = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (simple, error))
|
||||
return NULL;
|
||||
|
||||
r = g_simple_async_result_get_op_res_gpointer (simple);
|
||||
return g_object_ref (r->active);
|
||||
}
|
||||
|
||||
static void
|
||||
add_activate_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
ActivateInfo *info = user_data;
|
||||
gs_free_error GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
nm_assert (info);
|
||||
nm_assert (!info->active_path);
|
||||
nm_assert (!info->add_and_activate_output);
|
||||
|
||||
if (info->activate_type == ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION) {
|
||||
success = nmdbus_manager_call_add_and_activate_connection_finish (NMDBUS_MANAGER (object),
|
||||
NULL,
|
||||
&info->active_path,
|
||||
result,
|
||||
&error);
|
||||
} else {
|
||||
success = nmdbus_manager_call_add_and_activate_connection2_finish (NMDBUS_MANAGER (object),
|
||||
NULL,
|
||||
&info->active_path,
|
||||
&info->add_and_activate_output,
|
||||
result,
|
||||
&error);
|
||||
}
|
||||
if (!success) {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
activate_info_complete (info, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->cancellable) {
|
||||
info->cancelled_id = g_signal_connect (info->cancellable, "cancelled",
|
||||
G_CALLBACK (activation_cancelled), info);
|
||||
}
|
||||
|
||||
recheck_pending_activations (info->manager);
|
||||
}
|
||||
|
||||
void
|
||||
nm_manager_add_and_activate_connection_async (NMManager *manager,
|
||||
NMConnection *partial,
|
||||
NMDevice *device,
|
||||
const char *specific_object,
|
||||
GVariant *options,
|
||||
gboolean force_v2,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMManagerPrivate *priv;
|
||||
GVariant *dict = NULL;
|
||||
ActivateInfo *info;
|
||||
ActivateType activate_type = ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION;
|
||||
|
||||
g_return_if_fail (NM_IS_MANAGER (manager));
|
||||
g_return_if_fail (NM_IS_DEVICE (device));
|
||||
if (partial)
|
||||
g_return_if_fail (NM_IS_CONNECTION (partial));
|
||||
|
||||
priv = NM_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
info = g_slice_new0 (ActivateInfo);
|
||||
info->manager = manager;
|
||||
info->simple = g_simple_async_result_new (G_OBJECT (manager), callback, user_data,
|
||||
nm_manager_add_and_activate_connection_async);
|
||||
if (cancellable)
|
||||
g_simple_async_result_set_check_cancellable (info->simple, cancellable);
|
||||
info->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
|
||||
|
||||
c_list_link_tail (&priv->pending_activations, &info->lst);
|
||||
|
||||
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);
|
||||
if (force_v2) {
|
||||
if (!options)
|
||||
options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
|
||||
activate_type = ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2;
|
||||
} else {
|
||||
if (options) {
|
||||
if (g_variant_n_children (options) > 0)
|
||||
activate_type = ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2;
|
||||
else
|
||||
nm_g_variant_unref_floating (options);
|
||||
cancellable = g_task_get_cancellable (info->task);
|
||||
if (cancellable) {
|
||||
info->cancelled_id = g_signal_connect (cancellable,
|
||||
"cancelled",
|
||||
G_CALLBACK (_wait_for_active_connection_cancelled_cb),
|
||||
info);
|
||||
if (g_cancellable_is_cancelled (cancellable)) {
|
||||
_wait_for_active_connection_cancelled_cb (cancellable, info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info->activate_type = activate_type;
|
||||
|
||||
if (activate_type == ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2) {
|
||||
nmdbus_manager_call_add_and_activate_connection2 (priv->proxy,
|
||||
dict,
|
||||
nm_object_get_path (NM_OBJECT (device)),
|
||||
specific_object ?: "/",
|
||||
options,
|
||||
cancellable,
|
||||
add_activate_cb,
|
||||
info);
|
||||
} else {
|
||||
nmdbus_manager_call_add_and_activate_connection (priv->proxy,
|
||||
dict,
|
||||
nm_object_get_path (NM_OBJECT (device)),
|
||||
specific_object ?: "/",
|
||||
cancellable,
|
||||
add_activate_cb,
|
||||
info);
|
||||
}
|
||||
}
|
||||
|
||||
NMActiveConnection *
|
||||
nm_manager_add_and_activate_connection_finish (NMManager *manager,
|
||||
GAsyncResult *result,
|
||||
GVariant **out_result,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
_NMActivateResult *r;
|
||||
|
||||
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (manager), nm_manager_add_and_activate_connection_async), NULL);
|
||||
|
||||
simple = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (simple, error)) {
|
||||
NM_SET_OUT (out_result, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = g_simple_async_result_get_op_res_gpointer (simple);
|
||||
NM_SET_OUT (out_result, nm_g_variant_ref (r->add_and_activate_output));
|
||||
return g_object_ref (r->active);
|
||||
_wait_for_active_connections_check (self);
|
||||
}
|
||||
|
||||
static void
|
||||
device_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
||||
{
|
||||
NMManager *self = user_data;
|
||||
|
||||
recheck_pending_activations (self);
|
||||
_wait_for_active_connections_check (user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1241,9 +1064,7 @@ device_removed (NMManager *self, NMDevice *device)
|
|||
static void
|
||||
ac_devices_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
|
||||
{
|
||||
NMManager *self = user_data;
|
||||
|
||||
recheck_pending_activations (self);
|
||||
_wait_for_active_connections_check (user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1251,14 +1072,14 @@ active_connection_added (NMManager *self, NMActiveConnection *ac)
|
|||
{
|
||||
g_signal_connect_object (ac, "notify::" NM_ACTIVE_CONNECTION_DEVICES,
|
||||
G_CALLBACK (ac_devices_changed), self, 0);
|
||||
recheck_pending_activations (self);
|
||||
_wait_for_active_connections_check (self);
|
||||
}
|
||||
|
||||
static void
|
||||
active_connection_removed (NMManager *self, NMActiveConnection *ac)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (ac, G_CALLBACK (ac_devices_changed), self);
|
||||
recheck_pending_activations (self);
|
||||
_wait_for_active_connections_check (self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1767,6 +1588,8 @@ dispose (GObject *object)
|
|||
NMManager *manager = NM_MANAGER (object);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
|
||||
|
||||
nm_assert (c_list_is_empty (&priv->wait_for_active_connection_lst_head));
|
||||
|
||||
nm_clear_g_cancellable (&priv->perm_call_cancellable);
|
||||
|
||||
if (priv->devices) {
|
||||
|
@ -1786,11 +1609,6 @@ dispose (GObject *object)
|
|||
|
||||
g_clear_object (&priv->proxy);
|
||||
|
||||
/* Each activation should hold a ref on @manager, so if we're being disposed,
|
||||
* there shouldn't be any pending.
|
||||
*/
|
||||
g_warn_if_fail (c_list_is_empty (&priv->pending_activations));
|
||||
|
||||
g_hash_table_destroy (priv->permissions);
|
||||
priv->permissions = NULL;
|
||||
|
||||
|
|
|
@ -155,30 +155,11 @@ const GPtrArray *nm_manager_get_active_connections (NMManager *manager);
|
|||
NMActiveConnection *nm_manager_get_primary_connection (NMManager *manager);
|
||||
NMActiveConnection *nm_manager_get_activating_connection (NMManager *manager);
|
||||
|
||||
void nm_manager_activate_connection_async (NMManager *manager,
|
||||
NMConnection *connection,
|
||||
NMDevice *device,
|
||||
const char *specific_object,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
NMActiveConnection *nm_manager_activate_connection_finish (NMManager *manager,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
void nm_manager_add_and_activate_connection_async (NMManager *manager,
|
||||
NMConnection *partial,
|
||||
NMDevice *device,
|
||||
const char *specific_object,
|
||||
GVariant *options,
|
||||
gboolean force_v2,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
NMActiveConnection *nm_manager_add_and_activate_connection_finish (NMManager *manager,
|
||||
GAsyncResult *result,
|
||||
GVariant **out_result,
|
||||
GError **error);
|
||||
void nm_manager_wait_for_active_connection (NMManager *self,
|
||||
const char *active_path,
|
||||
const char *connection_path,
|
||||
GVariant *add_and_activate_output_take,
|
||||
GTask *task_take);
|
||||
|
||||
const GPtrArray *nm_manager_get_checkpoints (NMManager *manager);
|
||||
void nm_manager_checkpoint_create (NMManager *manager,
|
||||
|
@ -229,6 +210,9 @@ _NMActivateResult *_nm_activate_result_new (NMActiveConnection *active,
|
|||
|
||||
void _nm_activate_result_free (_NMActivateResult *result);
|
||||
|
||||
NM_AUTO_DEFINE_FCN0 (_NMActivateResult *, _nm_auto_free_activate_result, _nm_activate_result_free)
|
||||
#define nm_auto_free_activate_result nm_auto(_nm_auto_free_activate_result)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void nm_manager_reload (NMManager *manager,
|
||||
|
|
Loading…
Reference in a new issue