[Telepathy-commits] [telepathy-mission-control/master] Implement server side of channel request cancellation

Alberto Mardegan alberto.mardegan at nokia.com
Fri Jan 9 00:39:01 PST 2009


---
 src/mcd-account-requests.c |   98 ++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/src/mcd-account-requests.c b/src/mcd-account-requests.c
index 668d51e..dd58bc9 100644
--- a/src/mcd-account-requests.c
+++ b/src/mcd-account-requests.c
@@ -59,11 +59,60 @@ online_request_cb (McdAccount *account, gpointer userdata, const GError *error)
     g_return_if_fail (mcd_connection_get_connection_status (connection)
                       == TP_CONNECTION_STATUS_CONNECTED);
 
+    if (mcd_channel_get_status (channel) == MCD_CHANNEL_STATUS_FAILED)
+    {
+        g_debug ("%s: channel %p is failed", G_STRFUNC, channel);
+        g_object_unref (channel);
+        return;
+    }
+
     /* the connection will take ownership of the channel, so the reference we
      * are holding is passed to it */
     mcd_connection_request_channel (connection, channel);
 }
 
+static McdChannel *
+get_channel_from_request (McdAccount *account, const gchar *request_id)
+{
+    McdConnection *connection;
+    const GList *channels, *list;
+
+
+    connection = mcd_account_get_connection (account);
+    if (connection)
+    {
+        channels = mcd_operation_get_missions (MCD_OPERATION (connection));
+        for (list = channels; list != NULL; list = list->next)
+        {
+            McdChannel *channel = MCD_CHANNEL (list->data);
+
+            if (g_strcmp0 (_mcd_channel_get_request_path (channel),
+                           request_id) == 0)
+                return channel;
+        }
+    }
+
+    /* if we don't have a connection in connected state yet, the channel might
+     * be in the online requests queue */
+    list = _mcd_account_get_online_requests (account);
+    while (list)
+    {
+        McdOnlineRequestData *data = list->data;
+
+        if (data->callback == online_request_cb)
+        {
+            McdChannel *channel = MCD_CHANNEL (data->user_data);
+
+            if (g_strcmp0 (_mcd_channel_get_request_path (channel),
+                           request_id) == 0)
+                return channel;
+        }
+
+        list = list->next;
+    }
+    return NULL;
+}
+
 static void
 on_channel_status_changed (McdChannel *channel, McdChannelStatus status,
                            McdAccount *account)
@@ -195,11 +244,52 @@ account_request_cancel (McSvcAccountInterfaceChannelRequests *self,
                         DBusGMethodInvocation *context)
 {
     GError *error;
+    McdChannel *channel;
+    McdChannelStatus status;
+
+    g_debug ("%s called for %s", G_STRFUNC, request_id);
+    g_return_if_fail (request_id != NULL);
+    channel = get_channel_from_request (MCD_ACCOUNT (self), request_id);
+    if (!channel)
+    {
+        error = g_error_new (TP_ERRORS, TP_ERROR_INVALID_ARGUMENT,
+                             "Request %s not found", request_id);
+        dbus_g_method_return_error (context, error);
+        g_error_free (error);
+        return;
+    }
+
+    status = mcd_channel_get_status (channel);
+    g_debug ("channel %p is in status %u", channel, status);
+    if (status == MCD_CHANNEL_STATUS_REQUEST ||
+        status == MCD_CHANNEL_STATUS_REQUESTED ||
+        status == MCD_CHANNEL_STATUS_DISPATCHING)
+    {
+        g_object_ref (channel);
+        error = g_error_new (TP_ERRORS, TP_ERROR_CANCELLED, "Cancelled");
+        _mcd_channel_set_error (channel, error);
+
+        /* REQUESTED is a special case: the channel must not be aborted now,
+         * because we need to explicitly close the channel object when it will
+         * be created by the CM. In that case, mcd_mission_abort() will be
+         * called once the Create/EnsureChannel method returns, if the channel
+         * is ours */
+        if (status != MCD_CHANNEL_STATUS_REQUESTED)
+            mcd_mission_abort (MCD_MISSION (channel));
+
+        g_object_unref (channel);
+    }
+    else
+    {
+        error = g_error_new (TP_ERRORS, TP_ERROR_NOT_AVAILABLE,
+                             "Request %s is not cancellable (%u)",
+                             request_id, status);
+        dbus_g_method_return_error (context, error);
+        g_error_free (error);
+        return;
+    }
 
-    error = g_error_new (TP_ERRORS, TP_ERROR_NOT_IMPLEMENTED,
-                         "%s is currently just a stub", G_STRFUNC);
-    dbus_g_method_return_error (context, error);
-    g_error_free (error);
+    mc_svc_account_interface_channelrequests_return_from_cancel (context);
 }
 
 void
-- 
1.5.6.5




More information about the Telepathy-commits mailing list