diff options
author | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2011-05-27 13:05:27 +0200 |
---|---|---|
committer | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2011-05-27 13:05:27 +0200 |
commit | 396d10c4d48f9b36822ec4a34f104473d7e013c7 (patch) | |
tree | 20c95f87b30cf8dac8dc9bb64534eb869fa17735 | |
parent | 4054e4d9d2d0c325f9a9ba545f3d58545d9a97ff (diff) | |
parent | ded16605feb6f6bc70b57e9cf8a9674b1176cba3 (diff) | |
download | telepathy-glib-396d10c4d48f9b36822ec4a34f104473d7e013c7.tar.gz |
Merge branch 'cdo-reject-28015'
-rw-r--r-- | docs/reference/telepathy-glib-sections.txt | 2 | ||||
-rw-r--r-- | telepathy-glib/channel-dispatch-operation.c | 210 | ||||
-rw-r--r-- | telepathy-glib/channel-dispatch-operation.h | 12 | ||||
-rw-r--r-- | tests/dbus/channel-dispatch-operation.c | 53 |
4 files changed, 255 insertions, 22 deletions
diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt index 8084b2f77..fc49aac63 100644 --- a/docs/reference/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib-sections.txt @@ -4548,6 +4548,8 @@ tp_channel_dispatch_operation_claim_async tp_channel_dispatch_operation_claim_finish tp_channel_dispatch_operation_claim_with_async tp_channel_dispatch_operation_claim_with_finish +tp_channel_dispatch_operation_close_channels_async +tp_channel_dispatch_operation_close_channels_finish <SUBSECTION Standard> TP_CHANNEL_DISPATCH_OPERATION TP_CHANNEL_DISPATCH_OPERATION_CLASS diff --git a/telepathy-glib/channel-dispatch-operation.c b/telepathy-glib/channel-dispatch-operation.c index 340616ecb..a3bbe1294 100644 --- a/telepathy-glib/channel-dispatch-operation.c +++ b/telepathy-glib/channel-dispatch-operation.c @@ -1394,50 +1394,129 @@ gboolean } static void -claim_with_cb (GObject *source, +claim_with_cb (TpChannelDispatchOperation *self, + GSimpleAsyncResult *result) +{ + TpBaseClient *client; + + client = g_simple_async_result_get_op_res_gpointer (result); + + _tp_base_client_now_handling_channels (client, self->priv->channels); + + g_simple_async_result_complete (result); + g_object_unref (result); +} + +typedef void (*PrepareCoreAndClaimCb) (TpChannelDispatchOperation *self, + GSimpleAsyncResult *result); + +typedef struct +{ + GSimpleAsyncResult *result; + PrepareCoreAndClaimCb callback; +} PrepareCoreAndClaimCtx; + +static PrepareCoreAndClaimCtx * +prepare_core_and_claim_ctx_new (GSimpleAsyncResult *result, + PrepareCoreAndClaimCb callback) +{ + PrepareCoreAndClaimCtx *ctx = g_slice_new (PrepareCoreAndClaimCtx); + + ctx->result = g_object_ref (result); + ctx->callback = callback; + return ctx; +} + +static void +prepare_core_and_claim_ctx_free (PrepareCoreAndClaimCtx *ctx) +{ + g_object_unref (ctx->result); + g_slice_free (PrepareCoreAndClaimCtx, ctx); +} + +/* Takes ownership of @error */ +static void +prepare_core_and_claim_ctx_failed (PrepareCoreAndClaimCtx *ctx, + GError *error) +{ + g_simple_async_result_take_error (ctx->result, error); + g_simple_async_result_complete (ctx->result); + + /* We received a reference on result from the caller and was supposed to + * give it back when calling the callback. But as something went wrong, we + * terminate the operation ourself and so don't call the callback, so we + * have to drop this reference. */ + g_object_unref (ctx->result); + prepare_core_and_claim_ctx_free (ctx); +} + +static void +prepare_core_claim_cb (GObject *source, GAsyncResult *result, gpointer user_data) { TpChannelDispatchOperation *self = (TpChannelDispatchOperation *) source; - GSimpleAsyncResult *main_result = user_data; + PrepareCoreAndClaimCtx *ctx = user_data; GError *error = NULL; - TpBaseClient *client; if (!tp_channel_dispatch_operation_claim_finish (self, result, &error)) { - g_simple_async_result_take_error (main_result, error); - goto out; - } + DEBUG ("Failed to Claim %s: %s", + tp_proxy_get_object_path (self), error->message); - client = g_simple_async_result_get_op_res_gpointer (main_result); + prepare_core_and_claim_ctx_failed (ctx, error); + return; + } - _tp_base_client_now_handling_channels (client, self->priv->channels); + /* Pass back the ref we got from the caller */ + ctx->callback (self, ctx->result); -out: - g_simple_async_result_complete (main_result); - g_object_unref (main_result); + prepare_core_and_claim_ctx_free (ctx); } static void -claim_with_prepare_cb (GObject *source, +prepare_core_cb (GObject *source, GAsyncResult *result, gpointer user_data) { TpChannelDispatchOperation *self = (TpChannelDispatchOperation *) source; - GSimpleAsyncResult *main_result = user_data; + PrepareCoreAndClaimCtx *ctx = user_data; GError *error = NULL; if (!tp_proxy_prepare_finish (self, result, &error)) { - g_simple_async_result_take_error (main_result, error); - g_simple_async_result_complete (main_result); - g_object_unref (main_result); + DEBUG ("Failed to prepare CORE on %s: %s", + tp_proxy_get_object_path (self), error->message); + + prepare_core_and_claim_ctx_failed (ctx, error); return; } - tp_channel_dispatch_operation_claim_async (self, claim_with_cb, main_result); + tp_channel_dispatch_operation_claim_async (self, prepare_core_claim_cb, ctx); } +/* Prepare CORE feature on @self and then call Claim() on it. + * If either the preparation or the call failed, complete @result with the + * error. + * If everything goes fine call @callback. + * + * Takes the reference on @result and pass it back to @callback. + */ +static void +prepare_core_and_claim (TpChannelDispatchOperation *self, + PrepareCoreAndClaimCb callback, + GSimpleAsyncResult *result) +{ + GQuark features[] = { TP_CHANNEL_DISPATCH_OPERATION_FEATURE_CORE, 0 }; + PrepareCoreAndClaimCtx *ctx; + + ctx = prepare_core_and_claim_ctx_new (result, callback); + + /* We have to prepare the CDO to be able to get the list of its channels. + * We prepare it *before* calling Claim() as MC will destroy the CDO once it + * has been claimed. */ + tp_proxy_prepare_async (self, features, prepare_core_cb, ctx); +} /** * tp_channel_dispatch_operation_claim_with_async: @@ -1472,7 +1551,6 @@ tp_channel_dispatch_operation_claim_with_async ( gpointer user_data) { GSimpleAsyncResult *result; - GQuark features[] = { TP_CHANNEL_DISPATCH_OPERATION_FEATURE_CORE, 0 }; g_return_if_fail (TP_IS_CHANNEL_DISPATCH_OPERATION (self)); @@ -1483,10 +1561,7 @@ tp_channel_dispatch_operation_claim_with_async ( g_simple_async_result_set_op_res_gpointer (result, g_object_ref (client), g_object_unref); - /* We have to prepare the CDO to be able to get the list of its channels. - * We prepare it *before* calling Claim() as MC will destroy the CDO once it - * has been claimed. */ - tp_proxy_prepare_async (self, features, claim_with_prepare_cb, result); + prepare_core_and_claim (self, claim_with_cb, result); } /** @@ -1511,3 +1586,94 @@ tp_channel_dispatch_operation_claim_with_finish ( _tp_implement_finish_void (self, \ tp_channel_dispatch_operation_claim_with_async) } + +static void +channel_close_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + GError *error = NULL; + + if (!tp_channel_close_finish (TP_CHANNEL (source), result, &error)) + { + DEBUG ("Failed to close %s: %s", tp_proxy_get_object_path (source), + error->message); + + g_error_free (error); + } +} + +static void +claim_close_channels_cb (TpChannelDispatchOperation *self, + GSimpleAsyncResult *result) +{ + guint i; + + for (i = 0; i < self->priv->channels->len; i++) + { + TpChannel *channel = g_ptr_array_index (self->priv->channels, i); + + tp_channel_close_async (channel, channel_close_cb, NULL); + } + + g_simple_async_result_complete (result); + g_object_unref (result); +} + +/** + * tp_channel_dispatch_operation_close_channels_async: + * @self: a #TpChannelDispatchOperation + * @callback: a callback to call when the request has been satisfied + * @user_data: data to pass to @callback + * + * Called by an approver to claim channels and close them all right away. + * If this method is called successfully, @self has been claimed and + * tp_channel_close_async() has been called on all of its channels. + * + * If successful, this method will cause the #TpProxy::invalidated signal + * to be emitted, in the same way as for + * tp_channel_dispatch_operation_handle_with_async(). + * + * This method may fail because the dispatch operation has already + * been completed. Again, see tp_channel_dispatch_operation_handle_with_async() + * for more details. + * + * Since: 0.15.UNRELEASED + */ +void +tp_channel_dispatch_operation_close_channels_async ( + TpChannelDispatchOperation *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + + result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, + tp_channel_dispatch_operation_close_channels_async); + + prepare_core_and_claim (self, claim_close_channels_cb, result); +} + +/** + * tp_channel_dispatch_operation_close_channels_finish: + * @self: a #TpChannelDispatchOperation + * @result: a #GAsyncResult + * @error: a #GError to fill + * + * Finishes an async operation initiated using + * tp_channel_dispatch_operation_close_channels_finish(). + * + * Returns: %TRUE if the Claim() call was successful and + * Close() has at least been attempted on all the channels, otherwise %FALSE + * + * Since: 0.15.UNRELEASED + */ +gboolean +tp_channel_dispatch_operation_close_channels_finish ( + TpChannelDispatchOperation *self, + GAsyncResult *result, + GError **error) +{ + _tp_implement_finish_void (self, \ + tp_channel_dispatch_operation_close_channels_async) +} diff --git a/telepathy-glib/channel-dispatch-operation.h b/telepathy-glib/channel-dispatch-operation.h index 605f98f0d..387496d9a 100644 --- a/telepathy-glib/channel-dispatch-operation.h +++ b/telepathy-glib/channel-dispatch-operation.h @@ -142,6 +142,18 @@ gboolean tp_channel_dispatch_operation_claim_with_finish ( GAsyncResult *result, GError **error); +/* Reject API */ + +void tp_channel_dispatch_operation_close_channels_async ( + TpChannelDispatchOperation *self, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean tp_channel_dispatch_operation_close_channels_finish ( + TpChannelDispatchOperation *self, + GAsyncResult *result, + GError **error); + G_END_DECLS #include <telepathy-glib/_gen/tp-cli-channel-dispatch-operation.h> diff --git a/tests/dbus/channel-dispatch-operation.c b/tests/dbus/channel-dispatch-operation.c index 4f7f9e277..fa57d5da8 100644 --- a/tests/dbus/channel-dispatch-operation.c +++ b/tests/dbus/channel-dispatch-operation.c @@ -779,6 +779,57 @@ test_handle_with_time (Test *test, g_assert_no_error (test->error); } +static void +close_channels_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + Test *test = user_data; + + tp_channel_dispatch_operation_close_channels_finish ( + TP_CHANNEL_DISPATCH_OPERATION (source), result, &test->error); + + test->sig--; + if (test->sig == 0) + g_main_loop_quit (test->mainloop); +} + +static void +channel_invalidated_cb (TpProxy *proxy, + guint domain, + gint code, + gchar *message, + gpointer user_data) +{ + Test *test = user_data; + + test->sig--; + if (test->sig == 0) + g_main_loop_quit (test->mainloop); +} + +static void +test_close_channels (Test *test, + gconstpointer data G_GNUC_UNUSED) +{ + test->cdo = tp_channel_dispatch_operation_new (test->dbus, + "/whatever", NULL, &test->error); + g_assert_no_error (test->error); + + g_signal_connect (test->text_chan, "invalidated", + G_CALLBACK (channel_invalidated_cb), test); + g_signal_connect (test->text_chan_2, "invalidated", + G_CALLBACK (channel_invalidated_cb), test); + + tp_channel_dispatch_operation_close_channels_async (test->cdo, + close_channels_cb, test); + + test->sig = 3; + g_main_loop_run (test->mainloop); + + g_assert_no_error (test->error); +} + int main (int argc, char **argv) @@ -805,6 +856,8 @@ main (int argc, test_finished_preparing, teardown_services); g_test_add ("/cdo/handle-with-time", Test, NULL, setup_services, test_handle_with_time, teardown_services); + g_test_add ("/cdo/close-channels", Test, NULL, setup_services, + test_close_channels, teardown_services); return g_test_run (); } |