~ubuntu-branches/ubuntu/precise/telepathy-glib/precise-201202222208

« back to all changes in this revision

Viewing changes to telepathy-glib/call-stream.c

  • Committer: Ken VanDine
  • Date: 2012-02-22 18:08:37 UTC
  • mfrom: (1.6.39)
  • Revision ID: ken.vandine@canonical.com-20120222180837-02um6fex0eg073lf
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * call-stream.h - high level API for Call streams
 
3
 *
 
4
 * Copyright (C) 2011 Collabora Ltd. <http://www.collabora.co.uk/>
 
5
 *
 
6
 * This library is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU Lesser General Public
 
8
 * License as published by the Free Software Foundation; either
 
9
 * version 2.1 of the License, or (at your option) any later version.
 
10
 *
 
11
 * This library is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
 * Lesser General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public
 
17
 * License along with this library; if not, write to the Free Software
 
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 */
 
20
 
 
21
/**
 
22
 * SECTION:call-stream
 
23
 * @title: TpCallStream
 
24
 * @short_description: proxy object for a call stream
 
25
 *
 
26
 * #TpCallStream is a sub-class of #TpProxy providing convenient API
 
27
 * to represent #TpCallChannel's stream.
 
28
 */
 
29
 
 
30
/**
 
31
 * TpCallStream:
 
32
 *
 
33
 * Data structure representing a #TpCallStream.
 
34
 *
 
35
 * Since: 0.17.5
 
36
 */
 
37
 
 
38
/**
 
39
 * TpCallStreamClass:
 
40
 *
 
41
 * The class of a #TpCallStream.
 
42
 *
 
43
 * Since: 0.17.5
 
44
 */
 
45
 
 
46
#include "config.h"
 
47
 
 
48
#include "telepathy-glib/call-stream.h"
 
49
 
 
50
#include <telepathy-glib/call-misc.h>
 
51
#include <telepathy-glib/dbus.h>
 
52
#include <telepathy-glib/enums.h>
 
53
#include <telepathy-glib/errors.h>
 
54
#include <telepathy-glib/gtypes.h>
 
55
#include <telepathy-glib/interfaces.h>
 
56
#include <telepathy-glib/proxy-subclass.h>
 
57
#include <telepathy-glib/util.h>
 
58
 
 
59
#define DEBUG_FLAG TP_DEBUG_CALL
 
60
#include "telepathy-glib/debug-internal.h"
 
61
#include "telepathy-glib/call-internal.h"
 
62
#include "telepathy-glib/proxy-internal.h"
 
63
#include "telepathy-glib/util-internal.h"
 
64
#include "telepathy-glib/_gen/signals-marshal.h"
 
65
 
 
66
#include "_gen/tp-cli-call-stream-body.h"
 
67
 
 
68
G_DEFINE_TYPE (TpCallStream, tp_call_stream, TP_TYPE_PROXY)
 
69
 
 
70
struct _TpCallStreamPrivate
 
71
{
 
72
  TpConnection *connection;
 
73
 
 
74
  /* TpContact -> TpSendingState */
 
75
  GHashTable *remote_members;
 
76
  TpSendingState local_sending_state;
 
77
  gboolean can_request_receiving;
 
78
 
 
79
  gboolean properties_retrieved;
 
80
};
 
81
 
 
82
enum
 
83
{
 
84
  PROP_CONNECTION = 1,
 
85
  PROP_LOCAL_SENDING_STATE,
 
86
  PROP_CAN_REQUEST_RECEIVING,
 
87
};
 
88
 
 
89
enum /* signals */
 
90
{
 
91
  LOCAL_SENDING_STATE_CHANGED,
 
92
  REMOTE_MEMBERS_CHANGED,
 
93
  LAST_SIGNAL
 
94
};
 
95
 
 
96
static guint _signals[LAST_SIGNAL] = { 0, };
 
97
 
 
98
static void
 
99
update_remote_members (TpCallStream *self,
 
100
    GHashTable *updates,
 
101
    GPtrArray *removed)
 
