diff options
-rw-r--r-- | src/mcd-account-manager.c | 3 | ||||
-rw-r--r-- | src/mcd-account-priv.h | 4 | ||||
-rw-r--r-- | src/mcd-account.c | 88 | ||||
-rw-r--r-- | src/mcd-connection.c | 410 | ||||
-rw-r--r-- | src/mcd-service.c | 8 | ||||
-rw-r--r-- | test/twisted/account-manager/reconnect.py | 75 |
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) |