2
* call-stream.c - Source for TpyCallStream
3
* Copyright © 2009–2011 Collabora Ltd.
4
* @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
5
* @author Will Thompson <will.thompson@collabora.co.uk>
6
* @author Emilio Pozuelo Monfort <emilio.pozuelo@collabora.co.uk>
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2.1 of the License, or (at your option) any later version.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23
#include "call-stream.h"
25
#define DEBUG_FLAG TPY_DEBUG_CALL
28
#include <telepathy-yell/interfaces.h>
29
#include <telepathy-yell/gtypes.h>
30
#include <telepathy-yell/cli-call.h>
32
G_DEFINE_TYPE(TpyCallStream, tpy_call_stream, TP_TYPE_PROXY)
36
PROP_REMOTE_MEMBERS = 1,
37
PROP_LOCAL_SENDING_STATE,
38
PROP_CAN_REQUEST_RECEIVING,
42
struct _TpyCallStreamPrivate
44
GHashTable *remote_members;
45
TpySendingState local_sending_state;
46
gboolean can_request_receiving;
49
GSimpleAsyncResult *result;
53
on_call_stream_get_all_properties_cb (TpProxy *proxy,
54
GHashTable *properties,
59
TpyCallStream *self = TPY_CALL_STREAM (proxy);
64
g_warning ("Could not get the stream properties: %s", error->message);
68
self->priv->local_sending_state = tp_asv_get_uint32 (properties,
69
"LocalSendingState", NULL);
70
self->priv->can_request_receiving = tp_asv_get_boolean (properties,
71
"CanRequestReceiving", NULL);
73
tp_clear_pointer (&self->priv->remote_members, g_hash_table_unref);
74
members = tp_asv_get_boxed (properties,
75
"RemoteMembers", TPY_HASH_TYPE_CALL_MEMBER_MAP);
77
self->priv->remote_members =
78
g_boxed_copy (TPY_HASH_TYPE_CALL_MEMBER_MAP, members);
80
self->priv->ready = TRUE;
81
g_object_notify (G_OBJECT (self), "ready");
85
on_remote_members_changed_cb (TpProxy *proxy,
87
const GArray *removed,
91
TpyCallStream *self = TPY_CALL_STREAM (proxy);
96
for (i = 0; i < removed->len; i++)
97
g_hash_table_remove (self->priv->remote_members,
98
GUINT_TO_POINTER (g_array_index (removed, TpHandle, i)));
100
g_hash_table_iter_init (&iter, updates);
101
while (g_hash_table_iter_next (&iter, &key, &value))
102
g_hash_table_insert (self->priv->remote_members, key, value);
104
g_object_notify (G_OBJECT (self), "remote-members");
108
on_local_sending_state_changed_cb (TpProxy *proxy,
111
GObject *weak_object)
113
TpyCallStream *self = TPY_CALL_STREAM (proxy);
115
if (self->priv->local_sending_state == state)
118
self->priv->local_sending_state = state;
119
g_object_notify (G_OBJECT (self), "local-sending-state");
123
tpy_call_stream_constructed (GObject *obj)
125
TpyCallStream *self = (TpyCallStream *) obj;
128
((GObjectClass *) tpy_call_stream_parent_class)->constructed (obj);
130
tpy_cli_call_stream_connect_to_remote_members_changed (TP_PROXY (self),
131
on_remote_members_changed_cb, NULL, NULL, G_OBJECT (self), &err);
135
g_critical ("Failed to connect to RemoteMembersChanged signal: %s",
142
tpy_cli_call_stream_connect_to_local_sending_state_changed (TP_PROXY (self),
143
on_local_sending_state_changed_cb, NULL, NULL, G_OBJECT (self), &err);
147
g_critical ("Failed to connect to LocalSendingStateChanged signal: %s",
154
tp_cli_dbus_properties_call_get_all (self, -1,
155
TPY_IFACE_CALL_STREAM,
156
on_call_stream_get_all_properties_cb, NULL, NULL, G_OBJECT (self));
160
tpy_call_stream_init (TpyCallStream *self)
162
TpyCallStreamPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
163
TPY_TYPE_CALL_STREAM, TpyCallStreamPrivate);
166
priv->remote_members = g_hash_table_new (g_direct_hash, g_direct_equal);
170
tpy_call_stream_dispose (GObject *object)
172
TpyCallStream *self = TPY_CALL_STREAM (object);
174
tp_clear_object (&self->priv->result);
175
tp_clear_pointer (&self->priv->remote_members, g_hash_table_unref);
177
G_OBJECT_CLASS (tpy_call_stream_parent_class)->dispose (object);
181
tpy_call_stream_get_property (
187
TpyCallStream *self = TPY_CALL_STREAM (object);
188
TpyCallStreamPrivate *priv = self->priv;
192
case PROP_REMOTE_MEMBERS:
193
g_value_set_boxed (value, priv->remote_members);
195
case PROP_LOCAL_SENDING_STATE:
196
g_value_set_uint (value, priv->local_sending_state);
198
case PROP_CAN_REQUEST_RECEIVING:
199
g_value_set_boolean (value, priv->can_request_receiving);
202
g_value_set_boolean (value, priv->ready);
205
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
211
tpy_call_stream_set_property (
217
TpyCallStream *self = TPY_CALL_STREAM (object);
221
case PROP_LOCAL_SENDING_STATE:
222
self->priv->local_sending_state = g_value_get_uint (value);
225
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
231
tpy_call_stream_class_init (TpyCallStreamClass *bsc_class)
233
GObjectClass *object_class = G_OBJECT_CLASS (bsc_class);
234
TpProxyClass *proxy_class = (TpProxyClass *) bsc_class;
235
GParamSpec *param_spec;
237
g_type_class_add_private (bsc_class, sizeof (TpyCallStreamPrivate));
239
object_class->dispose = tpy_call_stream_dispose;
240
object_class->constructed = tpy_call_stream_constructed;
241
object_class->set_property = tpy_call_stream_set_property;
242
object_class->get_property = tpy_call_stream_get_property;
244
proxy_class->interface = TPY_IFACE_QUARK_CALL_STREAM;
246
param_spec = g_param_spec_boxed ("remote-members", "Remote members",
248
TPY_HASH_TYPE_CONTACT_SENDING_STATE_MAP,
249
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
250
g_object_class_install_property (object_class, PROP_REMOTE_MEMBERS,
253
param_spec = g_param_spec_uint ("local-sending-state", "LocalSendingState",
254
"Local sending state",
255
0, NUM_TPY_SENDING_STATES, 0,
256
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
257
g_object_class_install_property (object_class, PROP_LOCAL_SENDING_STATE,
260
param_spec = g_param_spec_boolean ("can-request-receiving",
261
"CanRequestReceiving",
262
"If true, the user can request that a remote contact starts sending on"
265
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
266
g_object_class_install_property (object_class, PROP_CAN_REQUEST_RECEIVING,
269
param_spec = g_param_spec_boolean ("ready",
271
"If true the stream has retrieved all async information from the CM",
273
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
274
g_object_class_install_property (object_class, PROP_READY,
279
tpy_call_stream_get_local_sending_state (
282
return self->priv->local_sending_state;
286
on_set_sending_cb (TpProxy *proxy,
289
GObject *weak_object)
291
TpyCallStream *self = TPY_CALL_STREAM (proxy);
295
DEBUG ("Failed to set sending: %s", error->message);
297
g_simple_async_result_set_from_error (self->priv->result, error);
300
g_simple_async_result_set_op_res_gboolean (self->priv->result, TRUE);
301
g_simple_async_result_complete (self->priv->result);
302
tp_clear_object (&self->priv->result);
306
tpy_call_stream_set_sending_async (TpyCallStream *self,
308
GAsyncReadyCallback callback,
311
g_return_if_fail (TPY_IS_CALL_STREAM (self));
312
g_return_if_fail (self->priv->result == NULL);
314
self->priv->result = g_simple_async_result_new (G_OBJECT (self), callback,
315
user_data, tpy_call_stream_set_sending_async);
317
tpy_cli_call_stream_call_set_sending (TP_PROXY (self), -1,
319
on_set_sending_cb, NULL, NULL, G_OBJECT (self));
323
tpy_call_stream_set_sending_finish (TpyCallStream *self,
324
GAsyncResult *result,
327
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
331
g_return_val_if_fail (g_simple_async_result_is_valid (result,
332
G_OBJECT (self), tpy_call_stream_set_sending_async),
335
return g_simple_async_result_get_op_res_gboolean (
336
G_SIMPLE_ASYNC_RESULT (result));
340
on_request_receiving_cb (TpProxy *proxy,
343
GObject *weak_object)
345
TpyCallStream *self = TPY_CALL_STREAM (proxy);
349
DEBUG ("Failed to request receiving: %s", error->message);
351
g_simple_async_result_set_from_error (self->priv->result, error);
354
g_simple_async_result_set_op_res_gboolean (self->priv->result, TRUE);
355
g_simple_async_result_complete (self->priv->result);
356
tp_clear_object (&self->priv->result);
360
tpy_call_stream_request_receiving_async (TpyCallStream *self,
363
GAsyncReadyCallback callback,
366
g_return_if_fail (TPY_IS_CALL_STREAM (self));
367
g_return_if_fail (self->priv->result == NULL);
369
self->priv->result = g_simple_async_result_new (G_OBJECT (self), callback,
370
user_data, tpy_call_stream_request_receiving_async);
372
tpy_cli_call_stream_call_request_receiving (TP_PROXY (self), -1,
374
on_request_receiving_cb, NULL, NULL, G_OBJECT (self));
378
tpy_call_stream_request_receiving_finish (TpyCallStream *self,
379
GAsyncResult *result,
382
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
386
g_return_val_if_fail (g_simple_async_result_is_valid (result,
387
G_OBJECT (self), tpy_call_stream_request_receiving_async),
390
return g_simple_async_result_get_op_res_gboolean (
391
G_SIMPLE_ASYNC_RESULT (result));