102
{
 
103
  if (updates != NULL)
 
104
    {
 
105
      tp_g_hash_table_update (self->priv->remote_members, updates,
 
106
          g_object_ref, NULL);
 
107
    }
 
108
 
 
109
  if (removed != NULL)
 
110
    {
 
111
      guint i;
 
112
 
 
113
      for (i = 0; i < removed->len; i++)
 
114
        {
 
115
          g_hash_table_remove (self->priv->remote_members,
 
116
              g_ptr_array_index (removed, i));
 
117
        }
 
118
    }
 
119
}
 
120
 
 
121
static void
 
122
remote_members_changed_cb (TpCallStream *self,
 
123
    GHashTable *updates,
 
124
    GHashTable *identifiers,
 
125
    const GArray *removed,
 
126
    const GValueArray *reason,
 
127
    gpointer user_data,
 
128
    GObject *weak_object)
 
129
{
 
130
  GHashTable *updates_contacts;
 
131
  GPtrArray *removed_contacts;
 
132
  TpCallStateReason *r;
 
133
 
 
134
  if (!self->priv->properties_retrieved)
 
135
    return;
 
136
 
 
137
  DEBUG ("Remote members: %d updated, %d removed",
 
138
      g_hash_table_size (updates), removed->len);
 
139
 
 
140
  updates_contacts = _tp_call_members_convert_table (self->priv->connection,
 
141
      updates, identifiers);
 
142
  removed_contacts = _tp_call_members_convert_array (self->priv->connection,
 
143
      removed);
 
144
  r = _tp_call_state_reason_new (reason);
 
145
 
 
146
  update_remote_members (self, updates_contacts, removed_contacts);
 
147
 
 
148
  g_signal_emit (self, _signals[REMOTE_MEMBERS_CHANGED], 0,
 
149
      updates_contacts, removed_contacts, r);
 
150
 
 
151
  g_hash_table_unref (updates_contacts);
 
152
  g_ptr_array_unref (removed_contacts);
 
153
  _tp_call_state_reason_unref (r);
 
154
}
 
155
 
 
156
static void
 
157
local_sending_state_changed_cb (TpCallStream *self,
 
158
    guint state,
 
159
    const GValueArray *reason,
 
160
    gpointer user_data,
 
161
    GObject *weak_object)
 
162
{
 
163
  TpCallStateReason *r;
 
164
 
 
165
  if (!self->priv->properties_retrieved)
 
166
    return;
 
167
 
 
168
  self->priv->local_sending_state = state;
 
169
  g_object_notify (G_OBJECT (self), "local-sending-state");
 
170
 
 
171
  r = _tp_call_state_reason_new (reason);
 
172
  g_signal_emit (self, _signals[LOCAL_SENDING_STATE_CHANGED], 0,
 
173
      self->priv->local_sending_state, r);
 
174
  _tp_call_state_reason_unref (r);
 
175
}
 
176
 
 
177
static void
 
178
got_all_properties_cb (TpProxy *proxy,
 
179
    GHashTable *properties,
 
180
    const GError *error,
 
181
    gpointer user_data,
 
182
    GObject *weak_object)
 
