tui: improve tracking of activation state

nmtui determines the activation result by tracking the active
connection state but that is not enough, as the active connection may
disappear or because we need to consider also the device state in some
particular cases.

Use the same logic implemented in nmcli that is now provided by the
nmc_activation_get_effective_state() helper.
This commit is contained in:
Beniamino Galvani 2017-10-12 15:43:09 +02:00
parent 1824cc9e3f
commit c898594c71

View file

@ -36,6 +36,7 @@
#include "nmt-password-dialog.h"
#include "nm-secret-agent-simple.h"
#include "nm-vpn-helpers.h"
#include "nm-client-utils.h"
#include "nmt-utils.h"
/**
@ -148,38 +149,60 @@ secrets_requested (NMSecretAgentSimple *agent,
g_object_unref (form);
}
typedef struct {
NMDevice *device;
NMActiveConnection *active;
NmtSyncOp *op;
} ActivateConnectionInfo;
static void
connect_cancelled (NmtNewtForm *form,
gpointer user_data)
{
NmtSyncOp *op = user_data;
ActivateConnectionInfo *info = user_data;
GError *error = NULL;
error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CANCELLED, "Cancelled");
nmt_sync_op_complete_boolean (op, FALSE, error);
nmt_sync_op_complete_boolean (info->op, FALSE, error);
g_clear_error (&error);
}
static void
check_activated (ActivateConnectionInfo *info)
{
NMActiveConnectionState ac_state;
const char *reason = NULL;
gs_free_error GError *error = NULL;
ac_state = nmc_activation_get_effective_state (info->active, info->device, &reason);
if (!NM_IN_SET (ac_state,
NM_ACTIVE_CONNECTION_STATE_ACTIVATED,
NM_ACTIVE_CONNECTION_STATE_DEACTIVATED))
return;
if (ac_state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
nm_assert (reason);
error = g_error_new (NM_CLIENT_ERROR, NM_CLIENT_ERROR_FAILED,
_("Activation failed: %s"), reason);
}
nmt_sync_op_complete_boolean (info->op, error == NULL, error);
}
static void
activate_ac_state_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
NmtSyncOp *op = user_data;
NMActiveConnectionState state;
GError *error = NULL;
check_activated (user_data);
}
state = nm_active_connection_get_state (NM_ACTIVE_CONNECTION (object));
if (state == NM_ACTIVE_CONNECTION_STATE_ACTIVATING)
return;
if (state != NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
error = g_error_new_literal (NM_CLIENT_ERROR, NM_CLIENT_ERROR_FAILED,
_("Activation failed"));
}
nmt_sync_op_complete_boolean (op, error == NULL, error);
g_clear_error (&error);
static void
activate_device_state_changed (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
check_activated (user_data);
}
static void
@ -226,6 +249,7 @@ activate_connection (NMConnection *connection,
const char *specific_object_path;
NMActiveConnection *ac;
GError *error = NULL;
ActivateConnectionInfo info = { };
form = g_object_new (NMT_TYPE_NEWT_FORM,
"escape-exits", TRUE,
@ -290,12 +314,18 @@ activate_connection (NMConnection *connection,
/* Now wait for the connection to actually reach the ACTIVATED state,
* allowing the user to cancel if it takes too long.
*/
nmt_sync_op_init (&op);
info.active = ac;
info.device = device;
info.op = &op;
g_signal_connect (form, "quit", G_CALLBACK (connect_cancelled), &op);
g_signal_connect (form, "quit", G_CALLBACK (connect_cancelled), &info);
g_signal_connect (ac, "notify::" NM_ACTIVE_CONNECTION_STATE,
G_CALLBACK (activate_ac_state_changed), &op);
G_CALLBACK (activate_ac_state_changed), &info);
if (device) {
g_signal_connect (device, "notify::" NM_DEVICE_STATE,
G_CALLBACK (activate_device_state_changed), &info);
}
if (!nmt_sync_op_wait_boolean (&op, &error)) {
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
@ -303,8 +333,10 @@ activate_connection (NMConnection *connection,
g_clear_error (&error);
}
g_signal_handlers_disconnect_by_func (form, G_CALLBACK (connect_cancelled), &op);
g_signal_handlers_disconnect_by_func (ac, G_CALLBACK (activate_ac_state_changed), &op);
g_signal_handlers_disconnect_by_func (form, G_CALLBACK (connect_cancelled), &info);
g_signal_handlers_disconnect_by_func (ac, G_CALLBACK (activate_ac_state_changed), &info);
if (device)
g_signal_handlers_disconnect_by_func (device, G_CALLBACK (activate_device_state_changed), &info);
done:
if (nmt_newt_widget_get_realized (NMT_NEWT_WIDGET (form)))