summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mcd-account-manager.c3
-rw-r--r--src/mcd-account-priv.h4
-rw-r--r--src/mcd-account.c88
-rw-r--r--src/mcd-connection.c410
-rw-r--r--src/mcd-service.c8
-rw-r--r--test/twisted/account-manager/reconnect.py75
6 files changed, 157 insertions, 431 deletions
diff --git a/src/mcd-account-manager.c b/src/mcd-account-manager.c
index 70d9faa6..0f40673b 100644
--- a/src/mcd-account-manager.c
+++ b/src/mcd-account-manager.c
@@ -404,7 +404,8 @@ complete_account_creation (McdAccount *account,
return;
}
- ok = _mcd_account_set_parameters (account, cad->parameters, NULL, &error);
+ ok = _mcd_account_set_parameters (account, cad->parameters, NULL, NULL,
+ &error);
if (ok && cad->properties != NULL)
{
diff --git a/src/mcd-account-priv.h b/src/mcd-account-priv.h
index 2db17f81..0bc9432f 100644
--- a/src/mcd-account-priv.h
+++ b/src/mcd-account-priv.h
@@ -39,10 +39,8 @@ G_GNUC_INTERNAL void _mcd_account_connect (McdAccount *account,
G_GNUC_INTERNAL gboolean _mcd_account_set_parameters (McdAccount *account,
GHashTable *params,
const gchar **unset,
+ GPtrArray *not_yet,
GError **error);
-G_GNUC_INTERNAL void _mcd_account_set_parameter (McdAccount *account,
- const gchar *name,
- const GValue *value);
G_GNUC_INTERNAL void _mcd_account_request_temporary_presence (McdAccount *self,
TpConnectionPresenceType type, const gchar *status);
diff --git a/src/mcd-account.c b/src/mcd-account.c
index 2d55a9db..9d00e48f 100644
--- a/src/mcd-account.c
+++ b/src/mcd-account.c
@@ -1311,16 +1311,34 @@ mcd_account_check_parameters (McdAccount *account)
* Sets the parameter @name to the value in @value. If @value, is %NULL, the
* parameter is unset.
*/
-void
+static void
_mcd_account_set_parameter (McdAccount *account, const gchar *name,
const GValue *value)
{
MCD_ACCOUNT_GET_CLASS (account)->set_parameter (account, name, value);
}
+/*
+ * _mcd_account_set_parameters:
+ * @account: the #McdAccount.
+ * @name: the parameter name.
+ * @params: names and values of parameters to set
+ * @unset: names of parameters to unset
+ * @not_yet: if not %NULL, borrowed names of parameters that cannot take
+ * effect until Reconnect() is called will be appended to this array
+ *
+ * Alter the account parameters.
+ *
+ * For the moment, the account will automatically be reconnected if anything
+ * is appended to @not_yet, in violation of telepathy-spec (fd.o #21154).
+ *
+ * Returns: %TRUE (possibly appending borrowed strings to @not_yet) on success,
+ * %FALSE (setting @error) on failure
+ */
gboolean
_mcd_account_set_parameters (McdAccount *account, GHashTable *params,
- const gchar ** unset, GError **error)
+ const gchar ** unset, GPtrArray *not_yet,
+ GError **error)
{
McdAccountPrivate *priv = account->priv;
const TpConnectionManagerParam *param;
@@ -1385,7 +1403,16 @@ _mcd_account_set_parameters (McdAccount *account, GHashTable *params,
param->name);
}
else
+ {
+ if (not_yet != NULL)
+ {
+ /* we assume that the TpConnectionManager won't get
+ * freed */
+ g_ptr_array_add (not_yet, param->name);
+ }
+
reset_connection = TRUE;
+ }
}
g_value_unset (&old);
}
@@ -1413,6 +1440,23 @@ _mcd_account_set_parameters (McdAccount *account, GHashTable *params,
for (unset_iter = unset; *unset_iter != NULL; unset_iter++)
{
+ if (mcd_account_get_parameter (account, *unset_iter, NULL))
+ {
+ DEBUG ("unsetting %s", *unset_iter);
+ /* pessimistically assume that removing any parameter merits
+ * reconnection (in a perfect implementation, if the
+ * Has_Default flag was set we'd check whether the current
+ * value is the default already) */
+ if (not_yet != NULL)
+ {
+ /* we assume that the TpConnectionManager won't get
+ * freed */
+ g_ptr_array_add (not_yet, (gchar *) *unset_iter);
+ }
+
+ reset_connection = TRUE;
+ }
+
_mcd_account_set_parameter (account, *unset_iter, NULL);
}
}
@@ -1422,6 +1466,7 @@ _mcd_account_set_parameters (McdAccount *account, GHashTable *params,
{
if (reset_connection)
{
+ /* FIXME: telepathy-spec violation (fd.o #21154) */
DEBUG ("resetting connection");
mcd_connection_close (priv->connection);
_mcd_account_connection_begin (account);
@@ -1454,17 +1499,21 @@ account_update_parameters (McSvcAccount *self, GHashTable *set,
GHashTable *parameters;
GValue value = { 0 };
GError *error = NULL;
+ GPtrArray *not_yet;
DEBUG ("called for %s", priv->unique_name);
- if (!_mcd_account_set_parameters (account, set, unset, &error))
+ /* pessimistically assume that every parameter mentioned will be deferred
+ * until reconnection */
+ not_yet = g_ptr_array_sized_new (g_hash_table_size (set) +
+ g_strv_length ((gchar **) unset) + 1);
+
+ if (!_mcd_account_set_parameters (account, set, unset, not_yet, &error))
{
- if (!error)
- g_set_error (&error, TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
- "Internal error");
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
+ g_ptr_array_free (not_yet, TRUE);
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
}
/* emit the PropertiesChanged signal */
@@ -1476,7 +1525,13 @@ account_update_parameters (McSvcAccount *self, GHashTable *set,
mcd_account_check_validity (account);
mcd_account_manager_write_conf (priv->account_manager);
+
+ g_ptr_array_add (not_yet, NULL);
+ /* FIXME: return this over D-Bus as a gchar ** (API break) */
+ (void) not_yet->pdata;
+
mc_svc_account_return_from_update_parameters (context);
+ g_ptr_array_free (not_yet, TRUE);
}
static void
@@ -1487,6 +1542,21 @@ account_reconnect (McSvcAccount *service,
DEBUG ("%s", mcd_account_get_unique_name (self));
+ /* if we can't, or don't want to, connect this method is a no-op */
+ if (!self->priv->enabled ||
+ !self->priv->valid ||
+ self->priv->req_presence_type == TP_CONNECTION_PRESENCE_TYPE_UNSET ||
+ self->priv->req_presence_type == TP_CONNECTION_PRESENCE_TYPE_OFFLINE)
+ {
+ DEBUG ("doing nothing (enabled=%c, valid=%c and "
+ "RequestedPresence=%i)",
+ self->priv->enabled ? 'T' : 'F',
+ self->priv->valid ? 'T' : 'F',
+ self->priv->req_presence_type);
+ mc_svc_account_return_from_reconnect (context);
+ return;
+ }
+
/* FIXME: this isn't quite right. If we've just called RequestConnection
* (possibly with out of date parameters) but we haven't got a Connection
* back from the CM yet, the old parameters will still be used, I think
diff --git a/src/mcd-connection.c b/src/mcd-connection.c
index 76701bbe..db9d3443 100644
--- a/src/mcd-connection.c
+++ b/src/mcd-connection.c
@@ -72,8 +72,6 @@
#include "_gen/cli-Connection_Interface_Contact_Capabilities-body.h"
#define INITIAL_RECONNECTION_TIME 1 /* 1 second */
-#define MAX_REF_PRESENCE 4
-#define LAST_MC_PRESENCE (TP_CONNECTION_PRESENCE_TYPE_BUSY + 1)
#define MCD_CONNECTION_PRIV(mcdconn) (MCD_CONNECTION (mcdconn)->priv)
@@ -101,9 +99,6 @@ struct _McdConnectionPrivate
TpConnection *tp_conn;
TpProxySignalConnection *new_channel_sc;
- /* Capabilities timer */
- guint capabilities_timer;
-
guint reconnect_timer; /* timer for reconnection */
guint reconnect_interval;
@@ -111,7 +106,6 @@ struct _McdConnectionPrivate
GHashTable *recognized_presences;
TpConnectionStatusReason abort_reason;
- guint got_capabilities : 1;
guint got_contact_capabilities : 1;
guint setting_avatar : 1;
guint has_presence_if : 1;
@@ -150,12 +144,6 @@ typedef struct
guint can_have_message : 1;
} McdPresenceInfo;
-struct param_data
-{
- GSList *pr_params;
- GHashTable *dest;
-};
-
enum
{
PROP_0,
@@ -175,16 +163,6 @@ enum
static guint signals[N_SIGNALS] = { 0 };
-struct request_id {
- guint requestor_serial;
- const gchar *requestor_client_id;
-};
-
-struct capabilities_wait_data {
- GError *error; /* error originally received when channel request failed */
- TpProxySignalConnection *signal_connection;
-};
-
static const gchar *_available_fb[] = { NULL };
static const gchar *_away_fb[] = { "away", NULL };
static const gchar *_ext_away_fb[] = { "xa", "away", NULL };
@@ -194,15 +172,10 @@ static const gchar **presence_fallbacks[] = {
_available_fb, _away_fb, _ext_away_fb, _hidden_fb, _busy_fb
};
-static void request_channel_cb (TpConnection *proxy, const gchar *channel_path,
- const GError *error, gpointer user_data,
- GObject *weak_object);
static GError * map_tp_error_to_mc_error (McdChannel *channel, const GError *tp_error);
static void _mcd_connection_release_tp_connection (McdConnection *connection);
static gboolean request_channel_new_iface (McdConnection *connection,
McdChannel *channel);
-static gboolean request_channel_old_iface (McdConnection *connection,
- McdChannel *channel);
static void
mcd_tmp_channel_data_free (gpointer data)
@@ -565,114 +538,6 @@ _foreach_channel_remove (McdMission * mission, McdOperation * operation)
}
static void
-on_capabilities_changed (TpConnection *proxy, const GPtrArray *caps,
- gpointer user_data, GObject *weak_object)
-{
- McdConnection *connection = user_data;
- McdConnectionPrivate *priv = connection->priv;
- McdChannel *channel = MCD_CHANNEL (weak_object);
- gboolean found = FALSE;
- GType type;
- gchar *chan_type;
- guint chan_handle, chan_handle_type;
- TpProxyPendingCall *call;
- guint i;
-
- DEBUG ("got capabilities for channel %p handle %d, type %s",
- channel, mcd_channel_get_handle (channel),
- mcd_channel_get_channel_type (channel));
- type = dbus_g_type_get_struct ("GValueArray", G_TYPE_UINT, G_TYPE_STRING,
- G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT,
- G_TYPE_UINT, G_TYPE_INVALID);
- for (i = 0; i < caps->len; i++)
- {
- GValue cap = { 0 };
-
- g_value_init (&cap, type);
- g_value_set_static_boxed (&cap, g_ptr_array_index(caps, i));
- dbus_g_type_struct_get (&cap, 0, &chan_handle, 1, &chan_type, G_MAXUINT);
- if (chan_handle == mcd_channel_get_handle (channel) &&
- strcmp (chan_type, mcd_channel_get_channel_type (channel)) == 0)
- {
- found = TRUE;
- break;
- }
- g_free (chan_type);
- }
-
- if (!found) return;
- /* Return also if the "tp_chan_call" data is set (which means that a
- * request for this channel has already been made) */
- if (g_object_get_data (G_OBJECT (channel), "tp_chan_call") != NULL)
- goto done;
- chan_handle_type = mcd_channel_get_handle_type (channel);
- DEBUG ("requesting channel again (type = %s, handle_type = %u, handle = %u)",
- chan_type, chan_handle_type, chan_handle);
- call = tp_cli_connection_call_request_channel (priv->tp_conn, -1,
- chan_type,
- chan_handle_type,
- chan_handle, TRUE,
- request_channel_cb,
- connection, NULL,
- (GObject *)channel);
- g_object_set_data ((GObject *)channel, "tp_chan_call", call);
-done:
- g_free (chan_type);
-}
-
-static gboolean
-on_channel_capabilities_timeout (McdChannel *channel,
- McdConnection *connection)
-{
- struct capabilities_wait_data *cwd;
- GError *mc_error;
-
- cwd = g_object_get_data (G_OBJECT (channel), "error_on_creation");
- if (!cwd) return FALSE;
-
- /* We reach this point if this channel was waiting for capabilities; we
- * abort it and return the original error */
- DEBUG ("channel %p timed out, returning error!", channel);
-
- mc_error = map_tp_error_to_mc_error (channel, cwd->error);
- mcd_channel_take_error (channel, mc_error);
- g_object_set_data (G_OBJECT (channel), "error_on_creation", NULL);
-
- /* No abort on channel, because we are the only one holding the only
- * reference to this temporary channel.
- */
- return TRUE;
-}
-
-static gboolean
-on_capabilities_timeout (McdConnection *connection)
-{
- McdConnectionPrivate *priv = MCD_CONNECTION_PRIV (connection);
- const GList *list, *list_curr;
-
- DEBUG ("got_capabilities is %d", priv->got_capabilities);
- priv->got_capabilities = TRUE;
- list = mcd_operation_get_missions ((McdOperation *)connection);
- while (list)
- {
- McdChannel *channel = MCD_CHANNEL (list->data);
- McdChannelStatus status;
-
- list_curr = list;
- list = list->next;
- status = mcd_channel_get_status (channel);
- if ((status == MCD_CHANNEL_STATUS_REQUEST ||
- status == MCD_CHANNEL_STATUS_REQUESTED) &&
- on_channel_capabilities_timeout (channel, connection))
- {
- mcd_mission_abort ((McdMission *)channel);
- }
- }
- priv->capabilities_timer = 0;
- return FALSE;
-}
-
-static void
capabilities_advertise_cb (TpConnection *proxy, const GPtrArray *out0,
const GError *error, gpointer user_data,
GObject *weak_object)
@@ -697,7 +562,6 @@ _mcd_connection_setup_capabilities (McdConnection *connection)
if (!priv->has_capabilities_if)
{
DEBUG ("connection does not support capabilities interface");
- priv->got_capabilities = TRUE;
return;
}
protocol_name = mcd_account_get_protocol_name (priv->account);
@@ -710,14 +574,6 @@ _mcd_connection_setup_capabilities (McdConnection *connection)
capabilities_advertise_cb,
priv, NULL,
(GObject *) connection);
- if (priv->capabilities_timer)
- {
- g_warning ("This connection still has dangling capabilities timer on");
- g_source_remove (priv->capabilities_timer);
- }
- priv->capabilities_timer =
- g_timeout_add_seconds (10, (GSourceFunc)on_capabilities_timeout,
- connection);
/* free the connection capabilities */
type = dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING,
@@ -1162,7 +1018,7 @@ on_connection_status_changed (TpConnection *tp_conn, GParamSpec *pspec,
}
}
-static void proxy_destroyed (DBusGProxy *tp_conn, guint domain, gint code,
+static void proxy_destroyed (TpConnection *tp_conn, guint domain, gint code,
gchar *message, McdConnection *connection)
{
McdConnectionPrivate *priv = MCD_CONNECTION_PRIV (connection);
@@ -1170,13 +1026,6 @@ static void proxy_destroyed (DBusGProxy *tp_conn, guint domain, gint code,
_mcd_connection_release_tp_connection (connection);
- /* Destroy any pending timer */
- if (priv->capabilities_timer)
- {
- g_source_remove (priv->capabilities_timer);
- priv->capabilities_timer = 0;
- }
-
if (priv->abort_reason == TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED ||
priv->abort_reason == TP_CONNECTION_STATUS_REASON_NETWORK_ERROR ||
priv->abort_reason == TP_CONNECTION_STATUS_REASON_NAME_IN_USE)
@@ -1719,8 +1568,7 @@ _mcd_connection_dispose (GObject * object)
/* Remove any pending source: timer and idle */
g_source_remove_by_user_data (connection);
- priv->capabilities_timer = 0;
-
+
mcd_operation_foreach (MCD_OPERATION (connection),
(GFunc) _foreach_channel_remove, connection);
@@ -1916,7 +1764,14 @@ _mcd_connection_request_channel (McdConnection *connection,
if (priv->has_requests_if)
ret = request_channel_new_iface (connection, channel);
else
- ret = request_channel_old_iface (connection, channel);
+ {
+ mcd_channel_take_error (channel,
+ g_error_new (TP_ERRORS,
+ TP_ERROR_NOT_IMPLEMENTED,
+ "No Requests interface"));
+ mcd_mission_abort ((McdMission *) channel);
+ return TRUE;
+ }
if (ret)
_mcd_channel_set_status (channel, MCD_CHANNEL_STATUS_REQUESTED);
@@ -2040,198 +1895,6 @@ map_tp_error_to_mc_error (McdChannel *channel, const GError *error)
}
static void
-remove_capabilities_refs (gpointer data)
-{
- struct capabilities_wait_data *cwd = data;
-
- DEBUG ("called");
- tp_proxy_signal_connection_disconnect (cwd->signal_connection);
- g_error_free (cwd->error);
- g_free (cwd);
-}
-
-static void
-request_channel_cb (TpConnection *proxy, const gchar *channel_path,
- const GError *tp_error, gpointer user_data,
- GObject *weak_object)
-{
- McdChannel *channel = MCD_CHANNEL (weak_object);
- McdConnection *connection = user_data;
- McdConnectionPrivate *priv = connection->priv;
- GError *error_on_creation;
- struct capabilities_wait_data *cwd;
- GQuark chan_type;
- TpHandleType chan_handle_type;
- guint chan_handle;
- /* We handle only the dbus errors */
-
- /* ChannelRequestor *chan_req = (ChannelRequestor *)user_data; */
- g_object_steal_data (G_OBJECT (channel), "tp_chan_call");
-
- chan_handle = mcd_channel_get_handle (channel);
- chan_handle_type = mcd_channel_get_handle_type (channel);
- chan_type = mcd_channel_get_channel_type_quark (channel);
-
- cwd = g_object_get_data (G_OBJECT (channel), "error_on_creation");
- if (cwd)
- {
- error_on_creation = cwd->error;
- g_object_set_data (G_OBJECT (channel), "error_on_creation", NULL);
- }
- else
- error_on_creation = NULL;
-
-
- if (tp_error != NULL)
- {
- DEBUG ("got error: %s", tp_error->message);
- if (error_on_creation != NULL)
- {
- /* replace the error, so that the initial one is reported */
- tp_error = error_on_creation;
- }
-
- if (priv->got_capabilities || error_on_creation)
- {
- /* Faild dispatch */
- GError *mc_error = map_tp_error_to_mc_error (channel, tp_error);
- mcd_channel_take_error (channel, mc_error);
- mcd_mission_abort ((McdMission *)channel);
- }
- else
- {
- /* the channel request has failed probably because we are just
- * connected and we didn't recive the contact capabilities yet. In
- * this case, wait for this contact's capabilities to arrive */
- DEBUG ("listening for remote capabilities on channel handle %d, type %d",
- chan_handle, mcd_channel_get_handle_type (channel));
- /* Store the error, we might need it later */
- cwd = g_malloc (sizeof (struct capabilities_wait_data));
- cwd->error = g_error_copy (tp_error);
- cwd->signal_connection =
- tp_cli_connection_interface_capabilities_connect_to_capabilities_changed (priv->tp_conn,
- on_capabilities_changed,
- connection, NULL,
- (GObject *)channel,
- NULL);
- g_object_set_data_full (G_OBJECT (channel), "error_on_creation", cwd,
- remove_capabilities_refs);
- }
- return;
- }
-
- if (channel_path == NULL)
- {
- GError *mc_error;
- g_warning ("Returned channel_path from telepathy is NULL");
-
- mc_error = g_error_new (MC_ERROR,
- MC_CHANNEL_REQUEST_GENERIC_ERROR,
- "Returned channel_path from telepathy is NULL");
- mcd_channel_take_error (channel, mc_error);
- mcd_mission_abort ((McdMission *)channel);
- return;
- }
-
- /* TODO: construct the a{sv} of immutable properties */
- /* Everything here is well and fine. We can create the channel proxy. */
- if (!_mcd_channel_create_proxy (channel, priv->tp_conn,
- channel_path, NULL))
- {
- mcd_mission_abort ((McdMission *)channel);
- return;
- }
-
- /* Dispatch the incoming channel */
- _mcd_dispatcher_take_channels (priv->dispatcher,
- g_list_prepend (NULL, channel),
- TRUE);
-}
-
-static void
-request_handles_cb (TpConnection *proxy, const GArray *handles,
- const GError *error, gpointer user_data,
- GObject *weak_object)
-{
- McdChannel *channel, *existing_channel;
- McdConnection *connection = user_data;
- McdConnectionPrivate *priv = connection->priv;
- guint chan_handle, chan_handle_type;
- GQuark chan_type;
- const GList *channels;
-
- channel = MCD_CHANNEL (weak_object);
-
- if (error != NULL || g_array_index (handles, guint, 0) == 0)
- {
- GError *mc_error;
- const gchar *msg;
-
- msg = error ? error->message : "got handle 0";
- g_warning ("Could not map string handle to a valid handle!: %s",
- msg);
-
- /* Fail dispatch */
- mc_error = g_error_new (MC_ERROR, MC_INVALID_HANDLE_ERROR,
- "Could not map string handle to a valid handle!: %s",
- msg);
- mcd_channel_take_error (channel, mc_error);
-
- /* No abort, because we are the only one holding the only reference
- * to this temporary channel
- */
- g_object_unref (channel);
- return;
- }
-
- chan_type = mcd_channel_get_channel_type_quark (channel),
- chan_handle_type = mcd_channel_get_handle_type (channel),
- chan_handle = g_array_index (handles, guint, 0);
-
- DEBUG ("Got handle %u", chan_handle);
-
- /* Check if a telepathy channel has already been created; this could happen
- * in the case we had a chat window open, the UI crashed and now the same
- * channel is requested. */
- channels = mcd_operation_get_missions (MCD_OPERATION (connection));
- while (channels)
- {
- /* for calls, we probably don't want this. TODO: investigate better */
- if (chan_type == TP_IFACE_QUARK_CHANNEL_TYPE_STREAMED_MEDIA) break;
-
- existing_channel = MCD_CHANNEL (channels->data);
- DEBUG ("Chan: %d, handle type %d, channel type %s",
- mcd_channel_get_handle (existing_channel),
- mcd_channel_get_handle_type (existing_channel),
- mcd_channel_get_channel_type (existing_channel));
- if (chan_handle == mcd_channel_get_handle (existing_channel) &&
- chan_handle_type == mcd_channel_get_handle_type (existing_channel) &&
- chan_type == mcd_channel_get_channel_type_quark (existing_channel))
- {
- DEBUG ("Channel already existing, returning old one");
- /* FIXME: this situation is weird. We should have checked for the
- * existance of the channel _before_ getting here, already when
- * creating the request */
- /* we no longer need the new channel */
- g_object_unref (channel);
- /* notify the dispatcher again */
- _mcd_dispatcher_take_channels (priv->dispatcher,
- g_list_prepend (NULL,
- existing_channel),
- TRUE);
- return;
- }
- channels = channels->next;
- }
-
- /* Update our newly acquired information */
- mcd_channel_set_handle (channel, chan_handle);
-
- g_return_if_fail (chan_handle != 0);
- mcd_connection_request_channel (connection, channel);
-}
-
-static void
common_request_channel_cb (TpConnection *proxy, gboolean yours,
const gchar *channel_path, GHashTable *properties,
const GError *error,
@@ -2332,56 +1995,6 @@ request_channel_new_iface (McdConnection *connection, McdChannel *channel)
return TRUE;
}
-static gboolean
-request_channel_old_iface (McdConnection *connection, McdChannel *channel)
-{
- McdConnectionPrivate *priv = MCD_CONNECTION_PRIV (connection);
- guint channel_handle, channel_handle_type;
-
- channel_handle_type = mcd_channel_get_handle_type (channel);
- channel_handle = mcd_channel_get_handle (channel);
-
- if (channel_handle != 0 || channel_handle_type == 0)
- {
- TpProxyPendingCall *call;
- const gchar *channel_type;
-
- channel_type = mcd_channel_get_channel_type (channel);
- call = tp_cli_connection_call_request_channel (priv->tp_conn, -1,
- channel_type,
- channel_handle_type,
- channel_handle, TRUE,
- request_channel_cb,
- connection, NULL,
- (GObject *)channel);
- g_object_set_data ((GObject *)channel, "tp_chan_call", call);
- }
- else
- {
- /* if channel handle is 0, this means that the channel was requested by
- * a string handle; in that case, we must first request a channel
- * handle for it */
- const gchar *name_array[2], *target_id;
-
- target_id = _mcd_channel_get_target_id (channel);
- g_return_val_if_fail (target_id != NULL, FALSE);
- g_return_val_if_fail (channel_handle_type != 0, FALSE);
-
- name_array[0] = target_id;
- name_array[1] = NULL;
-
- /* Channel is temporary and will be added as a child mission
- * only when we successfully resolve the handle. */
- tp_cli_connection_call_request_handles (priv->tp_conn, -1,
- channel_handle_type,
- name_array,
- request_handles_cb,
- connection, NULL,
- (GObject *)channel);
- }
- return TRUE;
-}
-
gboolean
mcd_connection_request_channel (McdConnection *connection,
McdChannel *channel)
@@ -2403,13 +2016,10 @@ mcd_connection_cancel_channel_request (McdConnection *connection,
const gchar *requestor_client_id,
GError **error)
{
- struct request_id req_id;
const GList *channels, *node;
McdChannel *channel;
/* first, see if the channel is in the list of the pending channels */
- req_id.requestor_serial = operation_id;
- req_id.requestor_client_id = requestor_client_id;
channels = mcd_operation_get_missions (MCD_OPERATION (connection));
if (!channels) return FALSE;
diff --git a/src/mcd-service.c b/src/mcd-service.c
index 22cae7f4..b2de1224 100644
--- a/src/mcd-service.c
+++ b/src/mcd-service.c
@@ -63,14 +63,6 @@
#define MISSION_CONTROL_DBUS_OBJECT "/org/freedesktop/Telepathy/MissionControl"
#define MISSION_CONTROL_DBUS_IFACE "org.freedesktop.Telepathy.MissionControl"
-#define LAST_MC_PRESENCE (TP_CONNECTION_PRESENCE_TYPE_BUSY + 1)
-
-typedef enum {
- MC_STATUS_DISCONNECTED,
- MC_STATUS_CONNECTING,
- MC_STATUS_CONNECTED,
-} McStatus;
-
static GObjectClass *parent_class = NULL;
#define MCD_OBJECT_PRIV(mission) (G_TYPE_INSTANCE_GET_PRIVATE ((mission), \
diff --git a/test/twisted/account-manager/reconnect.py b/test/twisted/account-manager/reconnect.py
index 4e79c889..c9d81951 100644
--- a/test/twisted/account-manager/reconnect.py
+++ b/test/twisted/account-manager/reconnect.py
@@ -1,7 +1,8 @@
import dbus
import dbus.service
-from servicetest import EventPattern, tp_name_prefix, tp_path_prefix
+from servicetest import EventPattern, tp_name_prefix, tp_path_prefix, \
+ call_async, sync_dbus
from mctest import exec_test, SimulatedConnection, create_fakecm_account,\
SimulatedChannel
import constants as cs
@@ -15,17 +16,71 @@ def test(q, bus, mc):
"password": "secrecy"}, signature='sv')
(cm_name_ref, account) = create_fakecm_account(q, bus, mc, params)
+ # Events that indicate that Reconnect might have done something
+ looks_like_reconnection = [
+ EventPattern('dbus-method-call', method='RequestConnection'),
+ EventPattern('dbus-method-call', method='Disconnect'),
+ ]
+
+ q.forbid_events(looks_like_reconnection)
+
+ # While we want to be online but the account is disabled, Reconnect is a
+ # no-op. Set Enabled to False explicitly, so we're less reliant on initial
+ # state.
+
+ call_async(q, account, 'Set', cs.ACCOUNT, 'Enabled', False,
+ dbus_interface=cs.PROPERTIES_IFACE)
+ q.expect('dbus-return', method='Set')
+
+ requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_AVAILABLE),
+ dbus.String(u'available'), dbus.String(u'')))
+ call_async(q, account, 'Set', cs.ACCOUNT,
+ 'RequestedPresence', requested_presence,
+ dbus_interface=cs.PROPERTIES_IFACE)
+ q.expect('dbus-return', method='Set')
+
+ call_async(q, account, 'Reconnect', dbus_interface=cs.ACCOUNT)
+ q.expect('dbus-return', method='Reconnect')
+
+ sync_dbus(bus, q, account)
+
+ # While we want to be offline but the account is enabled, Reconnect is
+ # still a no-op.
+ requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_OFFLINE),
+ dbus.String(u'offline'), dbus.String(u'')))
+ call_async(q, account, 'Set', cs.ACCOUNT,
+ 'RequestedPresence', requested_presence,
+ dbus_interface=cs.PROPERTIES_IFACE)
+ q.expect_many(
+ EventPattern('dbus-return', method='Set'),
+ EventPattern('dbus-signal',
+ path=account.object_path,
+ signal='AccountPropertyChanged',
+ interface=cs.ACCOUNT),
+ )
+
# Enable the account
- account.Set(cs.ACCOUNT, 'Enabled', True,
+ call_async(q, account, 'Set', cs.ACCOUNT, 'Enabled', True,
dbus_interface=cs.PROPERTIES_IFACE)
- q.expect('dbus-signal',
- path=account.object_path,
- signal='AccountPropertyChanged',
- interface=cs.ACCOUNT)
-
- # Go online
- requested_presence = dbus.Struct((dbus.UInt32(2L), dbus.String(u'brb'),
- dbus.String(u'Be back soon!')))
+ q.expect_many(
+ EventPattern('dbus-return', method='Set'),
+ EventPattern('dbus-signal',
+ path=account.object_path,
+ signal='AccountPropertyChanged',
+ interface=cs.ACCOUNT),
+ )
+
+ call_async(q, account, 'Reconnect', dbus_interface=cs.ACCOUNT)
+ q.expect('dbus-return', method='Reconnect')
+
+ sync_dbus(bus, q, account)
+
+ # Actually go online now
+
+ q.unforbid_events(looks_like_reconnection)
+
+ requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_AVAILABLE),
+ dbus.String(u'brb'), dbus.String(u'Be back soon!')))
account.Set(cs.ACCOUNT,
'RequestedPresence', requested_presence,
dbus_interface=cs.PROPERTIES_IFACE)