183
{
 
184
  TpCallStream *self = (TpCallStream *) proxy;
 
185
  const gchar * const *interfaces;
 
186
  GHashTable *remote_members;
 
187
  GHashTable *identifiers;
 
188
  GHashTable *contacts;
 
189
 
 
190
  if (error != NULL)
 
191
    {
 
192
      DEBUG ("Could not get the call stream properties: %s", error->message);
 
193
      _tp_proxy_set_feature_prepared (proxy,
 
194
          TP_CALL_STREAM_FEATURE_CORE, FALSE);
 
195
      return;
 
196
    }
 
197
 
 
198
  self->priv->properties_retrieved = TRUE;
 
199
 
 
200
  interfaces = tp_asv_get_boxed (properties,
 
201
      "Interfaces", G_TYPE_STRV);
 
202
  remote_members = tp_asv_get_boxed (properties,
 
203
      "RemoteMembers", TP_HASH_TYPE_CONTACT_SENDING_STATE_MAP),
 
204
  identifiers = tp_asv_get_boxed (properties,
 
205
      "RemoteMemberIdentifiers", TP_HASH_TYPE_HANDLE_IDENTIFIER_MAP);
 
206
  self->priv->local_sending_state = tp_asv_get_uint32 (properties,
 
207
      "LocalSendingState", NULL);
 
208
  self->priv->can_request_receiving = tp_asv_get_boolean (properties,
 
209
      "CanRequestReceiving", NULL);
 
210
 
 
211
  tp_proxy_add_interfaces ((TpProxy *) self, interfaces);
 
212
 
 
213
  contacts = _tp_call_members_convert_table (self->priv->connection,
 
214
      remote_members, identifiers);
 
215
  update_remote_members (self, contacts, NULL);
 
216
  g_hash_table_unref (contacts);
 
217
 
 
218
  _tp_proxy_set_feature_prepared (proxy, TP_CALL_STREAM_FEATURE_CORE, TRUE);
 
219
}
 
220
 
 
221
static void
 
222
tp_call_stream_constructed (GObject *obj)
 
223
{
 
224
  TpCallStream *self = (TpCallStream *) obj;
 
225
 
 
226
  ((GObjectClass *) tp_call_stream_parent_class)->constructed (obj);
 
227
 
 
228
  /* Connect signals for mutable properties */
 
229
  tp_cli_call_stream_connect_to_remote_members_changed (self,
 
230
      remote_members_changed_cb, NULL, NULL, G_OBJECT (self), NULL);
 
231
  tp_cli_call_stream_connect_to_local_sending_state_changed (self,
 
232
      local_sending_state_changed_cb, NULL, NULL, G_OBJECT (self), NULL);
 
233
 
 
234
  tp_cli_dbus_properties_call_get_all (self, -1,
 
235
      TP_IFACE_CALL_STREAM,
 
236
      got_all_properties_cb, NULL, NULL, G_OBJECT (self));
 
237
}
 
238
 
 
239
static void
 
240
tp_call_stream_dispose (GObject *object)
 
241
{
 
242
  TpCallStream *self = (TpCallStream *) object;
 
243
 
 
244
  g_clear_object (&self->priv->connection);
 
245
  tp_clear_pointer (&self->priv->remote_members, g_hash_table_unref);
 
246
 
 
247
  G_OBJECT_CLASS (tp_call_stream_parent_class)->dispose (object);
 
248
}
 
249
 
 
250
static void
 
251
tp_call_stream_get_property (GObject *object,
 
252
    guint property_id,
 
253
    GValue *value,
 
254
    GParamSpec *pspec)
 
255
{
 
256
  TpCallStream *self = (TpCallStream *) object;
 
257
  TpCallStreamPrivate *priv = self->priv;
 
258
 
 
259
  switch (property_id)
 
260
    {
 
261
      case PROP_CONNECTION:
 
262
        g_value_set_object (value, self->priv->connection);
 
263
        break;
 
264
      case PROP_LOCAL_SENDING_STATE:
 
265
        g_value_set_uint (value, priv->local_sending_state);
 
266
        break;
 
267
      case PROP_CAN_REQUEST_RECEIVING:
 
268
        g_value_set_boolean (value, priv->can_request_receiving);
 
269
        break;
 
270
      default:
 
271
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
272
        break;
 
273
    }
 
274
}
 
275
 
 
276
static void
 
277
tp_call_stream_set_property (GObject *object,
 
278
    guint property_id,
 
279
    const GValue *value,
 
280
    GParamSpec *pspec)
 
281
{
 
282
  TpCallStream *self = (TpCallStream *) object;
 
283
 
 
284
  switch (property_id)
 
285
    {
 
286
      case PROP_CONNECTION:
 
287
        g_assert (self->priv->connection == NULL); /* construct-only */
 
288
        self->priv->connection = g_value_dup_object (value);
 
289
        break;
 
290
      default:
 
291
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
292
        break;
 
293
    }
 
294
}
 
295
 
 
296
enum {
 
297
    FEAT_CORE,
 
298
    N_FEAT
 
299
};
 
300
 
 
301
static const TpProxyFeature *
 
302
tp_call_stream_list_features (TpProxyClass *cls G_GNUC_UNUSED)
 
303
{
 
304
  static TpProxyFeature features[N_FEAT + 1] = { { 0 } };
 
305
 
 
306
  if (G_LIKELY (features[0].name != 0))
 
307
    return features;
 
308
 
 
309
  /* started from constructed */
 
310
  features[FEAT_CORE].name = TP_CALL_STREAM_FEATURE_CORE;
 
311
  features[FEAT_CORE].core = TRUE;
 
312
 
 
313
  /* assert that the terminator at the end is there */
 
314
  g_assert (features[N_FEAT].name == 0);
 
315
 
 
316
  return features;
 
317
}
 
318
 
 
319
static void
 
320
tp_call_stream_class_init (TpCallStreamClass *klass)
 
321
{
 
322
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
323
  TpProxyClass *proxy_class = (TpProxyClass *) klass;
 
324
  GParamSpec *param_spec;
 
325
 
 
326
  gobject_class->constructed = tp_call_stream_constructed;
 
327
  gobject_class->get_property = tp_call_stream_get_property;
 
328
  gobject_class->set_property = tp_call_stream_set_property;
 
329
  gobject_class->dispose = tp_call_stream_dispose;
 
330
 
 
331
  proxy_class->list_features = tp_call_stream_list_features;
 
332
  proxy_class->interface = TP_IFACE_QUARK_CALL_STREAM;
 
333
 
 
334
  g_type_class_add_private (gobject_class, sizeof (TpCallStreamPrivate));
 
335
  tp_call_stream_init_known_interfaces ();
 
336
 
 
337
  /**
 
338
   * TpCallStream:connection:
 
339
   *
 
340
   * The #TpConnection of the call.
 
341
   *
 
342
   * Since: 0.17.5
 
343
   */
 
344
  param_spec = g_param_spec_object ("connection", "Connection",
 
345
      "The connection of this content",
 
346
      TP_TYPE_CONNECTION,
 
347
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
 
348
  g_object_class_install_property (gobject_class, PROP_CONNECTION,
 
349
      param_spec);
 
350
 
 
351
  /**
 
352
   * TpCallStream:local-sending-state:
 
353
   *
 
354
   * The local user's sending state, from #TpSendingState.
 
355
   *
 
356
   * Since: 0.17.5
 
357
   */
 
358
  param_spec = g_param_spec_uint ("local-sending-state", "LocalSendingState",
 
359
      "Local sending state",
 
360
      0, G_MAXUINT, 0,
 
361
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
 
362
  g_object_class_install_property (gobject_class, PROP_LOCAL_SENDING_STATE,
 
363
      param_spec);
 
364
 
 
365
  /**
 
366
   * TpCallStream:can-request-receiving:
 
367
   *
 
368
   * If %TRUE, the user can request that a remote contact starts sending on this
 
369
   * stream.
 
370
   *
 
371
   * Since: 0.17.5
 
372
   */
 
373
  param_spec = g_param_spec_boolean ("can-request-receiving",
 
374
      "CanRequestReceiving",
 
375
      "If true, the user can request that a remote contact starts sending on"
 
376
      "this stream.",
 
377
      FALSE,
 
378
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
 
379
  g_object_class_install_property (gobject_class, PROP_CAN_REQUEST_RECEIVING,
 
380
      param_spec);
 
381
 
 
382
  /**
 
383
   * TpCallStream::local-sending-state-changed
 
384
   * @self: the #TpCallStream
 
385
   * @state: the new #TpSendingState
 
386
   * @reason: the #TpCallStateReason for the change
 
387
   *
 
388
   * The ::local-sending-state-changed signal is emitted whenever the
 
389
   * stream sending state changes.
 
390
   *
 
391
   * Since: 0.17.5
 
392
   */
 
393
  _signals[LOCAL_SENDING_STATE_CHANGED] = g_signal_new ("local-sending-state-changed",
 
394
      G_OBJECT_CLASS_TYPE (klass),
 
395
      G_SIGNAL_RUN_LAST,
 
396
      0, NULL, NULL,
 
397
      _tp_marshal_VOID__UINT_BOXED,
 
398
      G_TYPE_NONE,
 
399
      4, G_TYPE_UINT, G_TYPE_UINT, TP_TYPE_CALL_STATE_REASON,
 
400
      G_TYPE_HASH_TABLE);
 
401
 
 
402
  /**
 
403
   * TpCallStream::remote-members-changed
 
404
   * @self: the #TpCallStream
 
405
   * @updates: (type GLib.HashTable) (element-type TelepathyGLib.Contact uint):
 
406
   *   #GHashTable mapping #TpContact to its new #TpSendingState
 
407
   * @removed: (type GLib.PtrArray) (element-type TelepathyGLib.Contact):
 
408
   *  #GPtrArray of #TpContact removed from remote contacts
 
409
   * @reason: the #TpCallStateReason for the change
 
410
   *
 
411
   * The ::remote-members-changed signal is emitted whenever the
 
412
   * stream's remote members changes.
 
413
   *
 
414
   * It is NOT guaranteed that #TpContact objects have any feature prepared.
 
415
   *
 
416
   * Since: 0.17.5
 
417
   */
 
418
  _signals[REMOTE_MEMBERS_CHANGED] = g_signal_new ("remote-members-changed",
 
419
      G_OBJECT_CLASS_TYPE (klass),
 
420
      G_SIGNAL_RUN_LAST,
 
421
      0, NULL, NULL,
 
422
      _tp_marshal_VOID__BOXED_BOXED_BOXED,
 
423
      G_TYPE_NONE,
 
424
      3, G_TYPE_HASH_TABLE, G_TYPE_PTR_ARRAY, TP_TYPE_CALL_STATE_REASON);
 
425
}
 
426
 
 
427
static void
 
428
tp_call_stream_init (TpCallStream *self)
 
429
{
 
430
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), TP_TYPE_CALL_STREAM,
 
431
      TpCallStreamPrivate);
 
432
 
 
433
  self->priv->remote_members = g_hash_table_new_full (NULL, NULL,
 
434
      g_object_unref, NULL);
 
435
}
 
436
 
 
437
/**
 
438
 * tp_call_stream_init_known_interfaces:
 
439
 *
 
440
 * Ensure that the known interfaces for #TpCallStream have been set up.
 
441
 * This is done automatically when necessary, but for correct
 
442
 * overriding of library interfaces by local extensions, you should
 
443
 * call this function before calling
 
444
 * tp_proxy_or_subclass_hook_on_interface_add() with first argument
 
445
 * %TP_TYPE_CALL_STREAM.
 
446
 *
 
447
 * Since: 0.17.5
 
448
 */
 
449
void
 
450
tp_call_stream_init_known_interfaces (void)
 
451
{
 
452
  static gsize once = 0;
 
453
 
 
454
  if (g_once_init_enter (&once))
 
455
    {
 
456
      GType tp_type = TP_TYPE_CALL_STREAM;
 
457
 
 
458
      tp_proxy_init_known_interfaces ();
 
459
      tp_proxy_or_subclass_hook_on_interface_add (tp_type,
 
460
          tp_cli_call_stream_add_signals);
 
461
      tp_proxy_subclass_add_error_mapping (tp_type,
 
462
          TP_ERROR_PREFIX, TP_ERRORS, TP_TYPE_ERROR);
 
463
 
 
464
      g_once_init_leave (&once, 1);
 
465
    }
 
466
}
 
467
 
 
468
/**
 
469
 * TP_CALL_STREAM_FEATURE_CORE:
 
470
 *
 
471
 * Expands to a call to a function that returns a quark for the "core"
 
472
 * feature on a #TpCallStream.
 
473
 *
 
474
 * One can ask for a feature to be prepared using the tp_proxy_prepare_async()
 
475
 * function, and waiting for it to trigger the callback.
 
476
 */
 
477
GQuark
 
478
tp_call_stream_get_feature_quark_core (void)
 
479
{
 
480
  return g_quark_from_static_string ("tp-call-stream-feature-core");
 
481
}
 
482
 
 
483
/**
 
484
 * tp_call_stream_get_local_sending_state:
 
485
 * @self: a #TpCallStream
 
486
 *
 
487
 * <!-- -->
 
488
 *
 
489
 * Returns: the value of #TpCallStream:local-seding-state
 
490
 * Since: 0.17.5
 
491
 */
 
492
TpSendingState
 
493
tp_call_stream_get_local_sending_state (TpCallStream *self)
 
494
{
 
495
  g_return_val_if_fail (TP_IS_CALL_STREAM (self), TP_SENDING_STATE_NONE);
 
496
 
 
497
  return self->priv->local_sending_state;
 
498
}
 
499
 
 
500
/**
 
501
 * tp_call_stream_can_request_receiving:
 
502
 * @self: a #TpCallStream
 
503
 *
 
504
 * <!-- -->
 
505
 *
 
506
 * Returns: the value of #TpCallStream:can-request-receiving
 
507
 * Since: 0.17.5
 
508
 */
 
509
gboolean
 
510
tp_call_stream_can_request_receiving (TpCallStream *self)
 
511
{
 
512
  g_return_val_if_fail (TP_IS_CALL_STREAM (self), FALSE);
 
513
 
 
514
  return self->priv->can_request_receiving;
 
515
}
 
516
 
 
517
/**
 
518
 * tp_call_stream_get_remote_members:
 
519
 * @self: a #TpCallStream
 
520
 *
 
521
 * Get the remote contacts to who this stream is connected, mapped to their
 
522
 * sending state.
 
523
 *
 
524
 * It is NOT guaranteed that #TpContact objects have any feature prepared.
 
525
 *
 
526
 * Returns: (transfer none) (type GLib.HashTable) (element-type TelepathyGLib.Contact uint):
 
527
 *  #GHashTable mapping #TpContact to its new #TpSendingState
 
528
 * Since: 0.17.5
 
529
 */
 
530
GHashTable *
 
531
tp_call_stream_get_remote_members (TpCallStream *self)
 
532
{
 
533
  g_return_val_if_fail (TP_IS_CALL_STREAM (self), NULL);
 
534
 
 
535
  return self->priv->remote_members;
 
536
}
 
537
 
 
538
static void
 
539
generic_async_cb (TpCallStream *self,
 
540
    const GError *error,
 
541
    gpointer user_data,
 
542
    GObject *weak_object)
 
543
{
 
544
  GSimpleAsyncResult *result = user_data;
 
545
 
 
546
  if (error != NULL)
 
547
    {
 
548
      DEBUG ("Error: %s", error->message);
 
549
      g_simple_async_result_set_from_error (result, error);
 
550
    }
 
551
 
 
552
  g_simple_async_result_complete (result);
 
553
}
 
554
 
 
555
/**
 
556
 * tp_call_stream_set_sending_async:
 
557
 * @self: a #TpCallStream
 
558
 * @send: the requested sending state
 
559
 * @callback: a callback to call when the operation finishes
 
560
 * @user_data: data to pass to @callback
 
561
 *
 
562
 * Set the stream to start or stop sending media from the local user to other
 
563
 * contacts.
 
564
 *
 
565
 * If @send is %TRUE, #TpCallStream:local-sending-state should change to
 
566
 * %TP_SENDING_STATE_SENDING, if it isn't already.
 
567
 * If @send is %FALSE, #TpCallStream:local-sending-state should change to
 
568
 * %TP_SENDING_STATE_NONE, if it isn't already.
 
569
 *
 
570
 * Since: 0.17.5
 
571
 */
 
572
void
 
573
tp_call_stream_set_sending_async (TpCallStream *self,
 
574
    gboolean send,
 
575
    GAsyncReadyCallback callback,
 
576
    gpointer user_data)
 
577
{
 
578
  GSimpleAsyncResult *result;
 
579
 
 
580
  g_return_if_fail (TP_IS_CALL_STREAM (self));
 
581
 
 
582
  result = g_simple_async_result_new (G_OBJECT (self), callback,
 
583
      user_data, tp_call_stream_set_sending_async);
 
584
 
 
585
  tp_cli_call_stream_call_set_sending (self, -1, send,
 
586
      generic_async_cb, result, g_object_unref, G_OBJECT (self));
 
587
}
 
588
 
 
589
/**
 
590
 * tp_call_stream_set_sending_finish:
 
591
 * @self: a #TpCallStream
 
592
 * @result: a #GAsyncResult
 
593
 * @error: a #GError to fill
 
594
 *
 
595
 * Finishes tp_call_stream_set_sending_async().
 
596
 *
 
597
 * Since: 0.17.5
 
598
 */
 
599
gboolean
 
600
tp_call_stream_set_sending_finish (TpCallStream *self,
 
601
    GAsyncResult *result,
 
602
    GError **error)
 
603
{
 
604
  _tp_implement_finish_void (self, tp_call_stream_set_sending_async);
 
605
}
 
606
 
 
607
/**
 
608
 * tp_call_stream_request_receiving_async:
 
609
 * @self: a #TpCallStream
 
610
 * @contact: contact from which sending is requested
 
611
 * @receive: the requested receiving state
 
612
 * @callback: a callback to call when the operation finishes
 
613
 * @user_data: data to pass to @callback
 
614
 *
 
615
 * Request that a remote contact stops or starts sending on this stream.
 
616
 *
 
617
 * The #TpCallStream:can-request-receiving property defines whether the protocol
 
618
 * allows the local user to request the other side start sending on this stream.
 
619
 *
 
620
 * If @receive is %TRUE, request that the given contact starts to send media.
 
621
 * If @receive is %FALSE, request that the given contact stops sending media.
 
622
 *
 
623
 * Since: 0.17.5
 
624
 */
 
625
void
 
626
tp_call_stream_request_receiving_async (TpCallStream *self,
 
627
    TpContact *contact,
 
628
    gboolean receive,
 
629
    GAsyncReadyCallback callback,
 
630
    gpointer user_data)
 
631
{
 
632
  GSimpleAsyncResult *result;
 
633
 
 
634
  g_return_if_fail (TP_IS_CALL_STREAM (self));
 
635
  g_return_if_fail (TP_IS_CONTACT (contact));
 
636
  g_return_if_fail (tp_contact_get_connection (contact) ==
 
637
      self->priv->connection);
 
638
 
 
639
  result = g_simple_async_result_new (G_OBJECT (self), callback,
 
640
      user_data, tp_call_stream_set_sending_async);
 
641
 
 
642
  tp_cli_call_stream_call_request_receiving (self, -1,
 
643
      tp_contact_get_handle (contact), receive,
 
644
      generic_async_cb, result, g_object_unref, G_OBJECT (self));
 
645
}
 
646
 
 
647
/**
 
648
 * tp_call_stream_request_receiving_finish:
 
649
 * @self: a #TpCallStream
 
650
 * @result: a #GAsyncResult
 
651
 * @error: a #GError to fill
 
652
 *
 
653
 * Finishes tp_call_stream_request_receiving_async().
 
654
 *
 
655
 * Since: 0.17.5
 
656
 */
 
657
gboolean
 
658
tp_call_stream_request_receiving_finish (TpCallStream *self,
 
659
    GAsyncResult *result,
 
660
    GError **error)
 
661
{
 
662
  _tp_implement_finish_void (self, tp_call_stream_request_receiving_async);
 
663
}