summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--NEWS72
-rw-r--r--configure.ac25
-rw-r--r--extensions/Connection_Interface_Addressing.xml245
-rw-r--r--extensions/Makefile.am3
-rw-r--r--extensions/all.xml13
m---------lib/ext/wocky0
-rw-r--r--plugins/console/channel.c4
-rw-r--r--plugins/test.c1
-rw-r--r--src/Makefile.am8
-rw-r--r--src/call-stream.c2
-rw-r--r--src/conn-addressing.c18
-rw-r--r--src/conn-aliasing.c53
-rw-r--r--src/conn-aliasing.h1
-rw-r--r--src/conn-avatars.c34
-rw-r--r--src/conn-avatars.h9
-rw-r--r--src/conn-client-types.c39
-rw-r--r--src/conn-presence.c2
-rw-r--r--src/conn-presence.h2
-rw-r--r--src/connection.c387
-rw-r--r--src/connection.h9
-rw-r--r--src/ft-channel.c4
-rw-r--r--src/ft-manager.c11
-rw-r--r--src/legacy-caps.c40
-rw-r--r--src/legacy-caps.h42
-rw-r--r--src/media-channel-hold.c423
-rw-r--r--src/media-channel-internal.h93
-rw-r--r--src/media-channel.c3184
-rw-r--r--src/media-channel.h82
-rw-r--r--src/media-factory.c499
-rw-r--r--src/media-factory.h18
-rw-r--r--src/media-stream.c2085
-rw-r--r--src/media-stream.h119
-rw-r--r--src/message-util.c2
-rw-r--r--src/muc-channel.c24
-rw-r--r--src/muc-factory.c35
-rw-r--r--src/private-tubes-factory.c178
-rw-r--r--src/private-tubes-factory.h4
-rw-r--r--src/protocol.c18
-rw-r--r--src/roster.c484
-rw-r--r--src/server-sasl-channel.c2
-rw-r--r--src/tls-certificate.c2
-rw-r--r--src/tube-dbus.c2
-rw-r--r--src/tube-iface.c8
-rw-r--r--src/tube-iface.h6
-rw-r--r--src/tube-stream.c6
-rw-r--r--src/vcard-manager.c53
-rw-r--r--src/write-mgr-file.c85
-rw-r--r--tests/test-handles.c6
-rw-r--r--tests/twisted/Makefile.am45
-rw-r--r--tests/twisted/addressing.py6
-rw-r--r--tests/twisted/avatar-requirements.py20
-rw-r--r--tests/twisted/caps/advertise-contact-caps.py18
-rw-r--r--tests/twisted/caps/advertise-legacy.py110
-rw-r--r--tests/twisted/caps/caps-cache.py14
-rw-r--r--tests/twisted/caps/caps-persistent-cache.py12
-rw-r--r--tests/twisted/caps/from-bare-jid.py23
-rw-r--r--tests/twisted/caps/hashed-caps.py129
-rw-r--r--tests/twisted/caps/jingle-caps.py66
-rw-r--r--tests/twisted/caps/offline.py13
-rw-r--r--tests/twisted/caps/receive-jingle.py117
-rw-r--r--tests/twisted/caps/trust-thyself.py25
-rw-r--r--tests/twisted/caps/tube-caps.py22
-rw-r--r--tests/twisted/caps_helper.py80
-rw-r--r--tests/twisted/client-types.py48
-rw-r--r--tests/twisted/cm/protocol.py23
-rw-r--r--tests/twisted/connect/disco-facebook.py51
-rw-r--r--tests/twisted/connect/test-twice.py26
-rw-r--r--tests/twisted/console.py5
-rw-r--r--tests/twisted/constants.py151
-rw-r--r--tests/twisted/dataforms.py6
-rw-r--r--tests/twisted/file-transfer/file_transfer_helper.py15
-rw-r--r--tests/twisted/file-transfer/ft-client-caps.py30
-rw-r--r--tests/twisted/file-transfer/metadata.py2
-rw-r--r--tests/twisted/file-transfer/test-caps-file-transfer.py16
-rw-r--r--tests/twisted/file-transfer/test-ibb-too-early.py2
-rw-r--r--tests/twisted/file-transfer/test-send-file-declined.py4
-rw-r--r--tests/twisted/file-transfer/test-send-file-send-before-accept.py4
-rw-r--r--tests/twisted/file-transfer/test-send-file-to-unknown-contact.py2
-rw-r--r--tests/twisted/gabbletest.py7
-rw-r--r--tests/twisted/gateways.py11
-rw-r--r--tests/twisted/jingle-share/file_transfer_helper.py19
-rw-r--r--tests/twisted/jingle-share/jingleshareutils.py14
-rw-r--r--tests/twisted/jingle-share/test-caps-file-transfer.py20
-rw-r--r--tests/twisted/jingle-share/test-multift.py63
-rw-r--r--tests/twisted/jingle/accept-extra-stream.py198
-rw-r--r--tests/twisted/jingle/call-basics.py4
-rw-r--r--tests/twisted/jingle/call-codecoffer.py44
-rw-r--r--tests/twisted/jingle/call-google-relay.py2
-rw-r--r--tests/twisted/jingle/call-hold-av.py4
-rw-r--r--tests/twisted/jingle/call-muc.py6
-rw-r--r--tests/twisted/jingle/call-state.py288
-rw-r--r--tests/twisted/jingle/call_helper.py27
-rw-r--r--tests/twisted/jingle/callutils.py8
-rw-r--r--tests/twisted/jingle/decloak-peer.py24
-rw-r--r--tests/twisted/jingle/dtmf-no-audio.py81
-rw-r--r--tests/twisted/jingle/dtmf.py186
-rw-r--r--tests/twisted/jingle/google-relay.py424
-rw-r--r--tests/twisted/jingle/hold-audio.py425
-rw-r--r--tests/twisted/jingle/hold-av.py481
-rw-r--r--tests/twisted/jingle/incoming-basics.py191
-rw-r--r--tests/twisted/jingle/incoming-call-stream-error.py107
-rw-r--r--tests/twisted/jingle/incoming-gmail-modern-jingle.py190
-rw-r--r--tests/twisted/jingle/initial-audio-video.py192
-rw-r--r--tests/twisted/jingle/jingletest2.py8
-rw-r--r--tests/twisted/jingle/misuse.py52
-rw-r--r--tests/twisted/jingle/outgoing-basics.py349
-rw-r--r--tests/twisted/jingle/outgoing-ensure.py217
-rw-r--r--tests/twisted/jingle/outgoing-many-streams.py221
-rw-r--r--tests/twisted/jingle/payload-types.py108
-rw-r--r--tests/twisted/jingle/session-id-collision.py8
-rw-r--r--tests/twisted/jingle/stream-errors-on-content-reject.py246
-rw-r--r--tests/twisted/jingle/stream-errors-on-terminate.py140
-rw-r--r--tests/twisted/jingle/stream-handler-error.py64
-rw-r--r--tests/twisted/jingle/stun-server.py162
-rw-r--r--tests/twisted/jingle/test-content-adding-removal.py168
-rw-r--r--tests/twisted/jingle/test-content-complex.py257
-rw-r--r--tests/twisted/jingle/test-description-info.py213
-rw-r--r--tests/twisted/jingle/test-incoming-call-reject.py112
-rw-r--r--tests/twisted/jingle/test-incoming-iceudp.py104
-rw-r--r--tests/twisted/jingle/test-outgoing-call-rejected.py86
-rw-r--r--tests/twisted/jingle/test-outgoing-iceudp.py162
-rw-r--r--tests/twisted/jingle/test-wait-for-caps-incomplete.py71
-rw-r--r--tests/twisted/jingle/test-wait-for-caps.py99
-rw-r--r--tests/twisted/jingle/transport-info-parsing.py86
-rw-r--r--tests/twisted/last-activity.py2
-rw-r--r--tests/twisted/mail-notification.py3
-rw-r--r--tests/twisted/muc/avatars.py12
-rw-r--r--tests/twisted/muc/chat-states.py4
-rw-r--r--tests/twisted/muc/conference.py3
-rw-r--r--tests/twisted/muc/kicked.py9
-rw-r--r--tests/twisted/muc/name-conflict.py8
-rw-r--r--tests/twisted/muc/only-text-when-needed.py9
-rw-r--r--tests/twisted/muc/password.py8
-rw-r--r--tests/twisted/muc/presence-before-closing.py19
-rw-r--r--tests/twisted/muc/renamed.py13
-rw-r--r--tests/twisted/muc/room-config.py12
-rw-r--r--tests/twisted/muc/room.py5
-rw-r--r--tests/twisted/muc/roomlist.py128
-rw-r--r--tests/twisted/muc/scrollback.py8
-rw-r--r--tests/twisted/muc/send-error.py37
-rw-r--r--tests/twisted/muc/subject.py5
-rw-r--r--tests/twisted/muc/test-ensure.py42
-rw-r--r--tests/twisted/muc/test-muc-alias.py39
-rw-r--r--tests/twisted/muc/test-muc-invitation.py63
-rw-r--r--tests/twisted/muc/test-muc-ownership.py37
-rw-r--r--tests/twisted/muc/test-muc.py52
-rw-r--r--tests/twisted/mucutil.py20
-rw-r--r--tests/twisted/olpc/change-notifications.py2
-rw-r--r--tests/twisted/olpc/current-activity.py2
-rw-r--r--tests/twisted/olpc/olpc-muc-invitation.py19
-rw-r--r--tests/twisted/olpc/olpc-muc-prop-change.py19
-rw-r--r--tests/twisted/pep-support.py5
-rw-r--r--tests/twisted/plugin-channel-managers.py8
-rw-r--r--tests/twisted/power-save.py12
-rw-r--r--tests/twisted/presence/decloak.py4
-rw-r--r--tests/twisted/presence/error.py2
-rw-r--r--tests/twisted/presence/initial-contact-presence.py8
-rw-r--r--tests/twisted/presence/presence.py17
-rw-r--r--tests/twisted/presence/set-idempotence.py8
-rw-r--r--tests/twisted/presence/shared-status.py9
-rw-r--r--tests/twisted/presence_helper.py8
-rw-r--r--tests/twisted/pubsub.py1
-rw-r--r--tests/twisted/roster/authorize.py142
-rw-r--r--tests/twisted/roster/edit-before-roster.py2
-rw-r--r--tests/twisted/roster/ensure.py53
-rw-r--r--tests/twisted/roster/groups-12791.py54
-rw-r--r--tests/twisted/roster/groups.py65
-rw-r--r--tests/twisted/roster/initial-aliases.py5
-rw-r--r--tests/twisted/roster/push-from-contact.py16
-rw-r--r--tests/twisted/roster/push-without-id.py22
-rw-r--r--tests/twisted/roster/removed-from-rp-subscribe.py92
-rw-r--r--tests/twisted/roster/request-group-after-roster.py46
-rw-r--r--tests/twisted/roster/request-group-before-roster.py48
-rw-r--r--tests/twisted/roster/test-google-roster.py240
-rw-r--r--tests/twisted/roster/test-roster-item-deletion.py52
-rw-r--r--tests/twisted/roster/test-roster-subscribe.py145
-rw-r--r--tests/twisted/roster/test-roster.py35
-rw-r--r--tests/twisted/roster/test-save-alias-to-roster.py29
-rw-r--r--tests/twisted/rostertest.py180
-rw-r--r--tests/twisted/run-test.sh.in30
-rw-r--r--tests/twisted/sasl/abort.py4
-rw-r--r--tests/twisted/sasl/close.py2
-rw-r--r--tests/twisted/sasl/complex.py4
-rw-r--r--tests/twisted/sasl/jabber_auth.py10
-rw-r--r--tests/twisted/sasl/plain.py7
-rw-r--r--tests/twisted/sasl/saslutil.py18
-rw-r--r--tests/twisted/sasl/telepathy-password.py2
-rw-r--r--tests/twisted/servicetest.py223
-rw-r--r--tests/twisted/sidecar-own-caps.py5
-rw-r--r--tests/twisted/sidecars.py2
-rw-r--r--tests/twisted/test-debug.py33
-rw-r--r--tests/twisted/test-fallback-socks5-proxy.py2
-rw-r--r--tests/twisted/test-location.py20
-rw-r--r--tests/twisted/text/destroy.py56
-rw-r--r--tests/twisted/text/ensure.py31
-rw-r--r--tests/twisted/text/facebook-own-message.py2
-rw-r--r--tests/twisted/text/initiate-requestotron.py13
-rw-r--r--tests/twisted/text/initiate.py44
-rw-r--r--tests/twisted/text/receipts.py3
-rw-r--r--tests/twisted/text/respawn.py77
-rw-r--r--tests/twisted/text/send-error.py61
-rw-r--r--tests/twisted/text/send-to-correct-resource.py14
-rw-r--r--tests/twisted/text/test-chat-state.py39
-rw-r--r--tests/twisted/text/test-text-delayed.py22
-rw-r--r--tests/twisted/text/test-text-no-body.py10
-rw-r--r--tests/twisted/text/test-text.py83
-rw-r--r--tests/twisted/tools/exec-with-log.sh.in2
-rw-r--r--tests/twisted/tubes/accept-muc-dbus-tube.py18
-rw-r--r--tests/twisted/tubes/accept-muc-stream-tube.py51
-rw-r--r--tests/twisted/tubes/accept-private-dbus-tube.py4
-rw-r--r--tests/twisted/tubes/check-create-tube-return.py6
-rw-r--r--tests/twisted/tubes/close-muc-with-closed-tube.py52
-rw-r--r--tests/twisted/tubes/ensure-si-tube.py2
-rw-r--r--tests/twisted/tubes/offer-muc-dbus-tube.py25
-rw-r--r--tests/twisted/tubes/offer-muc-stream-tube.py22
-rw-r--r--tests/twisted/tubes/offer-private-dbus-tube.py4
-rw-r--r--tests/twisted/tubes/offer-private-stream-tube.py4
-rw-r--r--tests/twisted/tubes/test-get-available-tubes.py14
-rw-r--r--tests/twisted/tubes/test-socks5-muc.py2
-rw-r--r--tests/twisted/tubes/tubetestutil.py7
-rw-r--r--tests/twisted/vcard/disconnect-during-pep.py2
-rw-r--r--tests/twisted/vcard/get-contact-info.py14
-rw-r--r--tests/twisted/vcard/overlapping-sets.py2
-rw-r--r--tests/twisted/vcard/refresh-contact-info.py2
-rw-r--r--tests/twisted/vcard/test-alias-empty-vcard.py2
-rw-r--r--tests/twisted/vcard/test-alias-message.py25
-rw-r--r--tests/twisted/vcard/test-alias-pep.py2
-rw-r--r--tests/twisted/vcard/test-alias.py2
-rw-r--r--tests/twisted/vcard/test-avatar-async.py31
-rw-r--r--tests/twisted/vcard/test-avatar-retrieved.py2
-rw-r--r--tests/twisted/vcard/test-avatar-tokens.py11
-rw-r--r--tests/twisted/vcard/test-avatar.py12
-rw-r--r--tests/twisted/vcard/test-set-alias.py2
-rw-r--r--tests/twisted/vcard/test-vcard-cache.py11
-rw-r--r--tests/twisted/vcard/test-vcard-race.py3
-rw-r--r--tests/twisted/vcard/update-get-failed.py2
-rw-r--r--tests/twisted/version.py2
-rw-r--r--tools/lcov.am2
239 files changed, 2640 insertions, 15884 deletions
diff --git a/.gitignore b/.gitignore
index 9c42dc2c1..bb2a5bed8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ Makefile.in
_gen
/aclocal.m4
/autom4te.cache
+/build-aux
/compile
/config.cache
/config.guess
diff --git a/NEWS b/NEWS
index 4ee35856c..275031be5 100644
--- a/NEWS
+++ b/NEWS
@@ -1,16 +1,82 @@
-telepathy-gabble 0.17.6 (UNRELEASED)
+telepathy-gabble 0.19.0 (UNRELEASED)
====================================
-Enhancements:
+The “very confused owl” release.
+
+Dependencies:
+
+• telepathy-glib ≥ 0.21.1 is required.
+
+External changes:
+
+• Remove support for legacy StreamedMedia calls, and legacy Capabilities;
+ Gabble only implements Call1 calls and ContactCapabilities now
+ (fd.o #69194; Xavier, Simon, Guillaume)
+
+• Always announce channels one at a time (fd.o #69194, Simon)
+
+Fixes:
+
+• Stop claiming to implement legacy Presence, which was deleted in 2011
+ (fd.o #69194, Guillaume)
+
+Internal changes:
+
+• Fix various deprecated things (fd.o #69194, Simon)
+
+• Improved regression test coverage (fd.o #69474, Simon)
+
+telepathy-gabble 0.18.1 (2013-09-06)
+====================================
+
+This stable release fixes connection issues with Facebook which have been
+recently introduced because of a change in their XMPP servers.
+
+Fixes:
+
+• update Wocky:
+ · fd.o #68829: If we send an IQ to a server allow "from" to be empty (David
+ Edmundson)
+
+telepathy-gabble 0.18.0 (2013-08-09)
+====================================
+
+The “sea view over the steelworks” release.
+
+This is a new stable branch, recommended for use with GNOME 3.10.
+
+Summary of changes since 0.16.x:
+
+• GLib 2.32 is (directly) required
+• better interop with Google webmail for audio/video calls
+• better interop with Google and MSN servers
+• better interop with iChat
+• don't claim to support X-TELEPATHY-PASSWORD if the username is unknown
+• look up a STUN server automatically, using DNS SRV
+• old-style Tubes channels have been removed
+• bug fixes
+
+Enhancements since 0.17.6:
• Check for GLib 2.32 in the top-level configure.ac, and drop fallback paths
for older GLib (Simon)
-Fixes:
+Fixes since 0.17.6:
+
+• Update Wocky to its new gabble-0.18 branch:
+ · fd.o #67875: make the documentation build successfully (Simon)
+ · fd.o #67900: make the tests pass with GLib 2.36 (Simon)
• fd.o #65290: wrap uninstalled regression tests in run-test.sh so they
can work under Automake ≥ 1.13 (Simon)
+• fd.o #67828: fix a test failure with telepathy-glib 0.20.3/0.21.1 or later
+ (Simon)
+
+• Debian #714534: avoid naming a function parameter "errno", which
+ is technically a reserved word and might be a macro expanding to an
+ lvalue expression (Samuel Thibault)
+
telepathy-gabble 0.17.5 (2013-06-06)
====================================
diff --git a/configure.ac b/configure.ac
index ed5d4e229..d82124a8f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_PREREQ([2.59])
+AC_PREREQ([2.60])
# Making releases:
# set the new version number:
@@ -8,8 +8,8 @@ AC_PREREQ([2.59])
# set gabble_nano_version to 0.
m4_define([gabble_major_version], [0])
-m4_define([gabble_minor_version], [17])
-m4_define([gabble_micro_version], [5])
+m4_define([gabble_minor_version], [18])
+m4_define([gabble_micro_version], [999])
m4_define([gabble_nano_version], [1])
# Some magic
@@ -23,6 +23,7 @@ AC_INIT([Telepathy Gabble], [gabble_version],
[https://bugs.freedesktop.org/enter_bug.cgi?product=Telepathy&component=gabble])
AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([1.9 -Wno-portability tar-ustar subdir-objects])
AM_CONFIG_HEADER(config.h)
@@ -278,17 +279,6 @@ AC_SUBST(ENABLE_PLUGINS)
AM_CONDITIONAL(ENABLE_PLUGIN_API, test x$enable_plugin_api = xyes)
-AC_ARG_ENABLE(channel-type-call,
- AC_HELP_STRING([--disable-channel-type-call],
- [disable support for the draft Channel.Type.Call]),
- [enable_channel_type_call=$enableval], [enable_channel_type_call=yes])
-
-if test x$enable_channel_type_call = xyes; then
- AC_DEFINE(ENABLE_CHANNEL_TYPE_CALL, [], [Enable Channel.Type.Call])
-fi
-
-AM_CONDITIONAL(ENABLE_CHANNEL_TYPE_CALL, test x$enable_channel_type_call = xyes)
-
dnl Check for D-Bus
PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.1.0, dbus-glib-1 >= 0.82])
@@ -297,9 +287,9 @@ AC_SUBST(DBUS_LIBS)
AC_DEFINE(TP_SEAL_ENABLE, [], [Prevent to use sealed variables])
AC_DEFINE(TP_DISABLE_SINGLE_INCLUDE, [], [Disable single header include])
-AC_DEFINE(TP_VERSION_MIN_REQUIRED, TP_VERSION_0_18, [Ignore post 0.18 deprecations])
-AC_DEFINE(TP_VERSION_MAX_ALLOWED, TP_VERSION_0_20, [Prevent post 0.20 APIs])
-PKG_CHECK_MODULES(TP_GLIB, [telepathy-glib >= 0.19.9])
+AC_DEFINE([TP_VERSION_MIN_REQUIRED], [TP_VERSION_0_22], [Ignore post 0.22 deprecations])
+AC_DEFINE([TP_VERSION_MAX_ALLOWED], [TP_VERSION_0_22], [Prevent post 0.22 APIs])
+PKG_CHECK_MODULES(TP_GLIB, [telepathy-glib >= 0.21.1])
AC_SUBST(TP_GLIB_CFLAGS)
AC_SUBST(TP_GLIB_LIBS)
@@ -470,7 +460,6 @@ Configure summary:
Client type.................: \"${CLIENT_TYPE}\"
Plugin support..............: ${enable_plugins}
Plugin headers installed....: ${enable_plugin_api}
- Channel.Type.Call support...: ${enable_channel_type_call}
Google relay support........: ${enable_google_relay}
File transfer support.......: ${enable_ft}
Jingle file transfer support: ${enable_jingle_ft}
diff --git a/extensions/Connection_Interface_Addressing.xml b/extensions/Connection_Interface_Addressing.xml
deleted file mode 100644
index 2d8145f3c..000000000
--- a/extensions/Connection_Interface_Addressing.xml
+++ /dev/null
@@ -1,245 +0,0 @@
-<?xml version="1.0" ?>
-<node name="/Connection_Interface_Addressing" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
- <tp:copyright> Copyright (C) 2010 Collabora Limited </tp:copyright>
- <tp:license xmlns="http://www.w3.org/1999/xhtml">
- <p>This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or (at
- your option) any later version.</p>
-
- <p>This library is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
- General Public License for more details.</p>
-
- <p>You should have received a copy of the GNU Lesser General Public License
- along with this library; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</p>
- </tp:license>
- <interface name="org.freedesktop.Telepathy.Connection.Interface.Addressing1"
- tp:causes-havoc="experimental">
- <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
- <tp:requires interface="org.freedesktop.Telepathy.Connection.Interface.Contacts"/>
- <tp:added version="0.19.12">(as draft)</tp:added>
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>This interface deals with the multiple address types that can
- refer to the same contact, such as vCard fields and URIs.</p>
-
- <p>It can be used to retrieve contacts with a specific addresses
- through <tp:member-ref>GetContactsByVCardField</tp:member-ref> and
- <tp:member-ref>GetContactsByURI</tp:member-ref>, as well as
- defining the various addressing methods for a given contact
- through this interface's contact attributes.</p>
- </tp:docstring>
-
- <method name="GetContactsByVCardField"
- tp:name-for-bindings="Get_Contacts_By_VCard_Field">
- <arg direction="in" name="Field" type="s">
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>The vCard field of the addresses we are requesting. The
- field name SHOULD be in lower case. Supported
- fields can be found in
- <tp:dbus-ref namespace="org.freedesktop.Telepathy.Protocol.Interface.Addressing">AddressableVCardFields</tp:dbus-ref>.</p>
-
- <p>The <code>url</code> vCard field MUST NOT appear here; see
- <tp:member-ref>GetContactsByURI</tp:member-ref> instead.</p>
-
- <tp:rationale>
- <p>In practice, protocols have a limited set of URI
- schemes that make sense to resolve as a contact.</p>
- </tp:rationale>
-
- </tp:docstring>
- </arg>
- <arg direction="in" name="Addresses" type="as">
- <tp:docstring>
- The addresses to get contact handles for. The address types
- should match the given vCard field.
- </tp:docstring>
- </arg>
- <arg direction="in" name="Interfaces" type="as"
- tp:type="DBus_Interface[]">
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>A list of strings indicating which D-Bus interfaces the calling
- process is interested in. All supported attributes from these
- interfaces, whose values can be obtained without additional network
- activity, will be in the reply.</p>
-
- <p>Attributes from this interface and from
- <tp:dbus-ref>org.freedesktop.Telepathy.Connection</tp:dbus-ref>
- are always returned, and need not be requested
- explicitly.</p>
-
- <p>The behavior of this parameter is similar to the same
- parameter in
- <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">Contacts.GetContactAttributes</tp:dbus-ref>.</p>
- </tp:docstring>
- </arg>
-
- <arg direction="out" type="a{su}" name="Requested"
- tp:type="Addressing_Normalization_Map">
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>A mapping from requested vCard addresses to the corresponding
- contact handles.</p>
-
- <p>Requested addresses that are not valid or understood for this protocol
- MUST be omitted from the mapping.</p>
- </tp:docstring>
- </arg>
-
- <arg direction="out" type="a{ua{sv}}" name="Attributes"
- tp:type="Contact_Attributes_Map">
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>A dictionary mapping the contact handles to contact attributes.
- If any of the requested addresses are in fact invalid, they are
- simply omitted from this mapping. If contact attributes are not
- immediately known, the behaviour is defined by the interface;
- the attribute should either be omitted from the result or
- replaced with a default value.</p>
-
- <p>Requested addresses that are not valid or understood for this protocol
- MUST be omitted from the mapping.</p>
-
- <p>Each contact's attributes will always include at least the
- identifier that would be obtained by inspecting the handle
- (<code>org.freedesktop.Telepathy.Connection/contact-id</code>).
- </p>
- </tp:docstring>
- </arg>
-
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>Request contacts and retrieve their attributes using a given field
- in their vCards.</p>
-
- <p>The connection manager should record that these handles are in
- use by the client who invokes this method, and must not
- deallocate the handles until the client disconnects from the
- bus or calls the
- <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.ReleaseHandles</tp:dbus-ref>
- method.</p>
- </tp:docstring>
-
- <tp:possible-errors>
- <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
- </tp:possible-errors>
- </method>
-
- <method name="GetContactsByURI"
- tp:name-for-bindings="Get_Contacts_By_URI">
- <arg direction="in" name="URIs" type="as">
- <tp:docstring>
- The URI addresses to get contact handles for. Supported
- schemes can be found in
- <tp:dbus-ref namespace="org.freedesktop.Telepathy.Protocol.Interface.Addressing">AddressableURISchemes</tp:dbus-ref>.
- </tp:docstring>
- </arg>
- <arg direction="in" name="Interfaces" type="as"
- tp:type="DBus_Interface[]">
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>A list of strings indicating which D-Bus interfaces the calling
- process is interested in. All supported attributes from these
- interfaces, whose values can be obtained without additional network
- activity, will be in the reply.</p>
-
- <p>Attributes from this interface and from
- <tp:dbus-ref>org.freedesktop.Telepathy.Connection</tp:dbus-ref>
- are always returned, and need not be requested
- explicitly.</p>
-
- <p>The behavior of this parameter is similar to the same
- parameter in
- <tp:dbus-ref namespace="org.freedesktop.Telepathy.Connection.Interface">Contacts.GetContactAttributes</tp:dbus-ref>.</p>
- </tp:docstring>
- </arg>
-
- <arg direction="out" type="a{su}" name="Requested"
- tp:type="Addressing_Normalization_Map">
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>A mapping of requested URIs to the corresponding contact handles.</p>
-
- <p>Requested URIs that are not valid or understood for this protocol
- MUST be omitted from the mapping.</p>
- </tp:docstring>
- </arg>
-
- <arg direction="out" type="a{ua{sv}}" name="Attributes"
- tp:type="Contact_Attributes_Map">
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>A dictionary mapping the contact handles to contact attributes.
- If any of the requested addresses are in fact invalid, they are
- simply omitted from this mapping. If contact attributes are not
- immediately known, the behaviour is defined by the interface;
- the attribute should either be omitted from the result or
- replaced with a default value.</p>
-
- <p>Requested URIs that are not valid or understood for this protocol
- MUST be omitted from the mapping.</p>
-
- <p>Each contact's attributes will always include at least the
- identifier that would be obtained by inspecting the handle
- (<code>org.freedesktop.Telepathy.Connection/contact-id</code>).
- </p>
- </tp:docstring>
- </arg>
-
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>Request contacts and retrieve their attributes using URI addresses.</p>
-
- <p>The connection manager should record that these handles are in
- use by the client who invokes this method, and must not
- deallocate the handles until the client disconnects from the
- bus or calls the
- <tp:dbus-ref namespace="org.freedesktop.Telepathy">Connection.ReleaseHandles</tp:dbus-ref>
- method.</p>
- </tp:docstring>
-
- <tp:possible-errors>
- <tp:error name="org.freedesktop.Telepathy.Error.Disconnected"/>
- </tp:possible-errors>
- </method>
-
- <tp:mapping name="VCard_Field_Address_Map" array-name="">
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>A mapping of vCard fields and addresses that repreent
- the given contact.</p>
- </tp:docstring>
- <tp:member type="s" name="VCard_Field"/>
- <tp:member type="s" name="Address"/>
- </tp:mapping>
-
- <tp:contact-attribute name="addresses" type="a{ss}"
- tp:type="VCard_Field_Address_Map">
- <tp:docstring>
- The various vCard addresses that identify this contact.
- </tp:docstring>
- </tp:contact-attribute>
-
- <tp:contact-attribute name="uris" type="as">
- <tp:docstring>
- The various URI addresses that identify this contact.
- </tp:docstring>
- </tp:contact-attribute>
-
- <tp:mapping name="Addressing_Normalization_Map">
- <tp:docstring>
- A map from URIs/vCard addresses to the corresponding handle.
- </tp:docstring>
- <tp:added version="0.25.UNRELEASED"/>
-
- <tp:member type="s" name="Requested_String">
- <tp:docstring>
- The URI or vCard address that has been requested by
- <tp:member-ref>GetContactsByVCardField</tp:member-ref> or
- <tp:member-ref>GetContactsByURI</tp:member-ref>.
- </tp:docstring>
- </tp:member>
- <tp:member type="u" name="Handle" tp:type="Contact_Handle">
- <tp:docstring>
- A nonzero handle.
- </tp:docstring>
- </tp:member>
- </tp:mapping>
-
- </interface>
-</node>
-<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index b435ae3f4..2e4ac3690 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -4,7 +4,6 @@ EXTRA_DIST = \
all.xml \
Channel_Type_FileTransfer_Future.xml \
Connection_Future.xml \
- Connection_Interface_Addressing.xml \
Connection_Interface_Gabble_Decloak.xml \
Gabble_Plugin_Console.xml \
Gabble_Plugin_Gateways.xml \
@@ -49,7 +48,7 @@ DROP_NAMESPACE = sed -e 's@xmlns:tp="http://telepathy\.freedesktop\.org/wiki/Dbu
XSLTPROCFLAGS = --nonet --novalid
_gen/all.xml: all.xml $(wildcard *.xml) Makefile.am
- @$(mkdir_p) _gen
+ @$(MKDIR_P) _gen
$(AM_V_GEN)$(PYTHON) $(tools_dir)/xincludator.py \
$< > $@.tmp && mv $@.tmp $@
diff --git a/extensions/all.xml b/extensions/all.xml
index 99997d6db..8b2205f09 100644
--- a/extensions/all.xml
+++ b/extensions/all.xml
@@ -33,8 +33,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA</p>
from="Telepathy specification"/>
</tp:generic-types>
-<xi:include href="Connection_Interface_Addressing.xml"/>
-
<xi:include href="OLPC_Buddy_Info.xml"/>
<xi:include href="OLPC_Activity_Properties.xml"/>
@@ -108,17 +106,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA</p>
<tp:external-type name="Connection_Status" type="u"
from="Telepathy specification"/>
- <!-- use types from Channel_Type_Streamed_Media.xml -->
- <tp:enum name="Media_Stream_Type" type="u"
- array-name="Media_Stream_Type_List">
- <tp:enumvalue suffix="Audio" value="0">
- <tp:docstring>An audio stream</tp:docstring>
- </tp:enumvalue>
- <tp:enumvalue suffix="Video" value="1">
- <tp:docstring>A video stream</tp:docstring>
- </tp:enumvalue>
- </tp:enum>
-
<!-- use types from generic-types.xml -->
<tp:struct name="Socket_Address_IP" array-name="Socket_Address_IP_List">
<tp:docstring>An IP address and port.</tp:docstring>
diff --git a/lib/ext/wocky b/lib/ext/wocky
-Subproject 7f139058d3323d99b11667f93cb4abcb3ccc9c4
+Subproject 779eac498ae44c0e4cb581ae73edfe2d8408167
diff --git a/plugins/console/channel.c b/plugins/console/channel.c
index 6a9503eb6..3ddbef905 100644
--- a/plugins/console/channel.c
+++ b/plugins/console/channel.c
@@ -21,6 +21,10 @@
#include "console/channel.h"
#include <string.h>
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
#include <wocky/wocky.h>
#include <gabble/gabble.h>
#include "extensions/extensions.h"
diff --git a/plugins/test.c b/plugins/test.c
index bb6b71959..e084b00e2 100644
--- a/plugins/test.c
+++ b/plugins/test.c
@@ -5,6 +5,7 @@
#include <stdio.h>
#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
#include <wocky/wocky.h>
diff --git a/src/Makefile.am b/src/Makefile.am
index 22a0278db..6f5b47c71 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -73,8 +73,6 @@ libgabble_convenience_la_SOURCES = \
im-channel.c \
im-factory.h \
im-factory.c \
- legacy-caps.h \
- legacy-caps.c \
message-util.h \
message-util.c \
muc-channel.h \
@@ -163,12 +161,6 @@ libgabble_convenience_la_SOURCES += \
jingle-mint.c \
jingle-tp-util.h \
jingle-tp-util.c \
- media-channel.h \
- media-channel-internal.h \
- media-channel.c \
- media-channel-hold.c \
- media-stream.h \
- media-stream.c \
media-factory.h \
media-factory.c
endif
diff --git a/src/call-stream.c b/src/call-stream.c
index 89af93ce1..1a28969af 100644
--- a/src/call-stream.c
+++ b/src/call-stream.c
@@ -250,7 +250,7 @@ _endpoint_state_changed_cb (
GParamSpec *spec,
WockyJingleContent *content)
{
- TpMediaStreamState state;
+ TpStreamEndpointState state;
/* We only care about connecting RTP, RTCP is optional */
state = tp_call_stream_endpoint_get_state (endpoint, 1);
diff --git a/src/conn-addressing.c b/src/conn-addressing.c
index 7fff35455..60431159d 100644
--- a/src/conn-addressing.c
+++ b/src/conn-addressing.c
@@ -34,7 +34,7 @@
static const char *assumed_interfaces[] = {
TP_IFACE_CONNECTION,
- GABBLE_IFACE_CONNECTION_INTERFACE_ADDRESSING,
+ TP_IFACE_CONNECTION_INTERFACE_ADDRESSING,
NULL
};
@@ -48,11 +48,11 @@ _fill_contact_attributes (TpHandleRepoIface *contact_repo,
GHashTable *addresses = gabble_vcard_addresses_for_handle (contact_repo, contact);
tp_contacts_mixin_set_contact_attribute (attributes_hash,
- contact, GABBLE_IFACE_CONNECTION_INTERFACE_ADDRESSING"/uris",
+ contact, TP_TOKEN_CONNECTION_INTERFACE_ADDRESSING_URIS,
tp_g_value_slice_new_take_boxed (G_TYPE_STRV, uris));
tp_contacts_mixin_set_contact_attribute (attributes_hash,
- contact, GABBLE_IFACE_CONNECTION_INTERFACE_ADDRESSING"/addresses",
+ contact, TP_TOKEN_CONNECTION_INTERFACE_ADDRESSING_ADDRESSES,
tp_g_value_slice_new_take_boxed (TP_HASH_TYPE_STRING_STRING_MAP, addresses));
}
@@ -73,7 +73,7 @@ conn_addressing_fill_contact_attributes (GObject *obj,
}
static void
-conn_addressing_get_contacts_by_uri (GabbleSvcConnectionInterfaceAddressing *iface,
+conn_addressing_get_contacts_by_uri (TpSvcConnectionInterfaceAddressing *iface,
const gchar **uris,
const gchar **interfaces,
DBusGMethodInvocation *context)
@@ -101,7 +101,7 @@ conn_addressing_get_contacts_by_uri (GabbleSvcConnectionInterfaceAddressing *ifa
attributes = tp_contacts_mixin_get_contact_attributes (G_OBJECT (iface), handles,
interfaces, assumed_interfaces, sender);
- gabble_svc_connection_interface_addressing_return_from_get_contacts_by_uri (
+ tp_svc_connection_interface_addressing_return_from_get_contacts_by_uri (
context, requested, attributes);
g_array_unref (handles);
@@ -111,7 +111,7 @@ conn_addressing_get_contacts_by_uri (GabbleSvcConnectionInterfaceAddressing *ifa
}
static void
-conn_addressing_get_contacts_by_vcard_field (GabbleSvcConnectionInterfaceAddressing *iface,
+conn_addressing_get_contacts_by_vcard_field (TpSvcConnectionInterfaceAddressing *iface,
const gchar *field,
const gchar **addresses,
const gchar **interfaces,
@@ -141,7 +141,7 @@ conn_addressing_get_contacts_by_vcard_field (GabbleSvcConnectionInterfaceAddress
attributes = tp_contacts_mixin_get_contact_attributes (G_OBJECT (iface), handles,
interfaces, assumed_interfaces, sender);
- gabble_svc_connection_interface_addressing_return_from_get_contacts_by_vcard_field (
+ tp_svc_connection_interface_addressing_return_from_get_contacts_by_vcard_field (
context, requested, attributes);
g_array_unref (handles);
@@ -153,7 +153,7 @@ conn_addressing_get_contacts_by_vcard_field (GabbleSvcConnectionInterfaceAddress
void
conn_addressing_init (GabbleConnection *self) {
tp_contacts_mixin_add_contact_attributes_iface (G_OBJECT (self),
- GABBLE_IFACE_CONNECTION_INTERFACE_ADDRESSING,
+ TP_IFACE_CONNECTION_INTERFACE_ADDRESSING,
conn_addressing_fill_contact_attributes);
}
@@ -162,7 +162,7 @@ conn_addressing_iface_init (gpointer g_iface,
gpointer iface_data)
{
#define IMPLEMENT(x) \
- gabble_svc_connection_interface_addressing_implement_##x (\
+ tp_svc_connection_interface_addressing_implement_##x (\
g_iface, conn_addressing_##x)
IMPLEMENT (get_contacts_by_uri);
diff --git a/src/conn-aliasing.c b/src/conn-aliasing.c
index 26637039e..d7870eef5 100644
--- a/src/conn-aliasing.c
+++ b/src/conn-aliasing.c
@@ -39,16 +39,12 @@
static void gabble_conn_aliasing_pep_nick_reply_handler (
GabbleConnection *conn, WockyStanza *msg, TpHandle handle);
-static GQuark gabble_conn_aliasing_pep_alias_quark (void);
static GabbleConnectionAliasSource _gabble_connection_get_cached_remote_alias (
GabbleConnection *, TpHandle, gchar **);
static void maybe_request_vcard (GabbleConnection *self, TpHandle handle,
GabbleConnectionAliasSource source);
-/* distinct from any strdup()d pointer - used for negative caching */
-static const gchar *NO_ALIAS = "";
-
/**
* gabble_connection_get_alias_flags
*
@@ -202,12 +198,10 @@ static void
_cache_negatively (GabbleConnection *self,
TpHandle handle)
{
- TpBaseConnection *base = (TpBaseConnection *) self;
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (base,
- TP_HANDLE_TYPE_CONTACT);
-
- tp_handle_set_qdata (contact_handles, handle,
- gabble_conn_aliasing_pep_alias_quark (), (gchar *) NO_ALIAS, NULL);
+ /* We don't actually need to distinguish between "uncached" and
+ * "known to have no alias" because of how PEP works, so just
+ * remove it from the cache. */
+ g_hash_table_remove (self->pep_alias_cache, GUINT_TO_POINTER (handle));
}
/* Cache pep if successful */
@@ -632,20 +626,6 @@ gabble_connection_set_aliases (TpSvcConnectionInterfaceAliasing *iface,
}
}
-
-GQuark
-gabble_conn_aliasing_pep_alias_quark (void)
-{
- static GQuark quark = 0;
-
- if (G_UNLIKELY (quark == 0))
- quark = g_quark_from_static_string
- ("gabble_conn_aliasing_pep_alias_quark");
-
- return quark;
-}
-
-
static gboolean
_grab_nickname (GabbleConnection *self,
TpHandle handle,
@@ -654,7 +634,6 @@ _grab_nickname (GabbleConnection *self,
TpBaseConnection *base = (TpBaseConnection *) self;
TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (base,
TP_HANDLE_TYPE_CONTACT);
- GQuark quark = gabble_conn_aliasing_pep_alias_quark ();
const gchar *old, *nickname;
node = wocky_node_get_child_ns (node, "nick", NS_NICK);
@@ -668,23 +647,26 @@ _grab_nickname (GabbleConnection *self,
}
nickname = node->content;
- old = tp_handle_get_qdata (contact_handles, handle, quark);
+
+ old = g_hash_table_lookup (self->pep_alias_cache, GUINT_TO_POINTER (handle));
if (tp_strdiff (old, nickname))
{
if (nickname == NULL)
{
- DEBUG ("got empty <nick/> node, caching as NO_ALIAS");
+ DEBUG ("got empty <nick/> node, caching negatively");
_cache_negatively (self, handle);
}
else
{
- tp_handle_set_qdata (contact_handles, handle, quark, g_strdup (nickname),
- g_free);
+ DEBUG ("caching positively");
+ g_hash_table_insert (self->pep_alias_cache, GUINT_TO_POINTER (handle),
+ g_strdup (nickname));
}
gabble_conn_aliasing_nickname_updated ((GObject *) self, handle, self);
}
+
return TRUE;
}
@@ -909,9 +891,9 @@ get_cached_remote_alias (
const gchar *tmp;
gchar *resource;
- tmp = tp_handle_get_qdata (contact_handles, handle,
- gabble_conn_aliasing_pep_alias_quark ());
- if (tmp != NULL && tmp != NO_ALIAS)
+ tmp = g_hash_table_lookup (conn->pep_alias_cache, GUINT_TO_POINTER (handle));
+
+ if (tmp != NULL)
{
maybe_set (alias, tmp);
return GABBLE_CONNECTION_ALIAS_FROM_PRESENCE;
@@ -1183,12 +1165,19 @@ conn_aliasing_init (GabbleConnection *conn)
conn_aliasing_fill_contact_attributes);
conn->pep_nick = wocky_pep_service_new (NS_NICK, TRUE);
+ conn->pep_alias_cache = g_hash_table_new_full (NULL, NULL, NULL, g_free);
g_signal_connect (conn->pep_nick, "changed",
G_CALLBACK (pep_nick_node_changed), conn);
}
void
+conn_aliasing_finalize (GabbleConnection *conn)
+{
+ tp_clear_pointer (&conn->pep_alias_cache, g_hash_table_unref);
+}
+
+void
conn_aliasing_iface_init (gpointer g_iface, gpointer iface_data)
{
TpSvcConnectionInterfaceAliasingClass *klass = g_iface;
diff --git a/src/conn-aliasing.h b/src/conn-aliasing.h
index 353e3238e..d165449b4 100644
--- a/src/conn-aliasing.h
+++ b/src/conn-aliasing.h
@@ -28,6 +28,7 @@
G_BEGIN_DECLS
void conn_aliasing_init (GabbleConnection *conn);
+void conn_aliasing_finalize (GabbleConnection *conn);
void conn_aliasing_iface_init (gpointer g_iface, gpointer iface_data);
void gabble_conn_aliasing_nickname_updated (GObject *object,
diff --git a/src/conn-avatars.c b/src/conn-avatars.c
index a90555113..681a04df4 100644
--- a/src/conn-avatars.c
+++ b/src/conn-avatars.c
@@ -991,3 +991,37 @@ conn_avatars_properties_getter (GObject *object,
g_value_set_uint (value, GPOINTER_TO_UINT (getter_data));
}
}
+
+void
+gabble_connection_dup_avatar_requirements (GStrv *supported_mime_types,
+ guint *min_height,
+ guint *min_width,
+ guint *rec_height,
+ guint *rec_width,
+ guint *max_height,
+ guint *max_width,
+ guint *max_bytes)
+{
+ if (supported_mime_types != NULL)
+ {
+ *supported_mime_types = g_strdupv ((gchar **) mimetypes);
+ }
+
+ if (min_height != NULL)
+ *min_height = AVATAR_MIN_PX;
+ if (min_width != NULL)
+ *min_width = AVATAR_MIN_PX;
+
+ if (rec_height != NULL)
+ *rec_height = AVATAR_REC_PX;
+ if (rec_width != NULL)
+ *rec_width = AVATAR_REC_PX;
+
+ if (max_height != NULL)
+ *max_height = AVATAR_MAX_PX;
+ if (max_width != NULL)
+ *max_width = AVATAR_MAX_PX;
+
+ if (max_bytes != NULL)
+ *max_bytes = AVATAR_MAX_BYTES;
+}
diff --git a/src/conn-avatars.h b/src/conn-avatars.h
index 0e2899f24..a26506d0c 100644
--- a/src/conn-avatars.h
+++ b/src/conn-avatars.h
@@ -32,6 +32,15 @@ extern TpDBusPropertiesMixinPropImpl *conn_avatars_properties;
void conn_avatars_properties_getter (GObject *object, GQuark interface,
GQuark name, GValue *value, gpointer getter_data);
+void gabble_connection_dup_avatar_requirements (GStrv *supported_mime_types,
+ guint *min_height,
+ guint *min_width,
+ guint *rec_height,
+ guint *rec_width,
+ guint *max_height,
+ guint *max_width,
+ guint *max_bytes);
+
G_END_DECLS
#endif /* __CONN_AVATARS_H__ */
diff --git a/src/conn-client-types.c b/src/conn-client-types.c
index 1a5ff1e8f..2947534c0 100644
--- a/src/conn-client-types.c
+++ b/src/conn-client-types.c
@@ -132,6 +132,44 @@ client_types_get_client_types (TpSvcConnectionInterfaceClientTypes *iface,
g_hash_table_unref (client_types);
}
+static void
+client_types_request_client_types (TpSvcConnectionInterfaceClientTypes *iface,
+ TpHandle contact,
+ DBusGMethodInvocation *context)
+{
+ GabbleConnection *conn = GABBLE_CONNECTION (iface);
+ TpBaseConnection *base = (TpBaseConnection *) conn;
+ TpHandleRepoIface *contact_handles;
+ GError *error = NULL;
+ gchar **types;
+
+ /* Validate contact */
+ contact_handles = tp_base_connection_get_handles (base,
+ TP_HANDLE_TYPE_CONTACT);
+
+ if (!tp_handle_is_valid (contact_handles, contact, &error))
+ {
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+ return;
+ }
+
+ DEBUG ("RequestClientTypes called on the following handle: %u", contact);
+
+ if (!get_client_types_from_handle (conn, contact, &types))
+ {
+ /* FIXME fdo#70140 : we should wait for the disco reply before
+ * returning. */
+ static gchar *empty[] = { NULL };
+ types = g_strdupv (empty);
+ }
+
+ tp_svc_connection_interface_client_types_return_from_request_client_types (
+ context, (const gchar **) types);
+
+ g_strfreev (types);
+}
+
void
conn_client_types_iface_init (gpointer g_iface,
gpointer iface_data)
@@ -141,6 +179,7 @@ conn_client_types_iface_init (gpointer g_iface,
#define IMPLEMENT(x) tp_svc_connection_interface_client_types_implement_##x \
(klass, client_types_##x)
IMPLEMENT (get_client_types);
+ IMPLEMENT (request_client_types);
#undef IMPLEMENT
}
diff --git a/src/conn-presence.c b/src/conn-presence.c
index e06062f56..7798b6142 100644
--- a/src/conn-presence.c
+++ b/src/conn-presence.c
@@ -1917,7 +1917,7 @@ status_available_cb (GObject *obj, guint status)
}
}
-GabblePresenceId
+TpConnectionPresenceType
conn_presence_get_type (GabblePresence *presence)
{
return gabble_statuses[presence->status].presence_type;
diff --git a/src/conn-presence.h b/src/conn-presence.h
index 761a30799..6756f6923 100644
--- a/src/conn-presence.h
+++ b/src/conn-presence.h
@@ -60,7 +60,7 @@ void conn_decloak_iface_init (gpointer g_iface, gpointer iface_data);
void conn_decloak_emit_requested (GabbleConnection *conn,
TpHandle contact, const gchar *reason, gboolean decloaked);
-GabblePresenceId conn_presence_get_type (GabblePresence *presence);
+TpConnectionPresenceType conn_presence_get_type (GabblePresence *presence);
const TpPresenceStatusSpec *conn_presence_statuses (void);
diff --git a/src/connection.c b/src/connection.c
index 4bc10fc40..4f1078b85 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -57,7 +57,6 @@
#include "debug.h"
#include "disco.h"
#include "im-factory.h"
-#include "legacy-caps.h"
#include "muc-factory.h"
#include "namespaces.h"
#include "presence-cache.h"
@@ -76,7 +75,6 @@
#include "conn-addressing.h"
#ifdef ENABLE_VOIP
-#include "media-channel.h"
#include "media-factory.h"
#endif
@@ -84,10 +82,7 @@ static guint disco_reply_timeout = 5;
#define DISCONNECT_TIMEOUT 5
-static void capabilities_service_iface_init (gpointer, gpointer);
static void gabble_conn_contact_caps_iface_init (gpointer, gpointer);
-static void conn_capabilities_fill_contact_attributes (GObject *obj,
- const GArray *contacts, GHashTable *attributes_hash);
static void conn_contact_capabilities_fill_contact_attributes (GObject *obj,
const GArray *contacts, GHashTable *attributes_hash);
static void gabble_plugin_connection_iface_init (
@@ -107,8 +102,6 @@ G_DEFINE_TYPE_WITH_CODE(GabbleConnection,
conn_avatars_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_INFO,
conn_contact_info_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CAPABILITIES,
- capabilities_service_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
tp_dbus_properties_mixin_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS,
@@ -140,7 +133,7 @@ G_DEFINE_TYPE_WITH_CODE(GabbleConnection,
conn_client_types_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_POWER_SAVING,
conn_power_saving_iface_init);
- G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_CONNECTION_INTERFACE_ADDRESSING,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_ADDRESSING,
conn_addressing_iface_init);
G_IMPLEMENT_INTERFACE (GABBLE_TYPE_PLUGIN_CONNECTION,
gabble_plugin_connection_iface_init);
@@ -251,11 +244,8 @@ struct _GabbleConnectionPrivate
/* subscriptions on behalf of the Connection, like PEP "+notify"
* namespaces (this one is add-only) */
GabbleCapabilitySet *notify_caps;
- /* caps provided by Capabilities.AdvertiseCapabilities (tp-spec 0.16) */
- GabbleCapabilitySet *legacy_caps;
/* additional caps that we advertise until the first call to
- * AdvertiseCapabilities or UpdateCapabilities, for vague historical
- * reasons */
+ * UpdateCapabilities, for vague historical reasons */
GabbleCapabilitySet *bonus_caps;
/* sidecar caps set by gabble_connection_update_sidecar_capabilities */
GabbleCapabilitySet *sidecar_caps;
@@ -457,10 +447,6 @@ gabble_connection_constructor (GType type,
conn_addressing_init (self);
tp_contacts_mixin_add_contact_attributes_iface (G_OBJECT (self),
- TP_IFACE_CONNECTION_INTERFACE_CAPABILITIES,
- conn_capabilities_fill_contact_attributes);
-
- tp_contacts_mixin_add_contact_attributes_iface (G_OBJECT (self),
TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
conn_contact_capabilities_fill_contact_attributes);
@@ -480,7 +466,6 @@ gabble_connection_constructor (GType type,
priv->all_caps = gabble_capability_set_new ();
priv->notify_caps = gabble_capability_set_new ();
- priv->legacy_caps = gabble_capability_set_new ();
priv->sidecar_caps = gabble_capability_set_new ();
priv->client_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) gabble_capability_set_free);
@@ -489,7 +474,7 @@ gabble_connection_constructor (GType type,
g_free, (GDestroyNotify) g_ptr_array_unref);
/* Historically, the optional Jingle transports were in our initial
- * presence, but could be removed by AdvertiseCapabilities(). Emulate
+ * presence, but could be removed by UpdateCapabilities(). Emulate
* that here for now. */
priv->bonus_caps = gabble_capability_set_new ();
#ifdef ENABLE_VOIP
@@ -867,7 +852,7 @@ gabble_connection_get_unique_name (TpBaseConnection *self)
*/
void
_gabble_connection_create_handle_repos (TpBaseConnection *conn,
- TpHandleRepoIface *repos[NUM_TP_HANDLE_TYPES])
+ TpHandleRepoIface *repos[TP_NUM_HANDLE_TYPES])
{
repos[TP_HANDLE_TYPE_CONTACT] =
tp_dynamic_handle_repo_new (TP_HANDLE_TYPE_CONTACT,
@@ -888,9 +873,7 @@ static const gchar *implemented_interfaces[] = {
/* always present interfaces */
TP_IFACE_CONNECTION_INTERFACE_POWER_SAVING,
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
- TP_IFACE_CONNECTION_INTERFACE_CAPABILITIES,
TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
- TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_AVATARS,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO,
TP_IFACE_CONNECTION_INTERFACE_CONTACTS,
@@ -902,7 +885,7 @@ static const gchar *implemented_interfaces[] = {
GABBLE_IFACE_CONNECTION_INTERFACE_GABBLE_DECLOAK,
GABBLE_IFACE_CONNECTION_FUTURE,
TP_IFACE_CONNECTION_INTERFACE_CLIENT_TYPES,
- GABBLE_IFACE_CONNECTION_INTERFACE_ADDRESSING,
+ TP_IFACE_CONNECTION_INTERFACE_ADDRESSING,
NULL
};
static const gchar **interfaces_always_present = implemented_interfaces + 3;
@@ -1312,7 +1295,6 @@ gabble_connection_dispose (GObject *object)
g_hash_table_unref (priv->client_caps);
gabble_capability_set_free (priv->all_caps);
gabble_capability_set_free (priv->notify_caps);
- gabble_capability_set_free (priv->legacy_caps);
gabble_capability_set_free (priv->sidecar_caps);
gabble_capability_set_free (priv->bonus_caps);
@@ -1367,6 +1349,7 @@ gabble_connection_finalize (GObject *object)
tp_contacts_mixin_finalize (G_OBJECT(self));
+ conn_aliasing_finalize (self);
conn_presence_finalize (self);
conn_contact_info_finalize (self);
@@ -2501,7 +2484,6 @@ gabble_connection_refresh_capabilities (GabbleConnection *self,
gabble_capability_set_update (self->priv->all_caps,
gabble_capabilities_get_fixed_caps ());
gabble_capability_set_update (self->priv->all_caps, self->priv->notify_caps);
- gabble_capability_set_update (self->priv->all_caps, self->priv->legacy_caps);
gabble_capability_set_update (self->priv->all_caps, self->priv->sidecar_caps);
gabble_capability_set_update (self->priv->all_caps, self->priv->bonus_caps);
@@ -3132,67 +3114,12 @@ _emit_capabilities_changed (GabbleConnection *conn,
const GabbleCapabilitySet *old_set,
const GabbleCapabilitySet *new_set)
{
- GPtrArray *caps_arr;
- const CapabilityConversionData *ccd;
GHashTable *hash;
- guint i;
+ GPtrArray *caps_arr;
if (gabble_capability_set_equals (old_set, new_set))
return;
- /* o.f.T.C.Capabilities */
-
- caps_arr = g_ptr_array_new ();
-
- for (ccd = capabilities_conversions; NULL != ccd->iface; ccd++)
- {
- guint old_specific = ccd->c2tf_fn (old_set);
- guint new_specific = ccd->c2tf_fn (new_set);
-
- if (old_specific != 0 || new_specific != 0)
- {
- GValue caps_monster_struct = {0, };
- guint old_generic = old_specific ?
- TP_CONNECTION_CAPABILITY_FLAG_CREATE |
- TP_CONNECTION_CAPABILITY_FLAG_INVITE : 0;
- guint new_generic = new_specific ?
- TP_CONNECTION_CAPABILITY_FLAG_CREATE |
- TP_CONNECTION_CAPABILITY_FLAG_INVITE : 0;
-
- if (0 == (old_specific ^ new_specific))
- continue;
-
- g_value_init (&caps_monster_struct,
- TP_STRUCT_TYPE_CAPABILITY_CHANGE);
- g_value_take_boxed (&caps_monster_struct,
- dbus_g_type_specialized_construct
- (TP_STRUCT_TYPE_CAPABILITY_CHANGE));
-
- dbus_g_type_struct_set (&caps_monster_struct,
- 0, handle,
- 1, ccd->iface,
- 2, old_generic,
- 3, new_generic,
- 4, old_specific,
- 5, new_specific,
- G_MAXUINT);
-
- g_ptr_array_add (caps_arr, g_value_get_boxed (&caps_monster_struct));
- }
- }
-
- if (caps_arr->len)
- tp_svc_connection_interface_capabilities_emit_capabilities_changed (
- conn, caps_arr);
-
-
- for (i = 0; i < caps_arr->len; i++)
- {
- g_boxed_free (TP_STRUCT_TYPE_CAPABILITY_CHANGE,
- g_ptr_array_index (caps_arr, i));
- }
- g_ptr_array_unref (caps_arr);
-
/* o.f.T.C.ContactCapabilities */
caps_arr = gabble_connection_build_contact_caps (conn, handle, new_set);
@@ -3256,125 +3183,6 @@ connection_capabilities_update_cb (GabblePresenceCache *cache,
_emit_capabilities_changed (conn, handle, old_cap_set, new_cap_set);
}
-/**
- * gabble_connection_advertise_capabilities
- *
- * Implements D-Bus method AdvertiseCapabilities
- * on interface org.freedesktop.Telepathy.Connection.Interface.Capabilities
- *
- * @error: Used to return a pointer to a GError detailing any error
- * that occurred, D-Bus will throw the error only if this
- * function returns FALSE.
- *
- * Returns: TRUE if successful, FALSE if an error was thrown.
- */
-static void
-gabble_connection_advertise_capabilities (TpSvcConnectionInterfaceCapabilities *iface,
- const GPtrArray *add,
- const gchar **del,
- DBusGMethodInvocation *context)
-{
- GabbleConnection *self = GABBLE_CONNECTION (iface);
- TpBaseConnection *base = (TpBaseConnection *) self;
- guint i;
- GabbleConnectionPrivate *priv = self->priv;
- const CapabilityConversionData *ccd;
- GPtrArray *ret;
- GabbleCapabilitySet *save_set;
- GabbleCapabilitySet *add_set, *remove_set;
-
- TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
-
- /* Now that someone has told us our *actual* capabilities, we can stop
- * advertising spurious caps in initial presence */
- gabble_capability_set_clear (self->priv->bonus_caps);
-
- add_set = gabble_capability_set_new ();
- remove_set = gabble_capability_set_new ();
-
- for (i = 0; i < add->len; i++)
- {
- GValue iface_flags_pair = {0, };
- gchar *channel_type;
- guint flags;
-
- g_value_init (&iface_flags_pair, TP_STRUCT_TYPE_CAPABILITY_PAIR);
- g_value_set_static_boxed (&iface_flags_pair, g_ptr_array_index (add, i));
-
- dbus_g_type_struct_get (&iface_flags_pair,
- 0, &channel_type,
- 1, &flags,
- G_MAXUINT);
-
- for (ccd = capabilities_conversions; NULL != ccd->iface; ccd++)
- if (g_str_equal (channel_type, ccd->iface))
- ccd->tf2c_fn (flags, add_set);
-
- g_free (channel_type);
- }
-
- for (i = 0; NULL != del[i]; i++)
- {
- for (ccd = capabilities_conversions; NULL != ccd->iface; ccd++)
- if (g_str_equal (del[i], ccd->iface))
- ccd->tf2c_fn (~0, remove_set);
- }
-
- gabble_capability_set_update (priv->legacy_caps, add_set);
- gabble_capability_set_exclude (priv->legacy_caps, remove_set);
-
- if (DEBUGGING)
- {
- gchar *add_str = gabble_capability_set_dump (add_set, " ");
- gchar *remove_str = gabble_capability_set_dump (remove_set, " ");
-
- DEBUG ("caps to add:\n%s", add_str);
- DEBUG ("caps to remove:\n%s", remove_str);
- g_free (add_str);
- g_free (remove_str);
- }
-
- gabble_capability_set_free (add_set);
- gabble_capability_set_free (remove_set);
-
- if (gabble_connection_refresh_capabilities (self, &save_set))
- {
- _emit_capabilities_changed (self,
- tp_base_connection_get_self_handle (base), save_set, priv->all_caps);
- gabble_capability_set_free (save_set);
- }
-
- ret = g_ptr_array_new ();
-
- for (ccd = capabilities_conversions; NULL != ccd->iface; ccd++)
- {
- guint tp_caps = ccd->c2tf_fn (self->priv->all_caps);
-
- if (tp_caps != 0)
- {
- GValue iface_flags_pair = {0, };
-
- g_value_init (&iface_flags_pair, TP_STRUCT_TYPE_CAPABILITY_PAIR);
- g_value_take_boxed (&iface_flags_pair,
- dbus_g_type_specialized_construct (
- TP_STRUCT_TYPE_CAPABILITY_PAIR));
-
- dbus_g_type_struct_set (&iface_flags_pair,
- 0, ccd->iface,
- 1, tp_caps,
- G_MAXUINT);
-
- g_ptr_array_add (ret, g_value_get_boxed (&iface_flags_pair));
- }
- }
-
- tp_svc_connection_interface_capabilities_return_from_advertise_capabilities (
- context, ret);
-
- g_ptr_array_foreach (ret, (GFunc) g_value_array_free, NULL);
- g_ptr_array_unref (ret);
-}
-
static const gchar *
get_form_type (WockyDataForm *form)
{
@@ -3613,126 +3421,6 @@ gabble_connection_update_capabilities (
context);
}
-static const gchar *assumed_caps[] =
-{
- TP_IFACE_CHANNEL_TYPE_TEXT,
- NULL
-};
-
-
-/**
- * gabble_connection_get_handle_capabilities
- *
- * Add capabilities of handle to the given GPtrArray
- */
-static void
-gabble_connection_get_handle_capabilities (GabbleConnection *self,
- TpHandle handle, GPtrArray *arr)
-{
- TpBaseConnection *base = (TpBaseConnection *) self;
- GabblePresence *pres;
- const CapabilityConversionData *ccd;
- guint typeflags;
- const gchar **assumed;
-
- if (0 == handle)
- {
- /* obsolete request for the connection's capabilities, do nothing */
- return;
- }
-
- if (handle == tp_base_connection_get_self_handle (base))
- pres = self->self_presence;
- else
- pres = gabble_presence_cache_get (self->presence_cache, handle);
-
- if (NULL != pres)
- {
- const GabbleCapabilitySet *cap_set = gabble_presence_peek_caps (pres);
-
- for (ccd = capabilities_conversions; NULL != ccd->iface; ccd++)
- {
- typeflags = ccd->c2tf_fn (cap_set);
-
- if (typeflags)
- {
- GValue monster = {0, };
-
- g_value_init (&monster, TP_STRUCT_TYPE_CONTACT_CAPABILITY);
- g_value_take_boxed (&monster,
- dbus_g_type_specialized_construct (
- TP_STRUCT_TYPE_CONTACT_CAPABILITY));
-
- dbus_g_type_struct_set (&monster,
- 0, handle,
- 1, ccd->iface,
- 2, TP_CONNECTION_CAPABILITY_FLAG_CREATE |
- TP_CONNECTION_CAPABILITY_FLAG_INVITE,
- 3, typeflags,
- G_MAXUINT);
-
- g_ptr_array_add (arr, g_value_get_boxed (&monster));
- }
- }
- }
-
- for (assumed = assumed_caps; NULL != *assumed; assumed++)
- {
- GValue monster = {0, };
-
- g_value_init (&monster, TP_STRUCT_TYPE_CONTACT_CAPABILITY);
- g_value_take_boxed (&monster,
- dbus_g_type_specialized_construct (
- TP_STRUCT_TYPE_CONTACT_CAPABILITY));
-
- dbus_g_type_struct_set (&monster,
- 0, handle,
- 1, *assumed,
- 2, TP_CONNECTION_CAPABILITY_FLAG_CREATE |
- TP_CONNECTION_CAPABILITY_FLAG_INVITE,
- 3, 0,
- G_MAXUINT);
-
- g_ptr_array_add (arr, g_value_get_boxed (&monster));
- }
-}
-
-
-static void
-conn_capabilities_fill_contact_attributes (GObject *obj,
- const GArray *contacts, GHashTable *attributes_hash)
-{
- GabbleConnection *self = GABBLE_CONNECTION (obj);
- guint i;
- GPtrArray *array = NULL;
-
- for (i = 0; i < contacts->len; i++)
- {
- TpHandle handle = g_array_index (contacts, TpHandle, i);
-
- if (array == NULL)
- array = g_ptr_array_new ();
-
- gabble_connection_get_handle_capabilities (self, handle, array);
-
- if (array->len > 0)
- {
- GValue *val = tp_g_value_slice_new (
- TP_ARRAY_TYPE_CONTACT_CAPABILITY_LIST);
-
- g_value_take_boxed (val, array);
- tp_contacts_mixin_set_contact_attribute (attributes_hash,
- handle, TP_IFACE_CONNECTION_INTERFACE_CAPABILITIES"/caps",
- val);
-
- array = NULL;
- }
- }
-
- if (array != NULL)
- g_ptr_array_unref (array);
-}
-
static void
conn_contact_capabilities_fill_contact_attributes (GObject *obj,
const GArray *contacts, GHashTable *attributes_hash)
@@ -3755,54 +3443,6 @@ conn_contact_capabilities_fill_contact_attributes (GObject *obj,
}
/**
- * gabble_connection_get_capabilities
- *
- * Implements D-Bus method GetCapabilities
- * on interface org.freedesktop.Telepathy.Connection.Interface.Capabilities
- */
-static void
-gabble_connection_get_capabilities (TpSvcConnectionInterfaceCapabilities *iface,
- const GArray *handles,
- DBusGMethodInvocation *context)
-{
- GabbleConnection *self = GABBLE_CONNECTION (iface);
- TpBaseConnection *base = (TpBaseConnection *) self;
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (base,
- TP_HANDLE_TYPE_CONTACT);
- guint i;
- GPtrArray *ret;
- GError *error = NULL;
-
- TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
-
- if (!tp_handles_are_valid (contact_handles, handles, TRUE, &error))
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- ret = g_ptr_array_new ();
-
- for (i = 0; i < handles->len; i++)
- {
- TpHandle handle = g_array_index (handles, TpHandle, i);
-
- gabble_connection_get_handle_capabilities (self, handle, ret);
- }
-
- tp_svc_connection_interface_capabilities_return_from_get_capabilities (
- context, ret);
-
- for (i = 0; i < ret->len; i++)
- {
- g_value_array_free (g_ptr_array_index (ret, i));
- }
-
- g_ptr_array_unref (ret);
-}
-
-/**
* gabble_connection_get_contact_capabilities
*
* Implements D-Bus method GetContactCapabilities
@@ -3933,19 +3573,6 @@ gabble_connection_send_presence (GabbleConnection *conn,
}
static void
-capabilities_service_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcConnectionInterfaceCapabilitiesClass *klass =
- (TpSvcConnectionInterfaceCapabilitiesClass *) g_iface;
-
-#define IMPLEMENT(x) tp_svc_connection_interface_capabilities_implement_##x (\
- klass, gabble_connection_##x)
- IMPLEMENT(advertise_capabilities);
- IMPLEMENT(get_capabilities);
-#undef IMPLEMENT
-}
-
-static void
gabble_conn_contact_caps_iface_init (gpointer g_iface, gpointer iface_data)
{
TpSvcConnectionInterfaceContactCapabilitiesClass *klass = g_iface;
diff --git a/src/connection.h b/src/connection.h
index c3e9138b0..842f9e58f 100644
--- a/src/connection.h
+++ b/src/connection.h
@@ -26,6 +26,7 @@
#include <dbus/dbus-glib.h>
#include <glib-object.h>
#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
#include <wocky/wocky.h>
@@ -248,6 +249,12 @@ struct _GabbleConnection {
/* ContactInfo.SupportedFields, or NULL to use the generic one */
GPtrArray *contact_info_fields;
+ /* Contacts' aliases from PEP. Private to conn-aliasing.c.
+ * TpHandle => (transfer full) gchar *
+ * We don't distinguish between "not cached" and "known to have
+ * no PEP alias" here. */
+ GHashTable *pep_alias_cache;
+
GabbleConnectionPrivate *priv;
};
@@ -304,7 +311,7 @@ const gchar **gabble_connection_get_guaranteed_interfaces (void);
/* extern only for the benefit of the unit tests */
void _gabble_connection_create_handle_repos (TpBaseConnection *conn,
- TpHandleRepoIface *repos[NUM_TP_HANDLE_TYPES]);
+ TpHandleRepoIface *repos[TP_NUM_HANDLE_TYPES]);
/* For unit tests only */
void gabble_connection_set_disco_reply_timeout (guint timeout);
diff --git a/src/ft-channel.c b/src/ft-channel.c
index fd82405c5..91af4931e 100644
--- a/src/ft-channel.c
+++ b/src/ft-channel.c
@@ -633,7 +633,7 @@ gabble_file_transfer_channel_class_init (
"TpFileTransferState state",
"State of the file transfer in this channel",
0,
- NUM_TP_FILE_TRANSFER_STATES,
+ TP_NUM_FILE_TRANSFER_STATES,
TP_FILE_TRANSFER_STATE_NONE,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
@@ -674,7 +674,7 @@ gabble_file_transfer_channel_class_init (
"TpFileHashType content-hash-type",
"Hash type",
0,
- NUM_TP_FILE_HASH_TYPES,
+ TP_NUM_FILE_HASH_TYPES,
TP_FILE_HASH_TYPE_NONE,
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
diff --git a/src/ft-manager.c b/src/ft-manager.c
index a4266b5a0..cca26d4cb 100644
--- a/src/ft-manager.c
+++ b/src/ft-manager.c
@@ -289,8 +289,6 @@ static void
gabble_ft_manager_channels_created (GabbleFtManager *self, GList *channels)
{
GList *i;
- GHashTable *new_channels = g_hash_table_new_full (g_direct_hash,
- g_direct_equal, NULL, NULL);
for (i = channels; i ; i = i->next)
{
@@ -304,12 +302,9 @@ gabble_ft_manager_channels_created (GabbleFtManager *self, GList *channels)
self->priv->channels = g_list_append (self->priv->channels, chan);
/* The channels can't satisfy a request because this will always be called
when we receive an incoming jingle-share session */
- g_hash_table_insert (new_channels, chan, NULL);
+ tp_channel_manager_emit_new_channel (self,
+ TP_EXPORTABLE_CHANNEL (chan), NULL);
}
-
- tp_channel_manager_emit_new_channels (self, new_channels);
-
- g_hash_table_unref (new_channels);
}
#endif
@@ -526,7 +521,7 @@ gabble_ft_manager_handle_request (TpChannelManager *manager,
}
else
{
- if (content_hash_type >= NUM_TP_FILE_HASH_TYPES)
+ if (content_hash_type >= TP_NUM_FILE_HASH_TYPES)
{
g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
"%u is not a valid ContentHashType", content_hash_type);
diff --git a/src/legacy-caps.c b/src/legacy-caps.c
deleted file mode 100644
index 827fc15ea..000000000
--- a/src/legacy-caps.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * legacy-caps.c - Connection.Interface.Capabilities constants and utilities
- * Copyright (C) 2005 Collabora Ltd.
- * Copyright (C) 2005 Nokia Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include "legacy-caps.h"
-
-#include <telepathy-glib/telepathy-glib-dbus.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_PRESENCE
-#include "debug.h"
-#ifdef ENABLE_VOIP
-#include "media-factory.h"
-#endif
-
-const CapabilityConversionData capabilities_conversions[] =
-{
-#ifdef ENABLE_VOIP
- { TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
- _gabble_media_factory_typeflags_to_caps,
- _gabble_media_factory_caps_to_typeflags },
-#endif
- { NULL, NULL, NULL}
-};
diff --git a/src/legacy-caps.h b/src/legacy-caps.h
deleted file mode 100644
index e2de46c37..000000000
--- a/src/legacy-caps.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * legacy-caps.h - Connection.Interface.Capabilities constants and utilities
- * Copyright (C) 2005 Collabora Ltd.
- * Copyright (C) 2005 Nokia Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __GABBLE_LEGACY_CAPS__H__
-#define __GABBLE_LEGACY_CAPS__H__
-
-#include <glib-object.h>
-
-#include "gabble/capabilities.h"
-
-typedef void (*TypeFlagsToCapsFunc) (guint typeflags, GabbleCapabilitySet *caps);
-typedef guint (*CapsToTypeFlagsFunc) (const GabbleCapabilitySet *caps);
-
-typedef struct _CapabilityConversionData CapabilityConversionData;
-
-struct _CapabilityConversionData
-{
- const gchar *iface;
- TypeFlagsToCapsFunc tf2c_fn;
- CapsToTypeFlagsFunc c2tf_fn;
-};
-
-extern const CapabilityConversionData capabilities_conversions[];
-
-#endif
diff --git a/src/media-channel-hold.c b/src/media-channel-hold.c
deleted file mode 100644
index b4dc26c5a..000000000
--- a/src/media-channel-hold.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * media-channel-hold.c - Hold and CallState interface implementations
- * Copyright © 2006–2009 Collabora Ltd.
- * Copyright © 2006–2009 Nokia Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#include "media-channel.h"
-#include "media-channel-internal.h"
-
-#include <telepathy-glib/telepathy-glib.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#include "debug.h"
-#include "util.h"
-
-/*
- * Implementation of Channel.Interface.Hold, which deals with placing the peer
- * on and off hold.
- */
-
-static void
-stream_hold_state_changed (GabbleMediaStream *stream G_GNUC_UNUSED,
- GParamSpec *unused G_GNUC_UNUSED,
- gpointer data)
-{
- GabbleMediaChannel *self = data;
- GabbleMediaChannelPrivate *priv = self->priv;
- gboolean all_held = TRUE, any_held = FALSE;
- guint i;
-
- for (i = 0; i < priv->streams->len; i++)
- {
- gboolean its_hold;
-
- g_object_get (g_ptr_array_index (priv->streams, i),
- "local-hold", &its_hold,
- NULL);
-
- DEBUG ("Stream at index %u has local-hold=%u", i, (guint) its_hold);
-
- all_held = all_held && its_hold;
- any_held = any_held || its_hold;
- }
-
- DEBUG ("all_held=%u, any_held=%u", (guint) all_held, (guint) any_held);
-
- if (all_held && !any_held)
- {
- /* There are no streams, move to the desired state immediately */
- switch (priv->hold_state)
- {
- case TP_LOCAL_HOLD_STATE_PENDING_HOLD:
- DEBUG ("no streams, moving from pending hold to held");
- priv->hold_state = TP_LOCAL_HOLD_STATE_HELD;
-
- /* No need to touch the session: send_held (TRUE) is called as soon
- * as Hold is requested.
- */
- break;
-
- case TP_LOCAL_HOLD_STATE_PENDING_UNHOLD:
- DEBUG ("no streams, moving from pending unhold to unheld");
- priv->hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
-
- if (priv->session != NULL)
- wocky_jingle_session_set_local_hold (priv->session, FALSE);
-
- break;
-
- default:
- /* nothing to change */
- return;
- }
- }
- else if (all_held)
- {
- /* Move to state HELD */
- switch (priv->hold_state)
- {
- case TP_LOCAL_HOLD_STATE_HELD:
- /* nothing changed */
- return;
-
- case TP_LOCAL_HOLD_STATE_PENDING_UNHOLD:
- /* This can happen if the user asks us to hold, then changes their
- * mind. We make no particular guarantees about stream states when
- * in PENDING_UNHOLD state, so keep claiming to be in that state */
- return;
-
- case TP_LOCAL_HOLD_STATE_PENDING_HOLD:
- /* We wanted to hold, and indeed we have. Yay! Keep whatever
- * reason code we used for going to PENDING_HOLD */
- priv->hold_state = TP_LOCAL_HOLD_STATE_HELD;
- break;
-
- case TP_LOCAL_HOLD_STATE_UNHELD:
- /* We were previously UNHELD. So why have we gone on hold now? */
- DEBUG ("Unexpectedly entered HELD state!");
- priv->hold_state = TP_LOCAL_HOLD_STATE_HELD;
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
- break;
- }
- }
- else if (any_held)
- {
- switch (priv->hold_state)
- {
- case TP_LOCAL_HOLD_STATE_UNHELD:
- /* The streaming client has spontaneously changed its stream
- * state. Why? We just don't know */
- DEBUG ("Unexpectedly entered PENDING_UNHOLD state!");
- priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_UNHOLD;
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
- break;
-
- case TP_LOCAL_HOLD_STATE_HELD:
- /* Likewise */
- DEBUG ("Unexpectedly entered PENDING_HOLD state!");
- priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_HOLD;
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
- break;
-
- default:
- /* nothing particularly interesting - we're trying to change hold
- * state already, so nothing to signal */
- return;
- }
- }
- else
- {
- /* Move to state UNHELD */
- switch (priv->hold_state)
- {
- case TP_LOCAL_HOLD_STATE_UNHELD:
- /* nothing changed */
- return;
-
- case TP_LOCAL_HOLD_STATE_PENDING_HOLD:
- /* This can happen if the user asks us to unhold, then changes their
- * mind. We make no particular guarantees about stream states when
- * in PENDING_HOLD state, so keep claiming to be in that state */
- return;
-
- case TP_LOCAL_HOLD_STATE_PENDING_UNHOLD:
- /* We wanted to hold, and indeed we have. Yay! Keep whatever
- * reason code we used for going to PENDING_UNHOLD */
- priv->hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
- break;
-
- case TP_LOCAL_HOLD_STATE_HELD:
- /* We were previously HELD. So why have we gone off hold now? */
- DEBUG ("Unexpectedly entered UNHELD state!");
- priv->hold_state = TP_LOCAL_HOLD_STATE_UNHELD;
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_NONE;
- break;
- }
-
- /* Tell the peer what's happened. */
- if (priv->session != NULL)
- wocky_jingle_session_set_local_hold (priv->session, FALSE);
- }
-
- tp_svc_channel_interface_hold_emit_hold_state_changed (self,
- priv->hold_state, priv->hold_state_reason);
-}
-
-
-static void
-stream_unhold_failed (GabbleMediaStream *stream,
- gpointer data)
-{
- GabbleMediaChannel *self = data;
- GabbleMediaChannelPrivate *priv = self->priv;
- guint i;
-
- DEBUG ("%p: %p", self, stream);
-
- /* Unholding failed - let's roll back to Hold state */
- priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_HOLD;
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_RESOURCE_NOT_AVAILABLE;
- tp_svc_channel_interface_hold_emit_hold_state_changed (self,
- priv->hold_state, priv->hold_state_reason);
-
- /* The stream's state may have changed from unheld to held, so re-poll.
- * It's possible that all streams are now held, in which case we can stop. */
- stream_hold_state_changed (stream, NULL, self);
-
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD)
- return;
-
- /* There should be no need to notify the peer, who already thinks they're
- * on hold, so just tell the streaming client what to do. */
-
- for (i = 0; i < priv->streams->len; i++)
- {
- gabble_media_stream_hold (g_ptr_array_index (priv->streams, i),
- TRUE);
- }
-}
-
-
-void
-gabble_media_channel_hold_stream_closed (GabbleMediaChannel *chan,
- GabbleMediaStream *stream)
-{
- /* A stream closing might cause the "total" hold state to change:
- * if there's one held and one unheld, and the unheld one closes,
- * then our state changes from indeterminate to held. */
- stream_hold_state_changed (stream, NULL, chan);
-}
-
-
-/* Implements RequestHold on Telepathy.Channel.Interface.Hold */
-static void
-gabble_media_channel_request_hold (TpSvcChannelInterfaceHold *iface,
- gboolean hold,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
- GabbleMediaChannelPrivate *priv = self->priv;
- WockyJingleSession *session = priv->session;
- guint i;
- TpLocalHoldState old_state = priv->hold_state;
-
- DEBUG ("%p: RequestHold(%u)", self, !!hold);
-
- if (hold)
- {
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD)
- {
- DEBUG ("No-op");
- tp_svc_channel_interface_hold_return_from_request_hold (context);
- return;
- }
-
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD && session != NULL)
- wocky_jingle_session_set_local_hold (session, TRUE);
-
- priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_HOLD;
- }
- else
- {
- if (priv->hold_state == TP_LOCAL_HOLD_STATE_UNHELD)
- {
- DEBUG ("No-op");
- tp_svc_channel_interface_hold_return_from_request_hold (context);
- return;
- }
-
- priv->hold_state = TP_LOCAL_HOLD_STATE_PENDING_UNHOLD;
- }
-
- if (old_state != priv->hold_state ||
- priv->hold_state_reason != TP_LOCAL_HOLD_STATE_REASON_REQUESTED)
- {
- tp_svc_channel_interface_hold_emit_hold_state_changed (self,
- priv->hold_state, TP_LOCAL_HOLD_STATE_REASON_REQUESTED);
- priv->hold_state_reason = TP_LOCAL_HOLD_STATE_REASON_REQUESTED;
- }
-
- if (priv->streams->len == 0)
- {
- /* No streams yet! We can go straight to the desired state. */
- stream_hold_state_changed (NULL, NULL, self);
- }
- else
- {
- /* Tell streaming client to release or reacquire resources */
-
- for (i = 0; i < priv->streams->len; i++)
- {
- gabble_media_stream_hold (g_ptr_array_index (priv->streams, i), hold);
- }
- }
-
- tp_svc_channel_interface_hold_return_from_request_hold (context);
-}
-
-
-/* Implements GetHoldState on Telepathy.Channel.Interface.Hold */
-static void
-gabble_media_channel_get_hold_state (TpSvcChannelInterfaceHold *iface,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = (GabbleMediaChannel *) iface;
- GabbleMediaChannelPrivate *priv = self->priv;
-
- tp_svc_channel_interface_hold_return_from_get_hold_state (context,
- priv->hold_state, priv->hold_state_reason);
-}
-
-
-void
-gabble_media_channel_hold_iface_init (gpointer g_iface,
- gpointer iface_data G_GNUC_UNUSED)
-{
- TpSvcChannelInterfaceHoldClass *klass = g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_interface_hold_implement_##x (\
- klass, gabble_media_channel_##x)
- IMPLEMENT(get_hold_state);
- IMPLEMENT(request_hold);
-#undef IMPLEMENT
-}
-
-
-/*
- * Implementation of Channel.Interface.CallState, which indicates call states
- * from the peer (such as being put on or off hold, or that the peer's client
- * is ringing.
- */
-
-static void
-remote_state_changed_cb (WockyJingleSession *session,
- GabbleMediaChannel *self)
-{
- GabbleMediaChannelPrivate *priv = self->priv;
- TpChannelCallStateFlags call_state = 0;
-
- if (wocky_jingle_session_get_remote_hold (session))
- call_state |= TP_CHANNEL_CALL_STATE_HELD;
-
- if (wocky_jingle_session_get_remote_ringing (session))
- call_state |= TP_CHANNEL_CALL_STATE_RINGING;
-
- DEBUG ("Call state changed to %u (current state %u)", call_state,
- priv->call_state);
-
- if (call_state == priv->call_state)
- return;
-
- priv->call_state = call_state;
-
- tp_svc_channel_interface_call_state_emit_call_state_changed (self,
- priv->peer, call_state);
-}
-
-
-/* Implements GetCallStates on Channel.Interface.CallState */
-static void
-gabble_media_channel_get_call_states (TpSvcChannelInterfaceCallState *iface,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = (GabbleMediaChannel *) iface;
- GabbleMediaChannelPrivate *priv = self->priv;
- GHashTable *states = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- if (priv->peer != 0)
- {
- g_hash_table_insert (states, GUINT_TO_POINTER (priv->peer),
- GUINT_TO_POINTER (priv->call_state));
- }
-
- tp_svc_channel_interface_call_state_return_from_get_call_states (context,
- states);
-
- g_hash_table_unref (states);
-}
-
-
-void
-gabble_media_channel_call_state_iface_init (gpointer g_iface,
- gpointer iface_data G_GNUC_UNUSED)
-{
- TpSvcChannelInterfaceCallStateClass *klass = g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_interface_call_state_implement_##x (\
- klass, gabble_media_channel_##x)
- IMPLEMENT(get_call_states);
-#undef IMPLEMENT
-}
-
-
-/* Called by construct_stream to allow the Hold code to hook itself up to a new
- * stream.
- */
-void
-gabble_media_channel_hold_new_stream (GabbleMediaChannel *chan,
- GabbleMediaStream *stream,
- WockyJingleMediaRtp *content)
-{
- GObject *chan_o = (GObject *) chan;
-
- gabble_signal_connect_weak (stream, "unhold-failed",
- (GCallback) stream_unhold_failed, chan_o);
- gabble_signal_connect_weak (stream, "notify::local-hold",
- (GCallback) stream_hold_state_changed, chan_o);
-
- /* A stream being added might cause the "total" hold state to change */
- stream_hold_state_changed (stream, NULL, chan);
-}
-
-/* Called by _latch_to_session to allow the CallState code to hook itself up to
- * a new session.
- */
-void
-gabble_media_channel_hold_latch_to_session (GabbleMediaChannel *chan)
-{
- g_assert (chan->priv->session != NULL);
-
- /* Watch the active/ringing/held state of the session so we can keep the call
- * state up to date.
- */
- gabble_signal_connect_weak (chan->priv->session, "remote-state-changed",
- (GCallback) remote_state_changed_cb, (GObject *) chan);
-}
diff --git a/src/media-channel-internal.h b/src/media-channel-internal.h
deleted file mode 100644
index 4459df726..000000000
--- a/src/media-channel-internal.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * media-channel-internal.h - implementation details shared between
- * MediaChannel source files
- * Copyright © 2006–2009 Collabora Ltd.
- * Copyright © 2006–2009 Nokia Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __GABBLE_MEDIA_CHANNEL_INTERNAL_H__
-#define __GABBLE_MEDIA_CHANNEL_INTERNAL_H__
-
-#include "media-channel.h"
-
-#include <glib.h>
-
-#include <telepathy-glib/telepathy-glib.h>
-#include <wocky/wocky.h>
-
-#include "media-stream.h"
-
-G_BEGIN_DECLS
-
-struct _GabbleMediaChannelPrivate
-{
- GabbleConnection *conn;
- gchar *object_path;
- TpHandle creator;
- TpHandle initial_peer;
- TpHandle peer;
- gboolean peer_in_rp;
-
- WockyJingleSession *session;
-
- /* array of referenced GabbleMediaStream*. Always non-NULL. */
- GPtrArray *streams;
- /* list of PendingStreamRequest* in no particular order */
- GList *pending_stream_requests;
-
- /* list of StreamCreationData* in no particular order */
- GList *stream_creation_datas;
-
- guint next_stream_id;
-
- TpLocalHoldState hold_state;
- TpLocalHoldStateReason hold_state_reason;
-
- TpChannelCallStateFlags call_state;
-
- GPtrArray *delayed_request_streams;
-
- TpDTMFPlayer *dtmf_player;
- gchar *deferred_tones;
-
- gboolean initial_audio;
- gboolean initial_video;
- gboolean immutable_streams;
- gboolean ready;
- gboolean closed;
- gboolean dispose_has_run;
- gboolean tried_decloaking;
- gboolean have_some_audio;
-};
-
-void gabble_media_channel_hold_latch_to_session (GabbleMediaChannel *chan);
-
-void gabble_media_channel_hold_new_stream (GabbleMediaChannel *chan,
- GabbleMediaStream *stream,
- WockyJingleMediaRtp *content);
-void gabble_media_channel_hold_stream_closed (GabbleMediaChannel *chan,
- GabbleMediaStream *stream);
-
-void gabble_media_channel_hold_iface_init (gpointer g_iface,
- gpointer iface_data G_GNUC_UNUSED);
-
-void gabble_media_channel_call_state_iface_init (gpointer g_iface,
- gpointer iface_data G_GNUC_UNUSED);
-
-G_END_DECLS
-
-#endif /* #ifndef __GABBLE_MEDIA_CHANNEL_INTERNAL_H__ */
diff --git a/src/media-channel.c b/src/media-channel.c
deleted file mode 100644
index c4ab89e37..000000000
--- a/src/media-channel.c
+++ /dev/null
@@ -1,3184 +0,0 @@
-/*
- * gabble-media-channel.c - Source for GabbleMediaChannel
- * Copyright (C) 2006 Collabora Ltd.
- * Copyright (C) 2006 Nokia Corporation
- * @author Ole Andre Vadla Ravnaas <ole.andre.ravnaas@collabora.co.uk>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include "media-channel.h"
-#include "media-channel-internal.h"
-
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
-#include <telepathy-glib/telepathy-glib.h>
-#include <telepathy-glib/telepathy-glib-dbus.h>
-
-#include <wocky/wocky.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#include "connection.h"
-#include "debug.h"
-#include "jingle-tp-util.h"
-#include "media-factory.h"
-#include "media-stream.h"
-#include "namespaces.h"
-#include "presence-cache.h"
-#include "presence.h"
-#include "util.h"
-
-#define MAX_STREAMS 99
-
-static void channel_iface_init (gpointer, gpointer);
-static void dtmf_iface_init (gpointer, gpointer);
-static void media_signalling_iface_init (gpointer, gpointer);
-static void streamed_media_iface_init (gpointer, gpointer);
-static void session_handler_iface_init (gpointer, gpointer);
-
-G_DEFINE_TYPE_WITH_CODE (GabbleMediaChannel, gabble_media_channel,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL,
- channel_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_CALL_STATE,
- gabble_media_channel_call_state_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_DTMF,
- dtmf_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
- tp_group_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_HOLD,
- gabble_media_channel_hold_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_MEDIA_SIGNALLING,
- media_signalling_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_STREAMED_MEDIA,
- streamed_media_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_PROPERTIES_INTERFACE,
- tp_properties_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_MEDIA_SESSION_HANDLER,
- session_handler_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL));
-
-static const gchar *gabble_media_channel_interfaces[] = {
- TP_IFACE_CHANNEL_INTERFACE_CALL_STATE,
- TP_IFACE_CHANNEL_INTERFACE_DTMF,
- TP_IFACE_CHANNEL_INTERFACE_GROUP,
- TP_IFACE_CHANNEL_INTERFACE_HOLD,
- TP_IFACE_CHANNEL_INTERFACE_MEDIA_SIGNALLING,
- TP_IFACE_PROPERTIES_INTERFACE,
- TP_IFACE_MEDIA_SESSION_HANDLER,
- NULL
-};
-
-/* properties */
-enum
-{
- PROP_OBJECT_PATH = 1,
- PROP_CHANNEL_TYPE,
- PROP_HANDLE_TYPE,
- PROP_HANDLE,
- PROP_TARGET_ID,
- PROP_INITIAL_PEER,
- PROP_PEER_IN_RP,
- PROP_PEER,
- PROP_REQUESTED,
- PROP_CONNECTION,
- PROP_CREATOR,
- PROP_CREATOR_ID,
- PROP_INTERFACES,
- PROP_CHANNEL_DESTROYED,
- PROP_CHANNEL_PROPERTIES,
- PROP_INITIAL_AUDIO,
- PROP_INITIAL_VIDEO,
- PROP_IMMUTABLE_STREAMS,
- PROP_CURRENTLY_SENDING_TONES,
- PROP_INITIAL_TONES,
- PROP_DEFERRED_TONES,
- /* TP properties (see also below) */
- PROP_NAT_TRAVERSAL,
- PROP_STUN_SERVER,
- PROP_STUN_PORT,
- PROP_GTALK_P2P_RELAY_TOKEN,
- PROP_SESSION,
- LAST_PROPERTY
-};
-
-/* TP properties */
-enum
-{
- CHAN_PROP_NAT_TRAVERSAL = 0,
- CHAN_PROP_STUN_SERVER,
- CHAN_PROP_STUN_PORT,
- CHAN_PROP_GTALK_P2P_RELAY_TOKEN,
- NUM_CHAN_PROPS,
- INVALID_CHAN_PROP
-};
-
-const TpPropertySignature channel_property_signatures[NUM_CHAN_PROPS] = {
- { "nat-traversal", G_TYPE_STRING },
- { "stun-server", G_TYPE_STRING },
- { "stun-port", G_TYPE_UINT },
- { "gtalk-p2p-relay-token", G_TYPE_STRING }
-};
-
-typedef struct {
- GabbleMediaChannel *self;
- WockyJingleContent *content;
- gulong removed_id;
- gchar *name;
- const gchar *nat_traversal;
- gboolean initial;
-} StreamCreationData;
-
-struct _delayed_request_streams_ctx {
- GabbleMediaChannel *chan;
- gulong caps_disco_id;
- gulong unsure_period_ended_id;
- guint contact_handle;
- GArray *types;
- GFunc succeeded_cb;
- GFunc failed_cb;
- gpointer context;
-};
-
-static void destroy_request (struct _delayed_request_streams_ctx *ctx,
- gpointer user_data);
-
-static void
-tones_deferred_cb (GabbleMediaChannel *self,
- const gchar *tones,
- TpDTMFPlayer *dtmf_player)
-{
- DEBUG ("waiting for user to continue sending '%s'", tones);
-
- g_free (self->priv->deferred_tones);
- self->priv->deferred_tones = g_strdup (tones);
- tp_svc_channel_interface_dtmf_emit_tones_deferred (self, tones);
-}
-
-static void
-gabble_media_channel_init (GabbleMediaChannel *self)
-{
- GabbleMediaChannelPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- GABBLE_TYPE_MEDIA_CHANNEL, GabbleMediaChannelPrivate);
-
- self->priv = priv;
-
- priv->next_stream_id = 1;
- priv->delayed_request_streams = g_ptr_array_sized_new (1);
- priv->streams = g_ptr_array_sized_new (1);
-
- /* initialize properties mixin */
- tp_properties_mixin_init (G_OBJECT (self), G_STRUCT_OFFSET (
- GabbleMediaChannel, properties));
-
- priv->dtmf_player = tp_dtmf_player_new ();
-
- tp_g_signal_connect_object (priv->dtmf_player, "finished",
- G_CALLBACK (tp_svc_channel_interface_dtmf_emit_stopped_tones), self,
- G_CONNECT_SWAPPED);
-
- tp_g_signal_connect_object (priv->dtmf_player, "tones-deferred",
- G_CALLBACK (tones_deferred_cb), self,
- G_CONNECT_SWAPPED);
-}
-
-static void session_state_changed_cb (WockyJingleSession *session,
- GParamSpec *arg1, GabbleMediaChannel *channel);
-static void session_terminated_cb (WockyJingleSession *session,
- gboolean local_terminator, WockyJingleReason reason, const gchar *text,
- gpointer user_data);
-static void session_new_content_cb (WockyJingleSession *session,
- WockyJingleContent *c, gpointer user_data);
-static void create_stream_from_content (GabbleMediaChannel *chan,
- WockyJingleContent *c, gboolean initial);
-static gboolean contact_is_media_capable (GabbleMediaChannel *chan, TpHandle peer,
- gboolean *wait, GError **error);
-static void stream_creation_data_cancel (gpointer p, gpointer unused);
-static void session_content_rejected_cb (WockyJingleSession *session,
- WockyJingleContent *c, WockyJingleReason reason, const gchar *message,
- gpointer user_data);
-
-static void
-create_initial_streams (GabbleMediaChannel *chan)
-{
- GabbleMediaChannelPrivate *priv = chan->priv;
- GList *contents, *li;
-
- contents = wocky_jingle_session_get_contents (priv->session);
-
- for (li = contents; li; li = li->next)
- {
- WockyJingleContent *c = li->data;
-
- /* I'm so sorry. */
- if (G_OBJECT_TYPE (c) == WOCKY_TYPE_JINGLE_MEDIA_RTP)
- {
- guint media_type;
-
- g_object_get (c, "media-type", &media_type, NULL);
-
- switch (media_type)
- {
- case WOCKY_JINGLE_MEDIA_TYPE_AUDIO:
- priv->initial_audio = TRUE;
- break;
- case WOCKY_JINGLE_MEDIA_TYPE_VIDEO:
- priv->initial_video = TRUE;
- break;
- default:
- /* smell? */
- DEBUG ("unknown rtp media type %u", media_type);
- }
- }
- else
- {
- g_assert_not_reached ();
- }
-
- create_stream_from_content (chan, c, TRUE);
- }
-
- DEBUG ("initial_audio: %s, initial_video: %s",
- priv->initial_audio ? "true" : "false",
- priv->initial_video ? "true" : "false");
-
- g_list_free (contents);
-}
-
-static void
-_latch_to_session (GabbleMediaChannel *chan)
-{
- GabbleMediaChannelPrivate *priv = chan->priv;
-
- g_assert (priv->session != NULL);
-
- DEBUG ("%p: Latching onto session %p", chan, priv->session);
-
- g_signal_connect (priv->session, "notify::state",
- (GCallback) session_state_changed_cb, chan);
-
- g_signal_connect (priv->session, "new-content",
- (GCallback) session_new_content_cb, chan);
-
- g_signal_connect (priv->session, "terminated",
- (GCallback) session_terminated_cb, chan);
-
- g_signal_connect (priv->session, "content-rejected",
- (GCallback) session_content_rejected_cb, chan);
-
- gabble_media_channel_hold_latch_to_session (chan);
-
- g_assert (priv->streams->len == 0);
-
- tp_svc_channel_interface_media_signalling_emit_new_session_handler (
- G_OBJECT (chan), priv->object_path, "rtp");
-}
-
-static void
-create_session (GabbleMediaChannel *chan,
- const gchar *jid,
- WockyJingleDialect dialect)
-{
- GabbleMediaChannelPrivate *priv = chan->priv;
- gboolean local_hold = (priv->hold_state != TP_LOCAL_HOLD_STATE_UNHELD);
- WockyJingleFactory *jf;
-
- g_assert (priv->session == NULL);
-
- DEBUG ("%p: Creating new outgoing session", chan);
-
- jf = gabble_jingle_mint_get_factory (priv->conn->jingle_mint);
- g_return_if_fail (jf != NULL);
- priv->session = g_object_ref (
- wocky_jingle_factory_create_session (jf, jid, dialect, local_hold));
-
- _latch_to_session (chan);
-}
-
-static GObject *
-gabble_media_channel_constructor (GType type, guint n_props,
- GObjectConstructParam *props)
-{
- GObject *obj;
- GabbleMediaChannelPrivate *priv;
- TpBaseConnection *conn;
- TpDBusDaemon *bus;
- TpIntset *set;
- TpHandleRepoIface *contact_handles;
- WockyJingleInfo *ji;
- const gchar *relay_token;
- GList *stun_servers;
-
- obj = G_OBJECT_CLASS (gabble_media_channel_parent_class)->
- constructor (type, n_props, props);
-
- priv = GABBLE_MEDIA_CHANNEL (obj)->priv;
- conn = (TpBaseConnection *) priv->conn;
- contact_handles = tp_base_connection_get_handles (conn,
- TP_HANDLE_TYPE_CONTACT);
-
- /* register object on the bus */
- bus = tp_base_connection_get_dbus_daemon (conn);
- tp_dbus_daemon_register_object (bus, priv->object_path, obj);
-
- tp_group_mixin_init (obj, G_STRUCT_OFFSET (GabbleMediaChannel, group),
- contact_handles, tp_base_connection_get_self_handle (conn));
-
- if (priv->session != NULL)
- {
- priv->peer = ensure_handle_from_contact (priv->conn,
- wocky_jingle_session_get_peer_contact (priv->session));
- g_return_val_if_fail (priv->peer != 0, NULL);
- priv->creator = priv->peer;
- }
- else
- {
- priv->creator = tp_base_connection_get_self_handle (conn);
- }
-
- /* automatically add creator to channel, but also ref them again (because
- * priv->creator is the InitiatorHandle) */
- g_assert (priv->creator != 0);
-
- set = tp_intset_new_containing (priv->creator);
- tp_group_mixin_change_members (obj, "", set, NULL, NULL, NULL, 0,
- TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
- tp_intset_destroy (set);
-
- /* We implement the 0.17.6 properties correctly, and can include a message
- * when ending a call.
- */
- tp_group_mixin_change_flags (obj,
- TP_CHANNEL_GROUP_FLAG_PROPERTIES |
- TP_CHANNEL_GROUP_FLAG_MESSAGE_REMOVE |
- TP_CHANNEL_GROUP_FLAG_MESSAGE_REJECT |
- TP_CHANNEL_GROUP_FLAG_MESSAGE_RESCIND,
- 0);
-
- /* Set up Google relay related properties */
- ji = gabble_jingle_mint_get_info (priv->conn->jingle_mint);
- stun_servers = wocky_jingle_info_get_stun_servers (ji);
- if (stun_servers != NULL)
- {
- WockyStunServer *stun_server = stun_servers->data;
-
- g_object_set (obj,
- "stun-server", stun_server->address,
- "stun-port", (guint) stun_server->port,
- NULL);
-
- g_list_free (stun_servers);
- }
-
- relay_token = wocky_jingle_info_get_google_relay_token (ji);
-
- if (relay_token != NULL)
- {
- g_object_set (obj,
- "gtalk-p2p-relay-token", relay_token,
- NULL);
- }
-
- if (priv->session != NULL)
- {
- /* This is an incoming call; make us local pending and don't set any
- * group flags (all we can do is add or remove ourselves, which is always
- * valid per the spec)
- */
- set = tp_intset_new_containing (tp_base_connection_get_self_handle (conn));
- tp_group_mixin_change_members (obj, "", NULL, NULL, set, NULL,
- priv->peer, TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
- tp_intset_destroy (set);
-
- /* Set up signal callbacks, emit session handler, initialize streams,
- * figure out InitialAudio and InitialVideo
- */
- _latch_to_session (GABBLE_MEDIA_CHANNEL (obj));
- create_initial_streams (GABBLE_MEDIA_CHANNEL (obj));
- }
- else
- {
- /* This is an outgoing call. */
-
- if (priv->initial_peer != 0)
- {
- if (priv->peer_in_rp)
- {
- /* This channel was created with RequestChannel(SM, Contact, h)
- * so the peer should start out in remote pending.
- */
- set = tp_intset_new_containing (priv->initial_peer);
- tp_group_mixin_change_members (obj, "", NULL, NULL, NULL, set,
- tp_base_connection_get_self_handle (conn),
- TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
- tp_intset_destroy (set);
- }
-
- /* else this channel was created with CreateChannel or EnsureChannel,
- * so don't.
- */
- }
- else
- {
- /* This channel was created with RequestChannel(SM, None, 0). */
-
- /* The peer can't be in remote pending */
- g_assert (!priv->peer_in_rp);
-
- /* The UI may call AddMembers([h], "") before calling
- * RequestStreams(h, [...]).
- */
- tp_group_mixin_change_flags (obj, TP_CHANNEL_GROUP_FLAG_CAN_ADD, 0);
- }
- }
-
- /* If this is a Google session, let's set ImmutableStreams */
- if (priv->session != NULL)
- {
- priv->immutable_streams = !wocky_jingle_session_can_modify_contents (priv->session);
- }
- /* If there's no session yet, but we know who the peer will be, and we have
- * presence for them, we can set ImmutableStreams using the same algorithm as
- * for old-style capabilities. If we don't know who the peer will be, then
- * the client is using an old calling convention and doesn't need to know
- * this.
- */
- else if (priv->initial_peer != 0)
- {
- GabblePresence *presence = gabble_presence_cache_get (
- priv->conn->presence_cache, priv->initial_peer);
- TpChannelMediaCapabilities flags = 0;
-
- if (presence != NULL)
- flags = _gabble_media_factory_caps_to_typeflags (
- gabble_presence_peek_caps (presence));
-
- if (flags & TP_CHANNEL_MEDIA_CAPABILITY_IMMUTABLE_STREAMS)
- priv->immutable_streams = TRUE;
- }
-
- return obj;
-}
-
-static void
-gabble_media_channel_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GabbleMediaChannel *chan = GABBLE_MEDIA_CHANNEL (object);
- GabbleMediaChannelPrivate *priv = chan->priv;
- TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn;
- const gchar *param_name;
- guint tp_property_id;
-
- switch (property_id) {
- case PROP_OBJECT_PATH:
- g_value_set_string (value, priv->object_path);
- break;
- case PROP_CHANNEL_TYPE:
- g_value_set_static_string (value, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
- break;
- case PROP_HANDLE_TYPE:
- /* This is used to implement TargetHandleType, which is immutable. If
- * the peer was known at channel-creation time, this will be Contact;
- * otherwise, it must be None even if we subsequently learn who the peer
- * is.
- */
- if (priv->initial_peer != 0)
- g_value_set_uint (value, TP_HANDLE_TYPE_CONTACT);
- else
- g_value_set_uint (value, TP_HANDLE_TYPE_NONE);
- break;
- case PROP_INITIAL_PEER:
- case PROP_HANDLE:
- /* As above: TargetHandle is immutable, so non-0 only if the peer handle
- * was known at creation time.
- */
- g_value_set_uint (value, priv->initial_peer);
- break;
- case PROP_TARGET_ID:
- /* As above. */
- if (priv->initial_peer != 0)
- {
- TpHandleRepoIface *repo = tp_base_connection_get_handles (
- base_conn, TP_HANDLE_TYPE_CONTACT);
- const gchar *target_id = tp_handle_inspect (repo, priv->initial_peer);
-
- g_value_set_string (value, target_id);
- }
- else
- {
- g_value_set_static_string (value, "");
- }
-
- break;
- case PROP_PEER:
- {
- TpHandle peer = 0;
-
- if (priv->initial_peer != 0)
- peer = priv->initial_peer;
- else
- peer = priv->peer;
-
- g_value_set_uint (value, peer);
- break;
- }
- case PROP_CONNECTION:
- g_value_set_object (value, priv->conn);
- break;
- case PROP_CREATOR:
- g_value_set_uint (value, priv->creator);
- break;
- case PROP_CREATOR_ID:
- {
- TpHandleRepoIface *repo = tp_base_connection_get_handles (
- base_conn, TP_HANDLE_TYPE_CONTACT);
-
- g_value_set_string (value, tp_handle_inspect (repo, priv->creator));
- }
- break;
- case PROP_REQUESTED:
- g_value_set_boolean (value,
- (priv->creator == tp_base_connection_get_self_handle (base_conn)));
- break;
- case PROP_INTERFACES:
- g_value_set_boxed (value, gabble_media_channel_interfaces);
- break;
- case PROP_CHANNEL_DESTROYED:
- g_value_set_boolean (value, priv->closed);
- break;
- case PROP_CHANNEL_PROPERTIES:
- g_value_take_boxed (value,
- tp_dbus_properties_mixin_make_properties_hash (object,
- TP_IFACE_CHANNEL, "TargetHandle",
- TP_IFACE_CHANNEL, "TargetHandleType",
- TP_IFACE_CHANNEL, "ChannelType",
- TP_IFACE_CHANNEL, "TargetID",
- TP_IFACE_CHANNEL, "InitiatorHandle",
- TP_IFACE_CHANNEL, "InitiatorID",
- TP_IFACE_CHANNEL, "Requested",
- TP_IFACE_CHANNEL, "Interfaces",
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "InitialAudio",
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "InitialVideo",
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA, "ImmutableStreams",
- NULL));
- break;
- case PROP_SESSION:
- g_value_set_object (value, priv->session);
- break;
- case PROP_INITIAL_AUDIO:
- g_value_set_boolean (value, priv->initial_audio);
- break;
- case PROP_INITIAL_VIDEO:
- g_value_set_boolean (value, priv->initial_video);
- break;
- case PROP_IMMUTABLE_STREAMS:
- g_value_set_boolean (value, priv->immutable_streams);
- break;
- case PROP_CURRENTLY_SENDING_TONES:
- g_value_set_boolean (value,
- tp_dtmf_player_is_active (priv->dtmf_player));
- break;
- case PROP_INITIAL_TONES:
- /* FIXME: stub */
- g_value_set_static_string (value, "");
- break;
- case PROP_DEFERRED_TONES:
- if (priv->deferred_tones != NULL)
- g_value_set_string (value, priv->deferred_tones);
- else
- g_value_set_static_string (value, "");
- break;
- default:
- param_name = g_param_spec_get_name (pspec);
-
- if (tp_properties_mixin_has_property (object, param_name,
- &tp_property_id))
- {
- GValue *tp_property_value =
- chan->properties.properties[tp_property_id].value;
-
- if (tp_property_value)
- {
- g_value_copy (tp_property_value, value);
- return;
- }
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-gabble_media_channel_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GabbleMediaChannel *chan = GABBLE_MEDIA_CHANNEL (object);
- GabbleMediaChannelPrivate *priv = chan->priv;
- const gchar *param_name;
- guint tp_property_id;
-
- switch (property_id) {
- case PROP_OBJECT_PATH:
- g_free (priv->object_path);
- priv->object_path = g_value_dup_string (value);
- break;
- case PROP_HANDLE_TYPE:
- case PROP_HANDLE:
- case PROP_CHANNEL_TYPE:
- /* these properties are writable in the interface, but not actually
- * meaningfully changable on this channel, so we do nothing */
- break;
- case PROP_CONNECTION:
- priv->conn = g_value_get_object (value);
- break;
- case PROP_CREATOR:
- priv->creator = g_value_get_uint (value);
- break;
- case PROP_INITIAL_PEER:
- priv->initial_peer = g_value_get_uint (value);
- break;
- case PROP_PEER_IN_RP:
- priv->peer_in_rp = g_value_get_boolean (value);
- break;
- case PROP_SESSION:
- g_assert (priv->session == NULL);
- priv->session = g_value_dup_object (value);
- if (priv->session != NULL)
- {
-
- }
- break;
- case PROP_INITIAL_AUDIO:
- priv->initial_audio = g_value_get_boolean (value);
- break;
- case PROP_INITIAL_VIDEO:
- priv->initial_video = g_value_get_boolean (value);
- break;
- default:
- param_name = g_param_spec_get_name (pspec);
-
- if (tp_properties_mixin_has_property (object, param_name,
- &tp_property_id))
- {
- tp_properties_mixin_change_value (object, tp_property_id, value,
- NULL);
- tp_properties_mixin_change_flags (object, tp_property_id,
- TP_PROPERTY_FLAG_READ,
- 0, NULL);
-
- return;
- }
-
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void gabble_media_channel_dispose (GObject *object);
-static void gabble_media_channel_finalize (GObject *object);
-static gboolean gabble_media_channel_add_member (GObject *obj,
- TpHandle handle,
- const gchar *message,
- GError **error);
-static gboolean gabble_media_channel_remove_member (GObject *obj,
- TpHandle handle, const gchar *message, guint reason, GError **error);
-
-static void
-gabble_media_channel_class_init (GabbleMediaChannelClass *gabble_media_channel_class)
-{
- static TpDBusPropertiesMixinPropImpl channel_props[] = {
- { "TargetHandleType", "handle-type", NULL },
- { "TargetHandle", "handle", NULL },
- { "TargetID", "target-id", NULL },
- { "ChannelType", "channel-type", NULL },
- { "Interfaces", "interfaces", NULL },
- { "Requested", "requested", NULL },
- { "InitiatorHandle", "creator", NULL },
- { "InitiatorID", "creator-id", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinPropImpl streamed_media_props[] = {
- { "ImmutableStreams", "immutable-streams", NULL },
- { "InitialAudio", "initial-audio", NULL },
- { "InitialVideo", "initial-video", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinPropImpl dtmf_props[] = {
- { "CurrentlySendingTones", "currently-sending-tones", NULL },
- { "InitialTones", "initial-tones", NULL },
- { "DeferredTones", "deferred-tones", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
- { TP_IFACE_CHANNEL,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- channel_props,
- },
- { TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- streamed_media_props,
- },
- { TP_IFACE_CHANNEL_INTERFACE_DTMF,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- dtmf_props,
- },
- { NULL }
- };
- GObjectClass *object_class = G_OBJECT_CLASS (gabble_media_channel_class);
- GParamSpec *param_spec;
-
- g_type_class_add_private (gabble_media_channel_class,
- sizeof (GabbleMediaChannelPrivate));
-
- object_class->constructor = gabble_media_channel_constructor;
-
- object_class->get_property = gabble_media_channel_get_property;
- object_class->set_property = gabble_media_channel_set_property;
-
- object_class->dispose = gabble_media_channel_dispose;
- object_class->finalize = gabble_media_channel_finalize;
-
- g_object_class_override_property (object_class, PROP_OBJECT_PATH,
- "object-path");
- g_object_class_override_property (object_class, PROP_CHANNEL_TYPE,
- "channel-type");
- g_object_class_override_property (object_class, PROP_HANDLE_TYPE,
- "handle-type");
- g_object_class_override_property (object_class, PROP_HANDLE, "handle");
-
- g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED,
- "channel-destroyed");
- g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES,
- "channel-properties");
-
- param_spec = g_param_spec_string ("target-id", "Target JID",
- "Currently empty, because this channel always has handle 0.",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec);
-
- param_spec = g_param_spec_uint ("initial-peer", "Other participant",
- "The TpHandle representing the other participant in the channel if known "
- "at construct-time; 0 if the other participant was unknown at the time "
- "of channel creation",
- 0, G_MAXUINT32, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_PEER, param_spec);
-
- param_spec = g_param_spec_boolean ("peer-in-rp",
- "Peer initially in Remote Pending?",
- "True if the channel was created with the most-deprecated "
- "RequestChannels form, and so the peer should be in Remote Pending "
- "before any XML has been sent.",
- FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_PEER_IN_RP, param_spec);
-
- param_spec = g_param_spec_uint ("peer", "Other participant",
- "The TpHandle representing the other participant in the channel if "
- "currently known; 0 if this is an anonymous channel on which "
- "RequestStreams has not yet been called.",
- 0, G_MAXUINT32, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_PEER, param_spec);
-
- param_spec = g_param_spec_object ("connection", "GabbleConnection object",
- "Gabble connection object that owns this media channel object.",
- GABBLE_TYPE_CONNECTION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
-
- param_spec = g_param_spec_uint ("creator", "Channel creator",
- "The TpHandle representing the contact who created the channel.",
- 0, G_MAXUINT32, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CREATOR, param_spec);
-
- param_spec = g_param_spec_string ("creator-id", "Creator bare JID",
- "The bare JID obtained by inspecting the creator handle.",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CREATOR_ID, param_spec);
-
- param_spec = g_param_spec_boolean ("requested", "Requested?",
- "True if this channel was requested by the local user",
- FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_REQUESTED, param_spec);
-
- param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
- "Additional Channel.Interface.* interfaces",
- G_TYPE_STRV,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
-
- param_spec = g_param_spec_string ("nat-traversal", "NAT traversal",
- "NAT traversal mechanism.",
- "gtalk-p2p",
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_NAT_TRAVERSAL,
- param_spec);
-
- param_spec = g_param_spec_string ("stun-server", "STUN server",
- "IP or address of STUN server.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STUN_SERVER, param_spec);
-
- param_spec = g_param_spec_uint ("stun-port", "STUN port",
- "UDP port of STUN server.",
- 0, G_MAXUINT16, 0,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STUN_PORT, param_spec);
-
- param_spec = g_param_spec_string ("gtalk-p2p-relay-token",
- "GTalk P2P Relay Token",
- "Magic token to authenticate with the Google Talk relay server.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_GTALK_P2P_RELAY_TOKEN,
- param_spec);
-
- param_spec = g_param_spec_object ("session", "WockyJingleSession object",
- "Jingle session associated with this media channel object.",
- WOCKY_TYPE_JINGLE_SESSION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_SESSION, param_spec);
-
- param_spec = g_param_spec_boolean ("initial-audio", "InitialAudio",
- "Whether the channel initially contained an audio stream",
- FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_AUDIO,
- param_spec);
-
- param_spec = g_param_spec_boolean ("initial-video", "InitialVideo",
- "Whether the channel initially contained an video stream",
- FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_VIDEO,
- param_spec);
-
- param_spec = g_param_spec_boolean ("immutable-streams", "ImmutableStreams",
- "Whether the set of streams on this channel are fixed once requested",
- FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_IMMUTABLE_STREAMS,
- param_spec);
-
- param_spec = g_param_spec_boolean ("currently-sending-tones",
- "CurrentlySendingTones",
- "True if a DTMF tone is being sent",
- FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CURRENTLY_SENDING_TONES,
- param_spec);
-
- param_spec = g_param_spec_string ("initial-tones", "InitialTones",
- "Initial DTMF tones to be sent in the first audio stream",
- "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIAL_TONES,
- param_spec);
-
- param_spec = g_param_spec_string ("deferred-tones", "DeferredTones",
- "DTMF tones that followed a 'w' or 'W', to be resumed on user request",
- "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_DEFERRED_TONES,
- param_spec);
-
- tp_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (GabbleMediaChannelClass, properties_class),
- channel_property_signatures, NUM_CHAN_PROPS, NULL);
-
- gabble_media_channel_class->dbus_props_class.interfaces = prop_interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (GabbleMediaChannelClass, dbus_props_class));
-
- tp_group_mixin_class_init (object_class,
- G_STRUCT_OFFSET (GabbleMediaChannelClass, group_class),
- gabble_media_channel_add_member, NULL);
- tp_group_mixin_class_set_remove_with_reason_func (object_class,
- gabble_media_channel_remove_member);
- tp_group_mixin_class_allow_self_removal (object_class);
-
- tp_group_mixin_init_dbus_properties (object_class);
-}
-
-void
-gabble_media_channel_dispose (GObject *object)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (object);
- GabbleMediaChannelPrivate *priv = self->priv;
- GList *l;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG ("called");
-
- priv->dispose_has_run = TRUE;
-
- if (!priv->closed)
- gabble_media_channel_close (self);
-
- g_assert (priv->closed);
- g_assert (priv->session == NULL);
-
- /* Since the session's dead, all the stream_creation_datas should have been
- * cancelled (which is indicated by their 'content' being NULL).
- */
- for (l = priv->stream_creation_datas; l != NULL; l = l->next)
- {
- StreamCreationData *d = l->data;
- g_assert (d->content == NULL);
- }
-
- g_list_free (priv->stream_creation_datas);
- priv->stream_creation_datas = NULL;
-
- if (priv->delayed_request_streams != NULL)
- {
- g_ptr_array_foreach (priv->delayed_request_streams,
- (GFunc) destroy_request, NULL);
- g_ptr_array_unref (priv->delayed_request_streams);
- priv->delayed_request_streams = NULL;
- }
-
- /* All of the streams should have closed in response to the contents being
- * removed when the call ended.
- */
- g_assert (priv->streams->len == 0);
- g_ptr_array_unref (priv->streams);
- priv->streams = NULL;
-
- if (G_OBJECT_CLASS (gabble_media_channel_parent_class)->dispose)
- G_OBJECT_CLASS (gabble_media_channel_parent_class)->dispose (object);
-}
-
-void
-gabble_media_channel_finalize (GObject *object)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (object);
- GabbleMediaChannelPrivate *priv = self->priv;
-
- g_free (priv->object_path);
- tp_clear_pointer (&self->priv->deferred_tones, g_free);
-
- tp_group_mixin_finalize (object);
- tp_properties_mixin_finalize (object);
-
- G_OBJECT_CLASS (gabble_media_channel_parent_class)->finalize (object);
-}
-
-
-/**
- * gabble_media_channel_close_async:
- *
- * Implements D-Bus method Close
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-gabble_media_channel_close_async (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
-
- if (DEBUGGING)
- {
- gchar *caller = dbus_g_method_get_sender (context);
-
- DEBUG ("called by %s", caller);
- g_free (caller);
- }
-
- gabble_media_channel_close (self);
- tp_svc_channel_return_from_close (context);
-}
-
-void
-gabble_media_channel_close (GabbleMediaChannel *self)
-{
- GabbleMediaChannelPrivate *priv = self->priv;
-
- DEBUG ("called on %p", self);
-
- if (!priv->closed)
- {
- priv->closed = TRUE;
-
- if (priv->session != NULL)
- wocky_jingle_session_terminate (priv->session,
- WOCKY_JINGLE_REASON_UNKNOWN, NULL, NULL);
-
- tp_svc_channel_emit_closed (self);
- }
-}
-
-
-/**
- * gabble_media_channel_get_channel_type
- *
- * Implements D-Bus method GetChannelType
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-gabble_media_channel_get_channel_type (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- tp_svc_channel_return_from_get_channel_type (context,
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
-}
-
-
-/**
- * gabble_media_channel_get_handle
- *
- * Implements D-Bus method GetHandle
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-gabble_media_channel_get_handle (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
-
- if (self->priv->initial_peer == 0)
- tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_NONE, 0);
- else
- tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_CONTACT,
- self->priv->initial_peer);
-}
-
-
-/**
- * gabble_media_channel_get_interfaces
- *
- * Implements D-Bus method GetInterfaces
- * on interface org.freedesktop.Telepathy.Channel
- */
-static void
-gabble_media_channel_get_interfaces (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- tp_svc_channel_return_from_get_interfaces (context,
- gabble_media_channel_interfaces);
-}
-
-
-/**
- * gabble_media_channel_get_session_handlers
- *
- * Implements D-Bus method GetSessionHandlers
- * on interface org.freedesktop.Telepathy.Channel.Interface.MediaSignalling
- */
-static void
-gabble_media_channel_get_session_handlers (TpSvcChannelInterfaceMediaSignalling *iface,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
- GabbleMediaChannelPrivate *priv;
- GPtrArray *ret;
- GType info_type = TP_STRUCT_TYPE_MEDIA_SESSION_HANDLER_INFO;
-
- g_assert (GABBLE_IS_MEDIA_CHANNEL (self));
-
- priv = self->priv;
-
- if (priv->session)
- {
- GValue handler = { 0, };
-
- g_value_init (&handler, info_type);
- g_value_take_boxed (&handler,
- dbus_g_type_specialized_construct (info_type));
-
- dbus_g_type_struct_set (&handler,
- 0, priv->object_path,
- 1, "rtp",
- G_MAXUINT);
-
- ret = g_ptr_array_sized_new (1);
- g_ptr_array_add (ret, g_value_get_boxed (&handler));
- }
- else
- {
- ret = g_ptr_array_sized_new (0);
- }
-
- tp_svc_channel_interface_media_signalling_return_from_get_session_handlers (
- context, ret);
- g_ptr_array_foreach (ret, (GFunc) g_value_array_free, NULL);
- g_ptr_array_unref (ret);
-}
-
-/**
- * make_stream_list:
- *
- * Creates an array of MediaStreamInfo structs.
- *
- * Precondition: priv->session is non-NULL.
- */
-static GPtrArray *
-make_stream_list (GabbleMediaChannel *self,
- guint len,
- GabbleMediaStream **streams)
-{
- GabbleMediaChannelPrivate *priv = self->priv;
- GPtrArray *ret;
- guint i;
- GType info_type = TP_STRUCT_TYPE_MEDIA_STREAM_INFO;
-
- g_assert (priv->session != NULL);
-
- ret = g_ptr_array_sized_new (len);
-
- for (i = 0; i < len; i++)
- {
- GValue entry = { 0, };
- guint id;
- TpMediaStreamType type;
- TpMediaStreamState connection_state;
- CombinedStreamDirection combined_direction;
-
- g_object_get (streams[i],
- "id", &id,
- "media-type", &type,
- "connection-state", &connection_state,
- "combined-direction", &combined_direction,
- NULL);
-
- g_value_init (&entry, info_type);
- g_value_take_boxed (&entry,
- dbus_g_type_specialized_construct (info_type));
-
- dbus_g_type_struct_set (&entry,
- 0, id,
- 1, priv->peer,
- 2, type,
- 3, connection_state,
- 4, COMBINED_DIRECTION_GET_DIRECTION (combined_direction),
- 5, COMBINED_DIRECTION_GET_PENDING_SEND (combined_direction),
- G_MAXUINT);
-
- g_ptr_array_add (ret, g_value_get_boxed (&entry));
- }
-
- return ret;
-}
-
-/**
- * gabble_media_channel_list_streams
- *
- * Implements D-Bus method ListStreams
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-gabble_media_channel_list_streams (TpSvcChannelTypeStreamedMedia *iface,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
- GabbleMediaChannelPrivate *priv;
- GPtrArray *ret;
-
- g_assert (GABBLE_IS_MEDIA_CHANNEL (self));
-
- priv = self->priv;
-
- /* If the session has not yet started, or has ended, return an empty array.
- */
- if (priv->session == NULL)
- {
- ret = g_ptr_array_new ();
- }
- else
- {
- ret = make_stream_list (self, priv->streams->len,
- (GabbleMediaStream **) priv->streams->pdata);
- }
-
- tp_svc_channel_type_streamed_media_return_from_list_streams (context, ret);
- g_ptr_array_foreach (ret, (GFunc) g_value_array_free, NULL);
- g_ptr_array_unref (ret);
-}
-
-
-static GabbleMediaStream *
-_find_stream_by_id (GabbleMediaChannel *chan,
- guint stream_id,
- GError **error)
-{
- GabbleMediaChannelPrivate *priv;
- guint i;
-
- g_assert (GABBLE_IS_MEDIA_CHANNEL (chan));
-
- priv = chan->priv;
-
- for (i = 0; i < priv->streams->len; i++)
- {
- GabbleMediaStream *stream = g_ptr_array_index (priv->streams, i);
- guint id;
-
- g_object_get (stream, "id", &id, NULL);
- if (id == stream_id)
- return stream;
- }
-
- g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
- "given stream id %u does not exist", stream_id);
- return NULL;
-}
-
-static GabbleMediaStream *
-_find_stream_by_content (GabbleMediaChannel *chan,
- WockyJingleContent *content)
-{
- GabbleMediaChannelPrivate *priv;
- guint i;
-
- g_assert (GABBLE_IS_MEDIA_CHANNEL (chan));
-
- priv = chan->priv;
-
- for (i = 0; i < priv->streams->len; i++)
- {
- GabbleMediaStream *stream = g_ptr_array_index (priv->streams, i);
- WockyJingleContent *c = WOCKY_JINGLE_CONTENT (
- gabble_media_stream_get_content (stream));
-
- if (content == c)
- return stream;
- }
-
- return NULL;
-}
-
-/**
- * gabble_media_channel_remove_streams
- *
- * Implements DBus method RemoveStreams
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-gabble_media_channel_remove_streams (TpSvcChannelTypeStreamedMedia *iface,
- const GArray * streams,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *obj = GABBLE_MEDIA_CHANNEL (iface);
- GabbleMediaChannelPrivate *priv;
- GPtrArray *stream_objs;
- GError *error = NULL;
- guint i;
-
- g_assert (GABBLE_IS_MEDIA_CHANNEL (obj));
-
- priv = obj->priv;
-
- if (!wocky_jingle_session_can_modify_contents (priv->session))
- {
- GError e = { TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
- "Streams can't be removed from Google Talk calls" };
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- stream_objs = g_ptr_array_sized_new (streams->len);
-
- /* check that all stream ids are valid and at the same time build an array
- * of stream objects so we don't have to look them up again after verifying
- * all stream identifiers. */
- for (i = 0; i < streams->len; i++)
- {
- guint id = g_array_index (streams, guint, i);
- GabbleMediaStream *stream;
- guint j;
-
- stream = _find_stream_by_id (obj, id, &error);
-
- if (stream == NULL)
- goto OUT;
-
- /* make sure we don't allow the client to repeatedly remove the same
- stream */
- for (j = 0; j < stream_objs->len; j++)
- {
- GabbleMediaStream *tmp = g_ptr_array_index (stream_objs, j);
-
- if (tmp == stream)
- {
- stream = NULL;
- break;
- }
- }
-
- if (stream != NULL)
- g_ptr_array_add (stream_objs, stream);
- }
-
- /* groovy, it's all good dude, let's remove them */
- if (stream_objs->len > 0)
- {
- GabbleMediaStream *stream;
- WockyJingleMediaRtp *c;
-
- for (i = 0; i < stream_objs->len; i++)
- {
- stream = g_ptr_array_index (stream_objs, i);
- c = gabble_media_stream_get_content (stream);
-
- /* FIXME: make sure session emits content-removed, on which we can
- * delete it from the list */
- wocky_jingle_session_remove_content (priv->session,
- (WockyJingleContent *) c);
- }
- }
-
-OUT:
- g_ptr_array_unref (stream_objs);
-
- if (error)
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
- else
- {
- tp_svc_channel_type_streamed_media_return_from_remove_streams (context);
- }
-}
-
-
-/**
- * gabble_media_channel_request_stream_direction
- *
- * Implements D-Bus method RequestStreamDirection
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-gabble_media_channel_request_stream_direction (TpSvcChannelTypeStreamedMedia *iface,
- guint stream_id,
- guint stream_direction,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
- GabbleMediaChannelPrivate *priv;
- GabbleMediaStream *stream;
- GError *error = NULL;
-
- g_assert (GABBLE_IS_MEDIA_CHANNEL (self));
-
- priv = self->priv;
-
- if (stream_direction > TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL)
- {
- g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
- "given stream direction %u is not valid", stream_direction);
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- stream = _find_stream_by_id (self, stream_id, &error);
-
- if (stream == NULL)
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- DEBUG ("called (stream %s, direction %u)", stream->name, stream_direction);
-
- /* streams with no session? I think not... */
- g_assert (priv->session != NULL);
-
- if (stream_direction == TP_MEDIA_STREAM_DIRECTION_NONE)
- {
- if (wocky_jingle_session_can_modify_contents (priv->session))
- {
- WockyJingleMediaRtp *c;
-
- DEBUG ("request for NONE direction; removing stream");
-
- c = gabble_media_stream_get_content (stream);
- wocky_jingle_session_remove_content (priv->session,
- (WockyJingleContent *) c);
-
- tp_svc_channel_type_streamed_media_return_from_request_stream_direction (
- context);
- }
- else
- {
- GError e = { TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
- "Stream direction can't be set to None in Google Talk calls" };
- DEBUG ("%s", e.message);
- dbus_g_method_return_error (context, &e);
- }
-
- return;
- }
-
- if (gabble_media_stream_change_direction (stream, stream_direction, &error))
- {
- tp_svc_channel_type_streamed_media_return_from_request_stream_direction (
- context);
- }
- else
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-typedef struct {
- /* number of streams requested == number of content objects */
- guint len;
- /* array of @len borrowed pointers */
- WockyJingleContent **contents;
- /* accumulates borrowed pointers to streams. Initially @len NULL pointers;
- * when the stream for contents[i] is created, it is stored at streams[i].
- */
- GabbleMediaStream **streams;
- /* number of non-NULL elements in streams (0 <= satisfied <= contents) */
- guint satisfied;
- /* succeeded_cb(context, GPtrArray<TP_STRUCT_TYPE_MEDIA_STREAM_INFO>)
- * will be called if the stream request succeeds.
- */
- GFunc succeeded_cb;
- /* failed_cb(context, GError *) will be called if the stream request fails.
- */
- GFunc failed_cb;
- gpointer context;
-} PendingStreamRequest;
-
-static PendingStreamRequest *
-pending_stream_request_new (GPtrArray *contents,
- GFunc succeeded_cb,
- GFunc failed_cb,
- gpointer context)
-{
- PendingStreamRequest *p = g_slice_new0 (PendingStreamRequest);
-
- g_assert (succeeded_cb);
- g_assert (failed_cb);
-
- p->len = contents->len;
- p->contents = g_memdup (contents->pdata, contents->len * sizeof (gpointer));
- p->streams = g_new0 (GabbleMediaStream *, contents->len);
- p->satisfied = 0;
- p->succeeded_cb = succeeded_cb;
- p->failed_cb = failed_cb;
- p->context = context;
-
- return p;
-}
-
-static gboolean
-pending_stream_request_maybe_satisfy (PendingStreamRequest *p,
- GabbleMediaChannel *channel,
- WockyJingleContent *content,
- GabbleMediaStream *stream)
-{
- guint i;
-
- for (i = 0; i < p->len; i++)
- {
- if (p->contents[i] == content)
- {
- g_assert (p->streams[i] == NULL);
- p->streams[i] = stream;
-
- if (++p->satisfied == p->len && p->context != NULL)
- {
- GPtrArray *ret = make_stream_list (channel, p->len, p->streams);
-
- p->succeeded_cb (p->context, ret);
- g_ptr_array_foreach (ret, (GFunc) g_value_array_free, NULL);
- g_ptr_array_unref (ret);
- p->context = NULL;
- return TRUE;
- }
- }
- }
-
- return FALSE;
-}
-
-static gboolean
-pending_stream_request_maybe_fail (PendingStreamRequest *p,
- GabbleMediaChannel *channel,
- WockyJingleContent *content)
-{
- guint i;
-
- for (i = 0; i < p->len; i++)
- {
- if (content == p->contents[i])
- {
- GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "A stream was removed before it could be fully set up" };
-
- /* return early */
- p->failed_cb (p->context, &e);
- p->context = NULL;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-pending_stream_request_free (gpointer data)
-{
- PendingStreamRequest *p = data;
-
- if (p->context != NULL)
- {
- GError e = { TP_ERROR, TP_ERROR_CANCELLED,
- "The session terminated before the requested streams could be added"
- };
-
- p->failed_cb (p->context, &e);
- }
-
- g_free (p->contents);
- g_free (p->streams);
-
- g_slice_free (PendingStreamRequest, p);
-}
-
-static gboolean
-_gabble_media_channel_request_contents (GabbleMediaChannel *chan,
- TpHandle peer,
- const GArray *media_types,
- GPtrArray **ret,
- GError **error)
-{
- GabbleMediaChannelPrivate *priv = chan->priv;
- gboolean want_audio, want_video;
- WockyJingleDialect dialect;
- guint idx;
- const gchar *peer_resource;
- const gchar *transport_ns = NULL;
-
- DEBUG ("called");
-
- want_audio = want_video = FALSE;
-
- for (idx = 0; idx < media_types->len; idx++)
- {
- guint media_type = g_array_index (media_types, guint, idx);
-
- if (media_type == TP_MEDIA_STREAM_TYPE_AUDIO)
- {
- want_audio = TRUE;
- }
- else if (media_type == TP_MEDIA_STREAM_TYPE_VIDEO)
- {
- want_video = TRUE;
- }
- else
- {
- g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
- "given media type %u is invalid", media_type);
- return FALSE;
- }
- }
-
- /* existing call; the recipient and the mode has already been decided */
- if (priv->session != NULL)
- {
- peer_resource = wocky_jingle_session_get_peer_resource (priv->session);
-
- if (peer_resource[0] != '\0')
- DEBUG ("existing call, using peer resource %s", peer_resource);
- else
- DEBUG ("existing call, using bare JID");
-
- /* is a google call... we have no other option */
- if (!wocky_jingle_session_can_modify_contents (priv->session))
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "Streams can't be added to ongoing Google Talk calls");
- return FALSE;
- }
-
- /* check if the resource supports it; FIXME - we assume only
- * one channel type (video or audio) will be added later */
- if (NULL == jingle_pick_best_content_type (priv->conn, peer,
- peer_resource,
- want_audio ? WOCKY_JINGLE_MEDIA_TYPE_AUDIO : WOCKY_JINGLE_MEDIA_TYPE_VIDEO))
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "member does not have the desired audio/video capabilities");
-
- return FALSE;
- }
-
- /* We assume we already picked the best possible transport ns for the
- * previous streams, so we just reuse that one */
- {
- GList *contents = wocky_jingle_session_get_contents (priv->session);
- WockyJingleContent *c;
-
- /* If we have a session, we must have at least one content. */
- g_assert (contents != NULL);
-
- c = contents->data;
- g_list_free (contents);
-
- transport_ns = wocky_jingle_content_get_transport_ns (c);
- }
- }
- /* no existing call; we should choose a recipient and a mode */
- else
- {
- gchar *jid;
-
- DEBUG ("picking the best resource (want audio: %u, want video: %u",
- want_audio, want_video);
-
- g_assert (priv->streams->len == 0);
-
- if (!jingle_pick_best_resource (priv->conn, peer,
- want_audio, want_video, &transport_ns, &dialect, &peer_resource))
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_CAPABLE,
- "member does not have the desired audio/video capabilities");
- return FALSE;
- }
-
- DEBUG ("Picking resource '%s' (transport: %s, dialect: %u)",
- peer_resource == NULL ? "(null)" : peer_resource,
- transport_ns, dialect);
-
- jid = gabble_peer_to_jid (priv->conn, peer, peer_resource);
- priv->peer = peer;
- create_session (chan, jid, dialect);
- g_free (jid);
-
- /* Change nat-traversal if we need to */
- if (!tp_strdiff (transport_ns, NS_JINGLE_TRANSPORT_ICEUDP))
- {
- DEBUG ("changing nat-traversal property to ice-udp");
- g_object_set (chan, "nat-traversal", "ice-udp", NULL);
- }
- else if (!tp_strdiff (transport_ns, NS_JINGLE_TRANSPORT_RAWUDP))
- {
- DEBUG ("changing nat-traversal property to raw-udp");
- g_object_set (chan, "nat-traversal", "none", NULL);
- }
- }
-
- /* check it's not a ridiculous number of streams */
- if ((priv->streams->len + media_types->len) > MAX_STREAMS)
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "I think that's quite enough streams already");
- return FALSE;
- }
-
- /* if we've got here, we're good to make the Jingle contents */
-
- *ret = g_ptr_array_sized_new (media_types->len);
-
- for (idx = 0; idx < media_types->len; idx++)
- {
- guint media_type = g_array_index (media_types, guint, idx);
- WockyJingleContent *c;
- const gchar *content_ns;
-
- content_ns = jingle_pick_best_content_type (priv->conn, peer,
- peer_resource,
- media_type == TP_MEDIA_STREAM_TYPE_AUDIO ?
- WOCKY_JINGLE_MEDIA_TYPE_AUDIO : WOCKY_JINGLE_MEDIA_TYPE_VIDEO);
-
- /* if we got this far, resource should be capable enough, so we
- * should not fail in choosing ns */
- g_assert (content_ns != NULL);
- g_assert (transport_ns != NULL);
-
- DEBUG ("Creating new jingle content with ns %s : %s", content_ns, transport_ns);
-
- c = wocky_jingle_session_add_content (priv->session,
- media_type == TP_MEDIA_STREAM_TYPE_AUDIO ?
- WOCKY_JINGLE_MEDIA_TYPE_AUDIO : WOCKY_JINGLE_MEDIA_TYPE_VIDEO,
- WOCKY_JINGLE_CONTENT_SENDERS_BOTH, NULL, content_ns, transport_ns);
-
- /* The stream is created in "new-content" callback, and appended to
- * priv->streams. This is now guaranteed to happen asynchronously (adding
- * streams can take time due to the relay info lookup, and if it doesn't,
- * we use an idle so it does). */
- g_assert (c != NULL);
- g_ptr_array_add (*ret, c);
- }
-
- return TRUE;
-}
-
-/* user_data param is here so we match the GFunc prototype */
-static void
-destroy_request (struct _delayed_request_streams_ctx *ctx,
- gpointer user_data G_GNUC_UNUSED)
-{
- GabbleMediaChannelPrivate *priv = ctx->chan->priv;
-
- if (ctx->unsure_period_ended_id)
- g_signal_handler_disconnect (priv->conn->presence_cache,
- ctx->unsure_period_ended_id);
-
- if (ctx->caps_disco_id)
- g_signal_handler_disconnect (priv->conn->presence_cache,
- ctx->caps_disco_id);
-
- if (ctx->context != NULL)
- {
- GError *error = NULL;
- g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "cannot add streams: peer has insufficient caps");
- ctx->failed_cb (ctx->context, error);
- g_error_free (error);
- }
-
- g_array_unref (ctx->types);
- g_slice_free (struct _delayed_request_streams_ctx, ctx);
-}
-
-static void
-destroy_and_remove_request (struct _delayed_request_streams_ctx *ctx)
-{
- GabbleMediaChannelPrivate *priv = ctx->chan->priv;
-
- destroy_request (ctx, NULL);
- g_ptr_array_remove_fast (priv->delayed_request_streams, ctx);
-}
-
-static void media_channel_request_streams (GabbleMediaChannel *self,
- TpHandle contact_handle,
- const GArray *types,
- GFunc succeeded_cb,
- GFunc failed_cb,
- gpointer context);
-
-static gboolean
-repeat_request (struct _delayed_request_streams_ctx *ctx)
-{
- media_channel_request_streams (ctx->chan, ctx->contact_handle, ctx->types,
- ctx->succeeded_cb, ctx->failed_cb, ctx->context);
-
- ctx->context = NULL;
- destroy_and_remove_request (ctx);
- return FALSE;
-}
-
-static void
-capabilities_discovered_cb (GabblePresenceCache *cache,
- TpHandle handle,
- struct _delayed_request_streams_ctx *ctx)
-{
- /* If this isn't the contact we're waiting for, ignore the signal. */
- if (ctx->contact_handle != handle)
- return;
-
- /* If we're still unsure about this contact (most likely because there are
- * more cache caps pending), wait for them. */
- if (gabble_presence_cache_is_unsure (cache, handle))
- return;
-
- repeat_request (ctx);
-}
-
-static void
-delay_stream_request (GabbleMediaChannel *chan,
- guint contact_handle,
- const GArray *types,
- GFunc succeeded_cb,
- GFunc failed_cb,
- gpointer context)
-{
- GabbleMediaChannelPrivate *priv = chan->priv;
- struct _delayed_request_streams_ctx *ctx =
- g_slice_new0 (struct _delayed_request_streams_ctx);
-
- ctx->chan = chan;
- ctx->contact_handle = contact_handle;
- ctx->succeeded_cb = succeeded_cb;
- ctx->failed_cb = failed_cb;
- ctx->context = context;
- ctx->types = g_array_sized_new (FALSE, FALSE, sizeof (guint), types->len);
- g_array_append_vals (ctx->types, types->data, types->len);
-
- ctx->caps_disco_id = g_signal_connect (priv->conn->presence_cache,
- "capabilities-discovered", G_CALLBACK (capabilities_discovered_cb),
- ctx);
- ctx->unsure_period_ended_id = g_signal_connect_swapped (
- priv->conn->presence_cache, "unsure-period-ended",
- G_CALLBACK (repeat_request), ctx);
-
- g_ptr_array_add (priv->delayed_request_streams, ctx);
-}
-
-static void
-media_channel_request_streams (GabbleMediaChannel *self,
- TpHandle contact_handle,
- const GArray *types,
- GFunc succeeded_cb,
- GFunc failed_cb,
- gpointer context)
-{
- GabbleMediaChannelPrivate *priv = self->priv;
- GPtrArray *contents;
- gboolean wait;
- PendingStreamRequest *psr;
- GError *error = NULL;
-
- if (types->len == 0)
- {
- GPtrArray *empty = g_ptr_array_sized_new (0);
-
- DEBUG ("no streams to request");
- succeeded_cb (context, empty);
- g_ptr_array_unref (empty);
-
- return;
- }
-
- /* If we know the caps haven't arrived yet, delay stream creation
- * and check again later. Else, give up. */
- if (!contact_is_media_capable (self, contact_handle, &wait, &error))
- {
- if (wait)
- {
- DEBUG ("Delaying RequestStreams until we get all caps from contact");
- delay_stream_request (self, contact_handle, types,
- succeeded_cb, failed_cb, context);
- g_error_free (error);
- return;
- }
-
- goto error;
- }
-
- if (priv->peer != 0 && priv->peer != contact_handle)
- {
- g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "cannot add streams for %u: this channel's peer is %u",
- contact_handle, priv->peer);
- goto error;
- }
-
- if (!_gabble_media_channel_request_contents (self, contact_handle, types,
- &contents, &error))
- goto error;
-
- psr = pending_stream_request_new (contents, succeeded_cb, failed_cb,
- context);
- priv->pending_stream_requests = g_list_prepend (priv->pending_stream_requests,
- psr);
- g_ptr_array_unref (contents);
-
- /* signal acceptance */
- wocky_jingle_session_accept (priv->session);
-
- return;
-
-error:
- DEBUG ("returning error %u: %s", error->code, error->message);
- failed_cb (context, error);
- g_error_free (error);
-}
-
-/**
- * gabble_media_channel_request_streams
- *
- * Implements D-Bus method RequestStreams
- * on interface org.freedesktop.Telepathy.Channel.Type.StreamedMedia
- */
-static void
-gabble_media_channel_request_streams (TpSvcChannelTypeStreamedMedia *iface,
- guint contact_handle,
- const GArray *types,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
- TpBaseConnection *base_conn = (TpBaseConnection *) self->priv->conn;
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (
- base_conn, TP_HANDLE_TYPE_CONTACT);
- GError *error = NULL;
-
- if (!tp_handle_is_valid (contact_handles, contact_handle, &error))
- {
- DEBUG ("that's not a handle, sonny! (%u)", contact_handle);
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
- else
- {
- /* FIXME: disallow this if we've put the peer on hold? */
-
- media_channel_request_streams (self, contact_handle, types,
- (GFunc) tp_svc_channel_type_streamed_media_return_from_request_streams,
- (GFunc) dbus_g_method_return_error,
- context);
- }
-}
-
-/**
- * gabble_media_channel_request_initial_streams:
- * @chan: an outgoing call, which must have just been constructed.
- * @succeeded_cb: called with arguments @user_data and a GPtrArray of
- * TP_STRUCT_TYPE_MEDIA_STREAM_INFO if the request succeeds.
- * @failed_cb: called with arguments @user_data and a GError * if the request
- * fails.
- * @user_data: context for the callbacks.
- *
- * Request streams corresponding to the values of InitialAudio and InitialVideo
- * in the channel request.
- */
-void
-gabble_media_channel_request_initial_streams (GabbleMediaChannel *chan,
- GFunc succeeded_cb,
- GFunc failed_cb,
- gpointer user_data)
-{
- GabbleMediaChannelPrivate *priv = chan->priv;
- GArray *types = g_array_sized_new (FALSE, FALSE, sizeof (guint), 2);
- guint media_type;
- TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn);
-
- /* This has to be an outgoing call... */
- g_assert (priv->creator == tp_base_connection_get_self_handle (base_conn));
- /* ...which has just been constructed. */
- g_assert (priv->session == NULL);
-
- if (priv->initial_peer == 0)
- {
- /* This is a ye olde anonymous channel, so InitialAudio/Video should be
- * impossible.
- */
- g_assert (!priv->initial_audio);
- g_assert (!priv->initial_video);
- }
-
- if (priv->initial_audio)
- {
- media_type = TP_MEDIA_STREAM_TYPE_AUDIO;
- g_array_append_val (types, media_type);
- }
-
- if (priv->initial_video)
- {
- media_type = TP_MEDIA_STREAM_TYPE_VIDEO;
- g_array_append_val (types, media_type);
- }
-
- media_channel_request_streams (chan, priv->initial_peer, types,
- succeeded_cb, failed_cb, user_data);
-
- g_array_unref (types);
-}
-
-static gboolean
-contact_is_media_capable (GabbleMediaChannel *chan,
- TpHandle peer,
- gboolean *wait_ret,
- GError **error)
-{
- GabbleMediaChannelPrivate *priv = chan->priv;
- GabblePresence *presence;
- TpBaseConnection *conn = (TpBaseConnection *) priv->conn;
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles (
- conn, TP_HANDLE_TYPE_CONTACT);
- gboolean wait = FALSE;
-
- presence = gabble_presence_cache_get (priv->conn->presence_cache, peer);
-
- if (presence != NULL)
- {
- const GabbleCapabilitySet *caps = gabble_presence_peek_caps (presence);
-
- if (gabble_capability_set_has_one (caps,
- gabble_capabilities_get_any_audio_video ()))
- return TRUE;
- }
-
- /* Okay, they're not capable (yet). Let's figure out whether we should wait,
- * and return an appropriate error.
- */
- if (gabble_presence_cache_is_unsure (priv->conn->presence_cache, peer))
- {
- DEBUG ("presence cache is still unsure about handle %u", peer);
- wait = TRUE;
- }
- else if (!priv->tried_decloaking &&
- gabble_presence_cache_request_decloaking (priv->conn->presence_cache,
- peer, "media"))
- {
- /* only ask to decloak at most once per call */
- priv->tried_decloaking = TRUE;
- DEBUG ("asked handle %u to decloak, let's see what they do", peer);
- wait = TRUE;
- }
-
- if (wait_ret != NULL)
- *wait_ret = wait;
-
- if (presence == NULL)
- g_set_error (error, TP_ERROR, TP_ERROR_OFFLINE,
- "contact %d (%s) has no presence available", peer,
- tp_handle_inspect (contact_handles, peer));
- else
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_CAPABLE,
- "contact %d (%s) doesn't have sufficient media caps", peer,
- tp_handle_inspect (contact_handles, peer));
-
- return FALSE;
-}
-
-static gboolean
-gabble_media_channel_add_member (GObject *obj,
- TpHandle handle,
- const gchar *message,
- GError **error)
-{
- GabbleMediaChannel *chan = GABBLE_MEDIA_CHANNEL (obj);
- GabbleMediaChannelPrivate *priv = chan->priv;
- TpGroupMixin *mixin = TP_GROUP_MIXIN (obj);
- TpIntset *set;
-
- /* did we create this channel? */
- if (priv->creator == mixin->self_handle)
- {
- GError *error_ = NULL;
- gboolean wait;
-
- /* yes: check we don't have a peer already, and if not add this one to
- * remote pending (but don't send an invitation yet).
- */
- if (priv->peer != 0 && priv->peer != handle)
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "handle %u cannot be added: this channel's peer is %u",
- handle, priv->peer);
- return FALSE;
- }
-
- /* We can't delay the request at this time, but if there's a chance
- * the caps might be available later, we'll add the contact and
- * hope for the best. */
- if (!contact_is_media_capable (chan, handle, &wait, &error_))
- {
- if (wait)
- {
- DEBUG ("contact %u caps still pending, adding anyways", handle);
- g_error_free (error_);
- }
- else
- {
- DEBUG ("%u: %s", error_->code, error_->message);
- g_propagate_error (error, error_);
- return FALSE;
- }
- }
-
- /* make the peer remote pending */
- set = tp_intset_new_containing (handle);
- tp_group_mixin_change_members (obj, "", NULL, NULL, NULL, set,
- mixin->self_handle, TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
- tp_intset_destroy (set);
-
- /* and remove CanAdd, since it was only here to allow this deprecated
- * API. */
- tp_group_mixin_change_flags (obj, 0, TP_CHANNEL_GROUP_FLAG_CAN_ADD);
-
- return TRUE;
- }
- else
- {
- /* no: has a session been created, is the handle being added ours,
- * and are we in local pending? (call answer) */
- if (priv->session &&
- handle == mixin->self_handle &&
- tp_handle_set_is_member (mixin->local_pending, handle))
- {
- /* is the call on hold? */
- if (priv->hold_state != TP_LOCAL_HOLD_STATE_UNHELD)
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "Can't answer a call while it's on hold");
- return FALSE;
- }
-
- /* make us a member */
- set = tp_intset_new_containing (handle);
- tp_group_mixin_change_members (obj, "", set, NULL, NULL, NULL,
- handle, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
- tp_intset_destroy (set);
-
- /* accept any local pending sends */
- g_ptr_array_foreach (priv->streams,
- (GFunc) gabble_media_stream_accept_pending_local_send, NULL);
-
- /* signal acceptance */
- wocky_jingle_session_accept (priv->session);
-
- return TRUE;
- }
- }
-
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "handle %u cannot be added in the current state", handle);
- return FALSE;
-}
-
-static gboolean
-gabble_media_channel_remove_member (GObject *obj,
- TpHandle handle,
- const gchar *message,
- TpChannelGroupChangeReason reason,
- GError **error)
-{
- GabbleMediaChannel *chan = GABBLE_MEDIA_CHANNEL (obj);
- GabbleMediaChannelPrivate *priv = chan->priv;
- TpGroupMixin *mixin = TP_GROUP_MIXIN (obj);
-
- /* We don't set CanRemove, and did allow self removal. So tp-glib should
- * ensure this.
- */
- g_assert (handle == mixin->self_handle);
-
- /* Closing up might make GabbleMediaFactory release its ref. */
- g_object_ref (chan);
-
- if (priv->session == NULL)
- {
- /* The call didn't even start yet; close up. */
- gabble_media_channel_close (chan);
- }
- else
- {
- WockyJingleReason wocky_jingle_reason = WOCKY_JINGLE_REASON_UNKNOWN;
-
- switch (reason)
- {
- case TP_CHANNEL_GROUP_CHANGE_REASON_NONE:
- wocky_jingle_reason = WOCKY_JINGLE_REASON_UNKNOWN;
- break;
- case TP_CHANNEL_GROUP_CHANGE_REASON_OFFLINE:
- wocky_jingle_reason = WOCKY_JINGLE_REASON_GONE;
- break;
- case TP_CHANNEL_GROUP_CHANGE_REASON_BUSY:
- wocky_jingle_reason = WOCKY_JINGLE_REASON_BUSY;
- break;
- case TP_CHANNEL_GROUP_CHANGE_REASON_ERROR:
- wocky_jingle_reason = WOCKY_JINGLE_REASON_GENERAL_ERROR;
- break;
- case TP_CHANNEL_GROUP_CHANGE_REASON_NO_ANSWER:
- wocky_jingle_reason = WOCKY_JINGLE_REASON_TIMEOUT;
- break;
- default:
- g_set_error (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
- "%u doesn't make sense as a reason to end a call", reason);
- g_object_unref (chan);
- return FALSE;
- }
-
- wocky_jingle_session_terminate (priv->session, wocky_jingle_reason, message,
- error);
- }
-
- /* Remove CanAdd if it was there for the deprecated anonymous channel
- * semantics, since the channel will go away RSN. */
- tp_group_mixin_change_flags (obj, 0, TP_CHANNEL_GROUP_FLAG_CAN_ADD);
-
- g_object_unref (chan);
-
- return TRUE;
-}
-
-/**
- * copy_stream_list:
- *
- * Returns a copy of priv->streams. This is used when applying a function to
- * all streams that could result in them being closed, to avoid stream_close_cb
- * modifying the list being iterated.
- */
-static GPtrArray *
-copy_stream_list (GabbleMediaChannel *channel)
-{
- return gabble_g_ptr_array_copy (channel->priv->streams);
-}
-
-
-/* return TRUE when the jingle reason is reason enough to raise a
- * StreamError */
-static gboolean
-extract_media_stream_error_from_jingle_reason (WockyJingleReason wocky_jingle_reason,
- TpMediaStreamError *stream_error)
-{
- TpMediaStreamError _stream_error;
-
- /* TODO: Make a better mapping with more distinction of possible errors */
- switch (wocky_jingle_reason)
- {
- case WOCKY_JINGLE_REASON_CONNECTIVITY_ERROR:
- _stream_error = TP_MEDIA_STREAM_ERROR_NETWORK_ERROR;
- break;
- case WOCKY_JINGLE_REASON_MEDIA_ERROR:
- _stream_error = TP_MEDIA_STREAM_ERROR_MEDIA_ERROR;
- break;
- case WOCKY_JINGLE_REASON_FAILED_APPLICATION:
- _stream_error = TP_MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED;
- break;
- case WOCKY_JINGLE_REASON_GENERAL_ERROR:
- _stream_error = TP_MEDIA_STREAM_ERROR_UNKNOWN;
- break;
- default:
- {
- if (stream_error != NULL)
- *stream_error = TP_MEDIA_STREAM_ERROR_UNKNOWN;
-
- return FALSE;
- }
- }
-
- if (stream_error != NULL)
- *stream_error = _stream_error;
-
- return TRUE;
-}
-
-static WockyJingleReason
-media_stream_error_to_jingle_reason (TpMediaStreamError stream_error)
-{
- switch (stream_error)
- {
- case TP_MEDIA_STREAM_ERROR_NETWORK_ERROR:
- return WOCKY_JINGLE_REASON_CONNECTIVITY_ERROR;
- case TP_MEDIA_STREAM_ERROR_MEDIA_ERROR:
- return WOCKY_JINGLE_REASON_MEDIA_ERROR;
- case TP_MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED:
- return WOCKY_JINGLE_REASON_FAILED_APPLICATION;
- default:
- return WOCKY_JINGLE_REASON_GENERAL_ERROR;
- }
-}
-
-static TpChannelGroupChangeReason
-wocky_jingle_reason_to_group_change_reason (WockyJingleReason wocky_jingle_reason)
-{
- switch (wocky_jingle_reason)
- {
- case WOCKY_JINGLE_REASON_BUSY:
- return TP_CHANNEL_GROUP_CHANGE_REASON_BUSY;
- case WOCKY_JINGLE_REASON_GONE:
- return TP_CHANNEL_GROUP_CHANGE_REASON_OFFLINE;
- case WOCKY_JINGLE_REASON_TIMEOUT:
- return TP_CHANNEL_GROUP_CHANGE_REASON_NO_ANSWER;
- case WOCKY_JINGLE_REASON_CONNECTIVITY_ERROR:
- case WOCKY_JINGLE_REASON_FAILED_APPLICATION:
- case WOCKY_JINGLE_REASON_FAILED_TRANSPORT:
- case WOCKY_JINGLE_REASON_GENERAL_ERROR:
- case WOCKY_JINGLE_REASON_MEDIA_ERROR:
- case WOCKY_JINGLE_REASON_SECURITY_ERROR:
- case WOCKY_JINGLE_REASON_INCOMPATIBLE_PARAMETERS:
- case WOCKY_JINGLE_REASON_UNSUPPORTED_APPLICATIONS:
- case WOCKY_JINGLE_REASON_UNSUPPORTED_TRANSPORTS:
- return TP_CHANNEL_GROUP_CHANGE_REASON_ERROR;
- default:
- return TP_CHANNEL_GROUP_CHANGE_REASON_NONE;
- }
-}
-
-static void
-session_terminated_cb (WockyJingleSession *session,
- gboolean local_terminator,
- WockyJingleReason wocky_jingle_reason,
- const gchar *text,
- gpointer user_data)
-{
- GabbleMediaChannel *channel = (GabbleMediaChannel *) user_data;
- GabbleMediaChannelPrivate *priv = channel->priv;
- TpGroupMixin *mixin = TP_GROUP_MIXIN (channel);
- guint terminator;
- WockyJingleState state;
- TpIntset *set;
-
- DEBUG ("called");
-
- g_object_get (session,
- "state", &state,
- NULL);
-
- if (local_terminator)
- terminator = mixin->self_handle;
- else
- terminator = priv->peer;
-
- set = tp_intset_new ();
-
- /* remove us and the peer from the member list */
- tp_intset_add (set, mixin->self_handle);
- tp_intset_add (set, priv->peer);
-
- tp_group_mixin_change_members ((GObject *) channel,
- text, NULL, set, NULL, NULL, terminator,
- wocky_jingle_reason_to_group_change_reason (wocky_jingle_reason));
-
- tp_intset_destroy (set);
-
- /* Ignore any Google relay session responses we're waiting for. */
- g_list_foreach (priv->stream_creation_datas, stream_creation_data_cancel,
- NULL);
-
- /* any contents that we were waiting for have now lost */
- g_list_foreach (priv->pending_stream_requests,
- (GFunc) pending_stream_request_free, NULL);
- g_list_free (priv->pending_stream_requests);
- priv->pending_stream_requests = NULL;
-
- {
- GPtrArray *tmp = copy_stream_list (channel);
- guint i;
- TpMediaStreamError stream_error = TP_MEDIA_STREAM_ERROR_UNKNOWN;
- gboolean is_error = extract_media_stream_error_from_jingle_reason (
- wocky_jingle_reason, &stream_error);
-
- for (i = 0; i < tmp->len; i++)
- {
- GabbleMediaStream *stream = tmp->pdata[i];
-
- if (is_error)
- {
- guint id;
-
- DEBUG ("emitting stream error");
-
- g_object_get (stream, "id", &id, NULL);
- tp_svc_channel_type_streamed_media_emit_stream_error (channel, id,
- stream_error, text);
- }
-
- gabble_media_stream_close (stream);
- }
-
- /* All the streams should have closed. */
- g_assert (priv->streams->len == 0);
-
- g_ptr_array_unref (tmp);
- }
-
- /* remove the session */
- tp_clear_object (&priv->session);
-
- /* close us if we aren't already closed */
- if (!priv->closed)
- {
- DEBUG ("calling media channel close from session terminated cb");
- gabble_media_channel_close (channel);
- }
-}
-
-
-static void
-session_state_changed_cb (WockyJingleSession *session,
- GParamSpec *arg1,
- GabbleMediaChannel *channel)
-{
- GObject *as_object = (GObject *) channel;
- GabbleMediaChannelPrivate *priv = channel->priv;
- TpGroupMixin *mixin = TP_GROUP_MIXIN (channel);
- WockyJingleState state;
- TpIntset *set;
-
- DEBUG ("called");
-
- g_object_get (session,
- "state", &state,
- NULL);
-
- set = tp_intset_new_containing (priv->peer);
-
- if (state >= WOCKY_JINGLE_STATE_PENDING_INITIATE_SENT &&
- state < WOCKY_JINGLE_STATE_ACTIVE &&
- !tp_handle_set_is_member (mixin->members, priv->peer))
- {
- /* The first time we send anything to the other user, they materialise
- * in remote-pending if necessary */
-
- tp_group_mixin_change_members (as_object, "", NULL, NULL, NULL, set,
- mixin->self_handle, TP_CHANNEL_GROUP_CHANGE_REASON_INVITED);
-
- /* Remove CanAdd if it happened to be there to support deprecated
- * RequestChannel(..., 0) followed by AddMembers([h], ...) semantics.
- */
- tp_group_mixin_change_flags (as_object, 0, TP_CHANNEL_GROUP_FLAG_CAN_ADD);
- }
-
- if (state == WOCKY_JINGLE_STATE_ACTIVE &&
- priv->creator == mixin->self_handle)
- {
-
- DEBUG ("adding peer to the member list and updating flags");
-
- /* add the peer to the member list */
- tp_group_mixin_change_members (as_object, "", set, NULL, NULL, NULL,
- priv->peer, TP_CHANNEL_GROUP_CHANGE_REASON_NONE);
- }
-
- tp_intset_destroy (set);
-}
-
-static void
-stream_close_cb (GabbleMediaStream *stream,
- GabbleMediaChannel *chan)
-{
- GabbleMediaChannelPrivate *priv = chan->priv;
- guint id, i;
- gboolean still_have_audio = FALSE;
-
- g_assert (GABBLE_IS_MEDIA_CHANNEL (chan));
-
- g_object_get (stream,
- "id", &id,
- NULL);
-
- tp_svc_channel_type_streamed_media_emit_stream_removed (chan, id);
-
- if (g_ptr_array_remove (priv->streams, stream))
- g_object_unref (stream);
- else
- g_warning ("stream %p (%s) removed, but it wasn't in priv->streams!",
- stream, stream->name);
-
- gabble_media_channel_hold_stream_closed (chan, stream);
-
- for (i = 0; i < priv->streams->len; i++)
- {
- GabbleMediaStream *other = g_ptr_array_index (priv->streams, i);
-
- if (gabble_media_stream_get_media_type (other) ==
- TP_MEDIA_STREAM_TYPE_AUDIO)
- {
- still_have_audio = TRUE;
- }
- }
-
- if (priv->have_some_audio && !still_have_audio)
- {
- /* the last audio stream just closed */
- tp_dtmf_player_cancel (priv->dtmf_player);
- }
-
- priv->have_some_audio = still_have_audio;
-}
-
-static void
-stream_error_cb (GabbleMediaStream *stream,
- TpMediaStreamError errno,
- const gchar *message,
- GabbleMediaChannel *chan)
-{
- GabbleMediaChannelPrivate *priv = chan->priv;
- WockyJingleMediaRtp *c;
- GList *contents;
- guint id;
-
- /* emit signal */
- g_object_get (stream, "id", &id, NULL);
- tp_svc_channel_type_streamed_media_emit_stream_error (chan, id, errno,
- message);
-
- contents = wocky_jingle_session_get_contents (priv->session);
-
- if (wocky_jingle_session_can_modify_contents (priv->session) &&
- g_list_length (contents) > 1)
- {
- /* remove stream from session (removal will be signalled
- * so we can dispose of the stream)
- */
- c = gabble_media_stream_get_content (stream);
-
- if (errno == TP_MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED)
- wocky_jingle_content_reject ((WockyJingleContent *) c,
- WOCKY_JINGLE_REASON_FAILED_APPLICATION);
- else
- wocky_jingle_session_remove_content (priv->session,
- (WockyJingleContent *) c);
- }
- else
- {
- /* We can't remove the content, or it's the only one left; let's
- * terminate the call. (The alternative is to carry on the call with
- * only audio/video, which will look or sound bad to the Google
- * Talk-using peer.)
- */
- DEBUG ("Terminating call in response to stream error");
- wocky_jingle_session_terminate (priv->session,
- media_stream_error_to_jingle_reason (errno), message, NULL);
- }
-
- g_list_free (contents);
-}
-
-static void
-stream_state_changed_cb (GabbleMediaStream *stream,
- GParamSpec *pspec,
- GabbleMediaChannel *chan)
-{
- guint id;
- TpMediaStreamState connection_state;
-
- g_object_get (stream,
- "id", &id,
- "connection-state", &connection_state,
- NULL);
-
- tp_svc_channel_type_streamed_media_emit_stream_state_changed (chan,
- id, connection_state);
-}
-
-static void
-stream_direction_changed_cb (GabbleMediaStream *stream,
- GParamSpec *pspec,
- GabbleMediaChannel *chan)
-{
- guint id;
- CombinedStreamDirection combined;
- TpMediaStreamDirection direction;
- TpMediaStreamPendingSend pending_send;
-
- g_object_get (stream,
- "id", &id,
- "combined-direction", &combined,
- NULL);
-
- direction = COMBINED_DIRECTION_GET_DIRECTION (combined);
- pending_send = COMBINED_DIRECTION_GET_PENDING_SEND (combined);
-
- DEBUG ("direction: %u, pending_send: %u", direction, pending_send);
-
- tp_svc_channel_type_streamed_media_emit_stream_direction_changed (
- chan, id, direction, pending_send);
-}
-
-static void
-construct_stream (GabbleMediaChannel *chan,
- WockyJingleContent *c,
- const gchar *name,
- const gchar *nat_traversal,
- const GPtrArray *relays,
- gboolean initial)
-{
- GObject *chan_o = (GObject *) chan;
- GabbleMediaChannelPrivate *priv = chan->priv;
- GabbleMediaStream *stream;
- TpMediaStreamType mtype;
- guint id;
- gchar *object_path;
- gboolean local_hold = (priv->hold_state == TP_LOCAL_HOLD_STATE_HELD ||
- priv->hold_state == TP_LOCAL_HOLD_STATE_PENDING_HOLD);
-
- id = priv->next_stream_id++;
-
- object_path = g_strdup_printf ("%s/MediaStream%u",
- priv->object_path, id);
-
- stream = gabble_media_stream_new (
- tp_base_connection_get_dbus_daemon (TP_BASE_CONNECTION (priv->conn)),
- object_path, c, name, id, nat_traversal, relays, local_hold);
- mtype = gabble_media_stream_get_media_type (stream);
-
- if (mtype == TP_MEDIA_STREAM_TYPE_AUDIO)
- {
- gabble_media_stream_add_dtmf_player (stream, priv->dtmf_player);
- priv->have_some_audio = TRUE;
- }
-
- DEBUG ("%p: created new MediaStream %p for content '%s'", chan, stream, name);
-
- g_ptr_array_add (priv->streams, stream);
-
- /* if any RequestStreams call was waiting for a stream to be created for
- * that content, return from it successfully */
- {
- GList *l = priv->pending_stream_requests;
-
- while (l != NULL)
- {
- if (pending_stream_request_maybe_satisfy (l->data,
- chan, c, stream))
- {
- GList *dead = l;
-
- pending_stream_request_free (dead->data);
-
- l = dead->next;
- priv->pending_stream_requests = g_list_delete_link (
- priv->pending_stream_requests, dead);
- }
- else
- {
- l = l->next;
- }
- }
- }
-
- gabble_signal_connect_weak (stream, "close", (GCallback) stream_close_cb,
- chan_o);
- gabble_signal_connect_weak (stream, "error", (GCallback) stream_error_cb,
- chan_o);
- gabble_signal_connect_weak (stream, "notify::connection-state",
- (GCallback) stream_state_changed_cb, chan_o);
- gabble_signal_connect_weak (stream, "notify::combined-direction",
- (GCallback) stream_direction_changed_cb, chan_o);
-
- if (initial)
- {
- /* If we accepted the call, then automagically accept the initial streams
- * when they pop up */
- if (tp_handle_set_is_member (chan->group.members,
- chan->group.self_handle))
- {
- gabble_media_stream_accept_pending_local_send (stream);
- }
- }
-
- DEBUG ("emitting StreamAdded with type '%s'",
- mtype == TP_MEDIA_STREAM_TYPE_AUDIO ? "audio" : "video");
-
- tp_svc_channel_type_streamed_media_emit_stream_added (
- chan, id, priv->peer, mtype);
-
- /* StreamAdded does not include the stream's direction and pending send
- * information, so we call the notify::combined-direction handler in order to
- * emit StreamDirectionChanged for the initial state.
- */
- stream_direction_changed_cb (stream, NULL, chan);
-
- gabble_media_channel_hold_new_stream (chan, stream,
- WOCKY_JINGLE_MEDIA_RTP (c));
-
- if (priv->ready)
- {
- /* all of the streams are bidirectional from farsight's point of view, it's
- * just in the signalling they change */
- DEBUG ("emitting MediaSessionHandler:NewStreamHandler signal for stream %d", id);
- tp_svc_media_session_handler_emit_new_stream_handler (chan,
- object_path, id, mtype, TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL);
- }
-
- g_free (object_path);
-}
-
-static void
-stream_creation_data_cancel (gpointer p,
- gpointer unused)
-{
- StreamCreationData *d = p;
-
- tp_clear_object (&d->content);
-}
-
-static void
-stream_creation_data_free (gpointer p)
-{
- StreamCreationData *d = p;
-
- g_free (d->name);
-
- if (d->content != NULL)
- {
- g_signal_handler_disconnect (d->content, d->removed_id);
- g_object_unref (d->content);
- }
-
- if (d->self != NULL)
- {
- GabbleMediaChannelPrivate *priv = d->self->priv;
-
- g_object_remove_weak_pointer (G_OBJECT (d->self), (gpointer *) &d->self);
- priv->stream_creation_datas = g_list_remove (
- priv->stream_creation_datas, d);
- }
-
- g_slice_free (StreamCreationData, d);
-}
-
-static gboolean
-construct_stream_later_cb (gpointer user_data)
-{
- StreamCreationData *d = user_data;
-
- if (d->content != NULL && d->self != NULL)
- construct_stream (d->self, d->content, d->name, d->nat_traversal, NULL,
- d->initial);
-
- return FALSE;
-}
-
-static void
-google_relay_session_cb (GPtrArray *relays,
- gpointer user_data)
-{
- StreamCreationData *d = user_data;
- GPtrArray *tp_relays = gabble_build_tp_relay_info (relays);
-
- if (d->content != NULL && d->self != NULL)
- construct_stream (d->self, d->content, d->name, d->nat_traversal, tp_relays,
- d->initial);
-
- g_ptr_array_unref (tp_relays);
- stream_creation_data_free (d);
-}
-
-static void
-content_removed_cb (WockyJingleContent *content,
- StreamCreationData *d)
-{
-
- if (d->content == NULL)
- return;
-
- if (d->self != NULL)
- {
- GList *l = d->self->priv->pending_stream_requests;
-
- /* if any RequestStreams call was waiting for a stream to be created for
- * that content, return from it unsuccessfully */
- while (l != NULL)
- {
- if (pending_stream_request_maybe_fail (l->data,
- d->self, d->content))
- {
- GList *dead = l;
-
- pending_stream_request_free (dead->data);
-
- l = dead->next;
- d->self->priv->pending_stream_requests = g_list_delete_link (
- d->self->priv->pending_stream_requests, dead);
- }
- else
- {
- l = l->next;
- }
- }
- }
-
- g_signal_handler_disconnect (d->content, d->removed_id);
- g_object_unref (d->content);
- d->content = NULL;
-}
-
-static void
-create_stream_from_content (GabbleMediaChannel *self,
- WockyJingleContent *c,
- gboolean initial)
-{
- gchar *name;
- StreamCreationData *d;
-
- g_object_get (c,
- "name", &name,
- NULL);
-
- if (G_OBJECT_TYPE (c) != WOCKY_TYPE_JINGLE_MEDIA_RTP)
- {
- DEBUG ("ignoring non MediaRtp content '%s'", name);
- g_free (name);
- return;
- }
-
- d = g_slice_new0 (StreamCreationData);
-
- d->self = self;
- d->name = name;
- d->content = g_object_ref (c);
- d->initial = initial;
-
- g_object_add_weak_pointer (G_OBJECT (d->self), (gpointer *) &d->self);
-
- /* If the content gets removed before we've finished looking up its
- * relay, we need to cancel the creation of the stream,
- * and make any PendingStreamRequests fail */
- d->removed_id = g_signal_connect (c, "removed",
- G_CALLBACK (content_removed_cb), d);
-
- self->priv->stream_creation_datas = g_list_prepend (
- self->priv->stream_creation_datas, d);
-
- switch (wocky_jingle_content_get_transport_type (c))
- {
- case JINGLE_TRANSPORT_GOOGLE_P2P:
- /* See if our server is Google, and if it is, ask them for a relay.
- * We ask for enough relays for 2 components (RTP and RTCP) since we
- * don't yet know whether there will be RTCP. */
- d->nat_traversal = "gtalk-p2p";
- DEBUG ("Attempting to create Google relay session");
- wocky_jingle_info_create_google_relay_session (
- gabble_jingle_mint_get_info (self->priv->conn->jingle_mint),
- 2, google_relay_session_cb, d);
- return;
-
- case JINGLE_TRANSPORT_ICE_UDP:
- d->nat_traversal = "ice-udp";
- break;
-
- default:
- d->nat_traversal = "none";
- }
-
- /* If we got here, just create the stream (do it asynchronously so that the
- * behaviour is the same in each case) */
- g_idle_add_full (G_PRIORITY_DEFAULT, construct_stream_later_cb,
- d, stream_creation_data_free);
-}
-
-static void
-session_content_rejected_cb (WockyJingleSession *session,
- WockyJingleContent *c, WockyJingleReason reason, const gchar *message,
- gpointer user_data)
-{
- GabbleMediaChannel *chan = GABBLE_MEDIA_CHANNEL (user_data);
- GabbleMediaStream *stream = _find_stream_by_content (chan, c);
- TpMediaStreamError stream_error = TP_MEDIA_STREAM_ERROR_UNKNOWN;
- guint id = 0;
-
- DEBUG (" ");
-
- g_return_if_fail (stream != NULL);
-
- g_object_get (stream,
- "id", &id,
- NULL);
-
- extract_media_stream_error_from_jingle_reason (reason, &stream_error);
-
- tp_svc_channel_type_streamed_media_emit_stream_error (chan, id, stream_error,
- message);
-}
-
-static void
-session_new_content_cb (WockyJingleSession *session,
- WockyJingleContent *c, gpointer user_data)
-{
- GabbleMediaChannel *chan = GABBLE_MEDIA_CHANNEL (user_data);
-
- DEBUG ("called");
-
- create_stream_from_content (chan, c, FALSE);
-}
-
-static void
-_emit_new_stream (GabbleMediaChannel *chan,
- GabbleMediaStream *stream)
-{
- gchar *object_path;
- guint id, media_type;
-
- g_object_get (stream,
- "object-path", &object_path,
- "id", &id,
- "media-type", &media_type,
- NULL);
-
- /* all of the streams are bidirectional from farsight's point of view, it's
- * just in the signalling they change */
- DEBUG ("emitting MediaSessionHandler:NewStreamHandler signal for %s stream %d ",
- media_type == TP_MEDIA_STREAM_TYPE_AUDIO ? "audio" : "video", id);
- tp_svc_media_session_handler_emit_new_stream_handler (chan,
- object_path, id, media_type, TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL);
-
- g_free (object_path);
-}
-
-
-static void
-gabble_media_channel_ready (TpSvcMediaSessionHandler *iface,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
- GabbleMediaChannelPrivate *priv = self->priv;
-
- if (priv->session == NULL)
- {
- /* This could also be because someone called Ready() before the
- * SessionHandler was announced. But the fact that the SessionHandler is
- * actually also the Channel, and thus this method is available before
- * NewSessionHandler is emitted, is an implementation detail. So the
- * error message describes the only legitimate situation in which this
- * could arise.
- */
- GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "call has already ended" };
-
- DEBUG ("no session, returning an error.");
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- if (!priv->ready)
- {
- guint i;
-
- DEBUG ("emitting NewStreamHandler for each stream");
-
- priv->ready = TRUE;
-
- for (i = 0; i < priv->streams->len; i++)
- _emit_new_stream (self, g_ptr_array_index (priv->streams, i));
- }
-
- tp_svc_media_session_handler_return_from_ready (context);
-}
-
-static void
-gabble_media_channel_error (TpSvcMediaSessionHandler *iface,
- guint errno,
- const gchar *message,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
- GabbleMediaChannelPrivate *priv;
- GPtrArray *tmp;
- guint i;
- WockyJingleState state;
-
- g_assert (GABBLE_IS_MEDIA_CHANNEL (self));
-
- priv = self->priv;
-
- if (priv->session == NULL)
- {
- /* This could also be because someone called Error() before the
- * SessionHandler was announced. But the fact that the SessionHandler is
- * actually also the Channel, and thus this method is available before
- * NewSessionHandler is emitted, is an implementation detail. So the
- * error message describes the only legitimate situation in which this
- * could arise.
- */
- GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE, "call has already ended" };
-
- DEBUG ("no session, returning an error.");
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- DEBUG ("Media.SessionHandler::Error called, error %u (%s) -- "
- "emitting error on each stream", errno, message);
-
- g_object_get (priv->session, "state", &state, NULL);
-
- if (state == WOCKY_JINGLE_STATE_ENDED)
- {
- tp_svc_media_session_handler_return_from_error (context);
- return;
- }
- else if (state == WOCKY_JINGLE_STATE_PENDING_CREATED)
- {
- /* shortcut to prevent sending remove actions if we haven't sent an
- * initiate yet */
- g_object_set (self, "state", WOCKY_JINGLE_STATE_ENDED, NULL);
- tp_svc_media_session_handler_return_from_error (context);
- return;
- }
-
- /* Calling gabble_media_stream_error () on all the streams will ultimately
- * cause them all to emit 'closed'. In response to 'closed', stream_close_cb
- * unrefs them, and removes them from priv->streams. So, we copy the stream
- * list to avoid it being modified from underneath us.
- */
- tmp = copy_stream_list (self);
-
- for (i = 0; i < tmp->len; i++)
- {
- GabbleMediaStream *stream = g_ptr_array_index (tmp, i);
-
- gabble_media_stream_error (stream, errno, message, NULL);
- }
-
- g_ptr_array_unref (tmp);
-
- tp_svc_media_session_handler_return_from_error (context);
-}
-
-#define TONE_MS 200
-#define GAP_MS 100
-#define PAUSE_MS 3000
-/* arbitrary limit on the length of a tone started with StartTone */
-#define MAX_TONE_SECONDS 10
-
-static void
-gabble_media_channel_start_tone (TpSvcChannelInterfaceDTMF *iface,
- guint stream_id G_GNUC_UNUSED,
- guchar event,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
- gchar tones[2] = { '\0', '\0' };
- GError *error = NULL;
-
- if (!self->priv->have_some_audio)
- {
- GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "There are no audio streams" };
-
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- tones[0] = tp_dtmf_event_to_char (event);
-
- if (tp_dtmf_player_play (self->priv->dtmf_player,
- tones, MAX_TONE_SECONDS * 1000, GAP_MS, PAUSE_MS, &error))
- {
- tp_clear_pointer (&self->priv->deferred_tones, g_free);
- tp_svc_channel_interface_dtmf_emit_sending_tones (self, tones);
- tp_svc_channel_interface_dtmf_return_from_start_tone (context);
- }
- else
- {
- dbus_g_method_return_error (context, error);
- g_clear_error (&error);
- }
-}
-
-static void
-gabble_media_channel_stop_tone (TpSvcChannelInterfaceDTMF *iface,
- guint stream_id,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
-
- tp_dtmf_player_cancel (self->priv->dtmf_player);
- tp_svc_channel_interface_dtmf_return_from_stop_tone (context);
-}
-
-static void
-gabble_media_channel_multiple_tones (
- TpSvcChannelInterfaceDTMF *iface,
- const gchar *dialstring,
- DBusGMethodInvocation *context)
-{
- GabbleMediaChannel *self = GABBLE_MEDIA_CHANNEL (iface);
- GError *error = NULL;
-
- if (!self->priv->have_some_audio)
- {
- GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "There are no audio streams" };
-
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- if (tp_dtmf_player_play (self->priv->dtmf_player,
- dialstring, TONE_MS, GAP_MS, PAUSE_MS, &error))
- {
- tp_clear_pointer (&self->priv->deferred_tones, g_free);
- tp_svc_channel_interface_dtmf_emit_sending_tones (self, dialstring);
- tp_svc_channel_interface_dtmf_return_from_start_tone (context);
- }
- else
- {
- dbus_g_method_return_error (context, error);
- g_clear_error (&error);
- }
-}
-
-static void
-channel_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelClass *klass = (TpSvcChannelClass *) g_iface;
-
-#define IMPLEMENT(x, suffix) tp_svc_channel_implement_##x (\
- klass, gabble_media_channel_##x##suffix)
- IMPLEMENT(close,_async);
- IMPLEMENT(get_channel_type,);
- IMPLEMENT(get_handle,);
- IMPLEMENT(get_interfaces,);
-#undef IMPLEMENT
-}
-
-static void
-dtmf_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelInterfaceDTMFClass *klass = g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_interface_dtmf_implement_##x (\
- klass, gabble_media_channel_##x)
- IMPLEMENT(start_tone);
- IMPLEMENT(stop_tone);
- IMPLEMENT(multiple_tones);
-#undef IMPLEMENT
-}
-
-static void
-streamed_media_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelTypeStreamedMediaClass *klass =
- (TpSvcChannelTypeStreamedMediaClass *) g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_type_streamed_media_implement_##x (\
- klass, gabble_media_channel_##x)
- IMPLEMENT(list_streams);
- IMPLEMENT(remove_streams);
- IMPLEMENT(request_stream_direction);
- IMPLEMENT(request_streams);
-#undef IMPLEMENT
-}
-
-static void
-media_signalling_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcChannelInterfaceMediaSignallingClass *klass =
- (TpSvcChannelInterfaceMediaSignallingClass *) g_iface;
-
-#define IMPLEMENT(x) tp_svc_channel_interface_media_signalling_implement_##x (\
- klass, gabble_media_channel_##x)
- IMPLEMENT(get_session_handlers);
-#undef IMPLEMENT
-}
-
-static void
-session_handler_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcMediaSessionHandlerClass *klass =
- (TpSvcMediaSessionHandlerClass *) g_iface;
-
-#define IMPLEMENT(x) tp_svc_media_session_handler_implement_##x (\
- klass, gabble_media_channel_##x)
- IMPLEMENT(error);
- IMPLEMENT(ready);
-#undef IMPLEMENT
-}
diff --git a/src/media-channel.h b/src/media-channel.h
deleted file mode 100644
index cbe488af2..000000000
--- a/src/media-channel.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * gabble-media-channel.h - Header for GabbleMediaChannel
- * Copyright (C) 2006 Collabora Ltd.
- * Copyright (C) 2006 Nokia Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __GABBLE_MEDIA_CHANNEL_H__
-#define __GABBLE_MEDIA_CHANNEL_H__
-
-#include <glib-object.h>
-
-#include <telepathy-glib/telepathy-glib.h>
-#include <telepathy-glib/properties-mixin.h>
-
-#include "presence.h"
-
-G_BEGIN_DECLS
-
-typedef struct _GabbleMediaChannel GabbleMediaChannel;
-typedef struct _GabbleMediaChannelPrivate GabbleMediaChannelPrivate;
-typedef struct _GabbleMediaChannelClass GabbleMediaChannelClass;
-
-struct _GabbleMediaChannelClass {
- GObjectClass parent_class;
-
- TpGroupMixinClass group_class;
- TpPropertiesMixinClass properties_class;
- TpDBusPropertiesMixinClass dbus_props_class;
-};
-
-struct _GabbleMediaChannel {
- GObject parent;
-
- TpGroupMixin group;
- TpPropertiesMixin properties;
-
- GabbleMediaChannelPrivate *priv;
-};
-
-GType gabble_media_channel_get_type (void);
-
-/* TYPE MACROS */
-#define GABBLE_TYPE_MEDIA_CHANNEL \
- (gabble_media_channel_get_type ())
-#define GABBLE_MEDIA_CHANNEL(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), GABBLE_TYPE_MEDIA_CHANNEL,\
- GabbleMediaChannel))
-#define GABBLE_MEDIA_CHANNEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), GABBLE_TYPE_MEDIA_CHANNEL,\
- GabbleMediaChannelClass))
-#define GABBLE_IS_MEDIA_CHANNEL(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), GABBLE_TYPE_MEDIA_CHANNEL))
-#define GABBLE_IS_MEDIA_CHANNEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), GABBLE_TYPE_MEDIA_CHANNEL))
-#define GABBLE_MEDIA_CHANNEL_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_MEDIA_CHANNEL, \
- GabbleMediaChannelClass))
-
-void gabble_media_channel_request_initial_streams (GabbleMediaChannel *chan,
- GFunc succeeded_cb,
- GFunc failed_cb,
- gpointer user_data);
-
-void gabble_media_channel_close (GabbleMediaChannel *self);
-
-G_END_DECLS
-
-#endif /* #ifndef __GABBLE_MEDIA_CHANNEL_H__*/
diff --git a/src/media-factory.c b/src/media-factory.c
index 85e4a1c46..7f7744c99 100644
--- a/src/media-factory.c
+++ b/src/media-factory.c
@@ -38,7 +38,6 @@
#include "debug.h"
#include "call-channel.h"
-#include "media-channel.h"
#include "namespaces.h"
#include "util.h"
@@ -72,29 +71,6 @@ media_channel_request_free (MediaChannelRequest *mcr)
g_slice_free (MediaChannelRequest, mcr);
}
-static void
-media_channel_request_succeeded_cb (MediaChannelRequest *mcr,
- GPtrArray *streams)
-{
- tp_channel_manager_emit_new_channel (mcr->self,
- mcr->channel, mcr->request_tokens);
-
- media_channel_request_free (mcr);
-}
-
-static void
-media_channel_request_failed_cb (MediaChannelRequest *mcr,
- GError *error)
-{
- GSList *l;
-
- for (l = mcr->request_tokens; l != NULL; l = g_slist_next (l))
- tp_channel_manager_emit_request_failed (mcr->self, l->data,
- error->domain, error->code, error->message);
-
- media_channel_request_free (mcr);
-}
-
static void channel_manager_iface_init (gpointer, gpointer);
static void caps_channel_manager_iface_init (gpointer, gpointer);
@@ -117,14 +93,10 @@ struct _GabbleMediaFactoryPrivate
GabbleConnection *conn;
gulong status_changed_id;
- GList *media_channels;
GList *call_channels;
GList *pending_call_channels;
guint channel_index;
- /* Whether or not we should use call channels for incoming calls */
- gboolean use_call_channels;
-
gboolean dispose_has_run;
};
@@ -159,7 +131,6 @@ gabble_media_factory_dispose (GObject *object)
priv->dispose_has_run = TRUE;
gabble_media_factory_close_all (fac);
- g_assert (priv->media_channels == NULL);
g_assert (priv->call_channels == NULL);
if (G_OBJECT_CLASS (gabble_media_factory_parent_class)->dispose)
@@ -231,76 +202,6 @@ gabble_media_factory_class_init (GabbleMediaFactoryClass *gabble_media_factory_c
}
-/**
- * media_channel_closed_cb:
- *
- * Signal callback for when a media channel is closed. Removes the references
- * that #GabbleMediaFactory holds to them.
- */
-static void
-media_channel_closed_cb (GabbleMediaChannel *chan, gpointer user_data)
-{
- GabbleMediaFactory *fac = GABBLE_MEDIA_FACTORY (user_data);
- GabbleMediaFactoryPrivate *priv = fac->priv;
-
- tp_channel_manager_emit_channel_closed_for_object (fac,
- TP_EXPORTABLE_CHANNEL (chan));
-
- DEBUG ("removing media channel %p with ref count %d",
- chan, G_OBJECT (chan)->ref_count);
-
- priv->media_channels = g_list_remove (priv->media_channels, chan);
- g_object_unref (chan);
-}
-
-/**
- * new_media_channel
- *
- * Creates a new empty GabbleMediaChannel.
- */
-static GabbleMediaChannel *
-new_media_channel (GabbleMediaFactory *fac,
- WockyJingleSession *sess,
- TpHandle maybe_peer,
- gboolean peer_in_rp,
- gboolean initial_audio,
- gboolean initial_video)
-{
- GabbleMediaFactoryPrivate *priv;
- TpBaseConnection *conn;
- GabbleMediaChannel *chan;
- gchar *object_path;
-
- g_assert (GABBLE_IS_MEDIA_FACTORY (fac));
-
- priv = fac->priv;
- conn = (TpBaseConnection *) priv->conn;
-
- object_path = g_strdup_printf ("%s/MediaChannel%u",
- tp_base_connection_get_object_path (conn), priv->channel_index);
- priv->channel_index += 1;
-
- chan = g_object_new (GABBLE_TYPE_MEDIA_CHANNEL,
- "connection", priv->conn,
- "object-path", object_path,
- "session", sess,
- "initial-peer", maybe_peer,
- "peer-in-rp", peer_in_rp,
- "initial-audio", initial_audio,
- "initial-video", initial_video,
- NULL);
-
- DEBUG ("object path %s", object_path);
-
- g_signal_connect (chan, "closed", (GCallback) media_channel_closed_cb, fac);
-
- priv->media_channels = g_list_prepend (priv->media_channels, chan);
-
- g_free (object_path);
-
- return chan;
-}
-
static void
call_channel_closed_cb (GabbleCallChannel *chan, gpointer user_data)
{
@@ -423,11 +324,6 @@ gabble_media_factory_close_all (GabbleMediaFactory *fac)
DEBUG ("closing channels");
/* Close will cause the channel to be removed from the list indirectly..*/
- while (priv->media_channels != NULL)
- gabble_media_channel_close (
- GABBLE_MEDIA_CHANNEL (priv->media_channels->data));
-
- /* Close will cause the channel to be removed from the list indirectly..*/
while (priv->call_channels != NULL)
tp_base_channel_close (TP_BASE_CHANNEL (priv->call_channels->data));
@@ -464,43 +360,10 @@ new_jingle_session_cb (GabbleJingleMint *jm,
peer = tp_handle_ensure (contacts, wocky_jingle_session_get_peer_jid (sess),
NULL, NULL);
- if (self->priv->use_call_channels)
- {
- new_call_channel (self, sess, peer,
- FALSE, NULL,
- FALSE, NULL,
- NULL);
- }
- else
- {
- GabbleMediaChannel *chan = new_media_channel (self, sess,
- peer,
- FALSE, FALSE, FALSE);
- GList *cs;
-
- /* FIXME: we need this detection to properly adjust nat-traversal on
- * the channel. We hope all contents will have the same transport... */
- cs = wocky_jingle_session_get_contents (sess);
-
- if (cs != NULL)
- {
- WockyJingleContent *c = cs->data;
- gchar *ns;
-
- g_object_get (c, "transport-ns", &ns, NULL);
-
- if (!tp_strdiff (ns, NS_JINGLE_TRANSPORT_ICEUDP))
- g_object_set (chan, "nat-traversal", "ice-udp", NULL);
- else if (!tp_strdiff (ns, NS_JINGLE_TRANSPORT_RAWUDP))
- g_object_set (chan, "nat-traversal", "none", NULL);
-
- g_free (ns);
- g_list_free (cs);
- }
-
- tp_channel_manager_emit_new_channel (self,
- TP_EXPORTABLE_CHANNEL (chan), NULL);
- }
+ new_call_channel (self, sess, peer,
+ FALSE, NULL,
+ FALSE, NULL,
+ NULL);
}
static void
@@ -550,9 +413,6 @@ gabble_media_factory_foreach_channel (TpChannelManager *manager,
GabbleMediaFactoryPrivate *priv = fac->priv;
GList *l;
- for (l = priv->media_channels; l != NULL; l = g_list_next (l))
- foreach (TP_EXPORTABLE_CHANNEL (l->data), user_data);
-
for (l = priv->call_channels; l != NULL; l = g_list_next (l))
foreach (TP_EXPORTABLE_CHANNEL (l->data), user_data);
}
@@ -563,38 +423,6 @@ static const gchar * const media_channel_fixed_properties[] = {
NULL
};
-/* If you change this at all, you'll probably also need to change both_allowed
- * and video_allowed */
-static const gchar * const named_channel_allowed_properties[] = {
- TP_PROP_CHANNEL_TARGET_HANDLE,
- TP_PROP_CHANNEL_TARGET_ID,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO,
- NULL
-};
-
-static const gchar * const * both_allowed =
- named_channel_allowed_properties + 2;
-
-static const gchar * const audio_allowed[] = {
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_IMMUTABLE_STREAMS,
- NULL
-};
-
-static const gchar * const video_allowed[] = {
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_IMMUTABLE_STREAMS,
- NULL
-};
-
-static const gchar * const both_allowed_immutable[] = {
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_IMMUTABLE_STREAMS,
- NULL
-};
-
static const gchar * const call_channel_allowed_properties[] = {
TP_PROP_CHANNEL_TARGET_HANDLE,
TP_PROP_CHANNEL_TARGET_ID,
@@ -648,21 +476,6 @@ gabble_media_factory_call_channel_allowed_properties (void)
}
static GHashTable *
-gabble_media_factory_streamed_media_channel_class (void)
-{
- GHashTable *table = tp_asv_new (
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT,
- TP_HANDLE_TYPE_CONTACT,
- NULL);
-
- tp_asv_set_static_string (table,
- TP_PROP_CHANNEL_CHANNEL_TYPE,
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA);
-
- return table;
-}
-
-static GHashTable *
gabble_media_factory_call_channel_class (void)
{
GHashTable *table = tp_asv_new (
@@ -681,13 +494,7 @@ gabble_media_factory_type_foreach_channel_class (GType type,
TpChannelManagerTypeChannelClassFunc func,
gpointer user_data)
{
- GHashTable *table = gabble_media_factory_streamed_media_channel_class ();
-
- func (type, table, named_channel_allowed_properties, user_data);
-
- g_hash_table_unref (table);
-
- table = gabble_media_factory_call_channel_class ();
+ GHashTable *table = gabble_media_factory_call_channel_class ();
func (type, table, call_channel_allowed_properties, user_data);
@@ -697,154 +504,11 @@ gabble_media_factory_type_foreach_channel_class (GType type,
typedef enum
{
- METHOD_REQUEST,
METHOD_CREATE,
METHOD_ENSURE,
} RequestMethod;
static gboolean
-gabble_media_factory_requestotron (TpChannelManager *manager,
- gpointer request_token,
- GHashTable *request_properties,
- RequestMethod method)
-{
- GabbleMediaFactory *self = GABBLE_MEDIA_FACTORY (manager);
- GabbleMediaFactoryPrivate *priv = self->priv;
- TpHandleType handle_type;
- TpHandle handle;
- GabbleMediaChannel *channel = NULL;
- GError *error = NULL;
- gboolean require_target_handle, add_peer_to_remote_pending;
- gboolean initial_audio, initial_video;
-
- /* Supported modes of operation:
- * - RequestChannel(None, 0):
- * channel is anonymous;
- * caller may optionally use AddMembers to add the peer to RemotePending
- * without sending them any XML;
- * caller uses RequestStreams to set the peer and start the call.
- * - RequestChannel(Contact, n) where n != 0:
- * channel has TargetHandle=n;
- * n is in remote pending;
- * call is started when caller calls RequestStreams.
- * - CreateChannel({THT: Contact, TH: n}):
- * channel has TargetHandle=n
- * n is not in the group interface at all
- * call is started when caller calls RequestStreams.
- * - EnsureChannel({THT: Contact, TH: n}):
- * look for a channel whose peer is n, and return that if found with
- * whatever properties and group membership it has;
- * otherwise the same as into CreateChannel
- */
- switch (method)
- {
- case METHOD_REQUEST:
- require_target_handle = FALSE;
- add_peer_to_remote_pending = TRUE;
- break;
- case METHOD_CREATE:
- case METHOD_ENSURE:
- require_target_handle = TRUE;
- add_peer_to_remote_pending = FALSE;
- break;
- default:
- g_assert_not_reached ();
- }
-
- if (tp_strdiff (tp_asv_get_string (request_properties,
- TP_PROP_CHANNEL_CHANNEL_TYPE),
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA))
- return FALSE;
-
- handle_type = tp_asv_get_uint32 (request_properties,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL);
-
- handle = tp_asv_get_uint32 (request_properties,
- TP_PROP_CHANNEL_TARGET_HANDLE, NULL);
-
- initial_audio = tp_asv_get_boolean (request_properties,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO, NULL);
- initial_video = tp_asv_get_boolean (request_properties,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO, NULL);
-
- switch (handle_type)
- {
- case TP_HANDLE_TYPE_NONE:
- /* already checked by TpBaseConnection */
- g_assert (handle == 0);
-
- if (require_target_handle)
- {
- g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
- "A valid Contact handle must be provided when requesting a media "
- "channel");
- goto error;
- }
-
- if (tp_channel_manager_asv_has_unknown_properties (request_properties,
- media_channel_fixed_properties, anon_channel_allowed_properties,
- &error))
- goto error;
-
- channel = new_media_channel (self, NULL, 0, FALSE, FALSE, FALSE);
- break;
-
- case TP_HANDLE_TYPE_CONTACT:
- /* validity already checked by TpBaseConnection */
- g_assert (handle != 0);
-
- if (tp_channel_manager_asv_has_unknown_properties (request_properties,
- media_channel_fixed_properties, named_channel_allowed_properties,
- &error))
- goto error;
-
- if (method == METHOD_ENSURE)
- {
- GList *l;
- TpHandle peer = 0;
-
- for (l = priv->media_channels; l != NULL; l = g_list_next (l))
- {
- channel = GABBLE_MEDIA_CHANNEL (l->data);
- g_object_get (channel, "peer", &peer, NULL);
-
- if (peer == handle)
- {
- /* Per the spec, we ignore InitialAudio and InitialVideo when
- * looking for an existing channel.
- */
- tp_channel_manager_emit_request_already_satisfied (self,
- request_token, TP_EXPORTABLE_CHANNEL (channel));
- return TRUE;
- }
- }
- }
-
- channel = new_media_channel (self, NULL, handle,
- add_peer_to_remote_pending, initial_audio, initial_video);
- break;
- default:
- return FALSE;
- }
-
- g_assert (channel != NULL);
-
- gabble_media_channel_request_initial_streams (channel,
- (GFunc) media_channel_request_succeeded_cb,
- (GFunc) media_channel_request_failed_cb,
- media_channel_request_new (self,
- TP_EXPORTABLE_CHANNEL (channel), request_token));
-
- return TRUE;
-
-error:
- tp_channel_manager_emit_request_failed (self, request_token,
- error->domain, error->code, error->message);
- g_error_free (error);
- return TRUE;
-}
-
-static gboolean
gabble_media_factory_create_call (TpChannelManager *manager,
gpointer request_token,
GHashTable *request_properties,
@@ -856,6 +520,10 @@ gabble_media_factory_create_call (TpChannelManager *manager,
gboolean initial_audio, initial_video;
const gchar *initial_audio_name, *initial_video_name;
+ if (tp_strdiff (tp_asv_get_string (request_properties,
+ TP_PROP_CHANNEL_CHANNEL_TYPE),
+ TP_IFACE_CHANNEL_TYPE_CALL))
+ return FALSE;
DEBUG ("Creating a new call channel");
@@ -947,27 +615,11 @@ error:
}
static gboolean
-gabble_media_factory_request_channel (TpChannelManager *manager,
- gpointer request_token,
- GHashTable *request_properties)
-{
- return gabble_media_factory_requestotron (manager, request_token,
- request_properties, METHOD_REQUEST);
-}
-
-
-static gboolean
gabble_media_factory_create_channel (TpChannelManager *manager,
gpointer request_token,
GHashTable *request_properties)
{
- if (!tp_strdiff (tp_asv_get_string (request_properties,
- TP_PROP_CHANNEL_CHANNEL_TYPE),
- TP_IFACE_CHANNEL_TYPE_CALL))
- return gabble_media_factory_create_call (manager, request_token,
- request_properties, METHOD_CREATE);
- else
- return gabble_media_factory_requestotron (manager, request_token,
+ return gabble_media_factory_create_call (manager, request_token,
request_properties, METHOD_CREATE);
}
@@ -977,14 +629,8 @@ gabble_media_factory_ensure_channel (TpChannelManager *manager,
gpointer request_token,
GHashTable *request_properties)
{
- if (!tp_strdiff (tp_asv_get_string (request_properties,
- TP_PROP_CHANNEL_CHANNEL_TYPE),
- TP_IFACE_CHANNEL_TYPE_CALL))
- return gabble_media_factory_create_call (manager, request_token,
- request_properties, METHOD_ENSURE);
- else
- return gabble_media_factory_requestotron (manager, request_token,
- request_properties, METHOD_ENSURE);
+ return gabble_media_factory_create_call (manager, request_token,
+ request_properties, METHOD_ENSURE);
}
@@ -997,7 +643,6 @@ channel_manager_iface_init (gpointer g_iface,
iface->foreach_channel = gabble_media_factory_foreach_channel;
iface->type_foreach_channel_class =
gabble_media_factory_type_foreach_channel_class;
- iface->request_channel = gabble_media_factory_request_channel;
iface->create_channel = gabble_media_factory_create_channel;
iface->ensure_channel = gabble_media_factory_ensure_channel;
}
@@ -1059,12 +704,21 @@ gabble_media_factory_add_caps (GabbleCapabilitySet *caps,
}
}
+typedef enum {
+ MEDIA_CAPABILITY_AUDIO = 1,
+ MEDIA_CAPABILITY_VIDEO = 2,
+ MEDIA_CAPABILITY_NAT_TRAVERSAL_STUN = 4,
+ MEDIA_CAPABILITY_NAT_TRAVERSAL_GTALK_P2P = 8,
+ MEDIA_CAPABILITY_NAT_TRAVERSAL_ICE_UDP = 16,
+ MEDIA_CAPABILITY_IMMUTABLE_STREAMS = 32,
+} MediaCapabilities;
+
/* The switch in gabble_media_factory_get_contact_caps needs to be kept in
* sync with the possible returns from this function. */
-TpChannelMediaCapabilities
+static MediaCapabilities
_gabble_media_factory_caps_to_typeflags (const GabbleCapabilitySet *caps)
{
- TpChannelMediaCapabilities typeflags = 0;
+ MediaCapabilities typeflags = 0;
gboolean has_a_transport, just_google, one_media_type;
has_a_transport = gabble_capability_set_has_one (caps,
@@ -1073,12 +727,12 @@ _gabble_media_factory_caps_to_typeflags (const GabbleCapabilitySet *caps)
if (has_a_transport &&
gabble_capability_set_has_one (caps,
gabble_capabilities_get_any_audio ()))
- typeflags |= TP_CHANNEL_MEDIA_CAPABILITY_AUDIO;
+ typeflags |= MEDIA_CAPABILITY_AUDIO;
if (has_a_transport &&
gabble_capability_set_has_one (caps,
gabble_capabilities_get_any_video ()))
- typeflags |= TP_CHANNEL_MEDIA_CAPABILITY_VIDEO;
+ typeflags |= MEDIA_CAPABILITY_VIDEO;
/* The checks below are an intentional asymmetry with the function going the
* other way - we don't require the other end to advertise the GTalk-P2P
@@ -1086,10 +740,10 @@ _gabble_media_factory_caps_to_typeflags (const GabbleCapabilitySet *caps)
* Having Google voice implied Google session and GTalk-P2P. */
if (gabble_capability_set_has (caps, NS_GOOGLE_FEAT_VOICE))
- typeflags |= TP_CHANNEL_MEDIA_CAPABILITY_AUDIO;
+ typeflags |= MEDIA_CAPABILITY_AUDIO;
if (gabble_capability_set_has (caps, NS_GOOGLE_FEAT_VIDEO))
- typeflags |= TP_CHANNEL_MEDIA_CAPABILITY_VIDEO;
+ typeflags |= MEDIA_CAPABILITY_VIDEO;
just_google =
gabble_capability_set_has_one (caps,
@@ -1097,46 +751,29 @@ _gabble_media_factory_caps_to_typeflags (const GabbleCapabilitySet *caps)
!gabble_capability_set_has_one (caps,
gabble_capabilities_get_any_jingle_av ());
- one_media_type = (typeflags == TP_CHANNEL_MEDIA_CAPABILITY_AUDIO)
- || (typeflags == TP_CHANNEL_MEDIA_CAPABILITY_VIDEO);
+ one_media_type = (typeflags == MEDIA_CAPABILITY_AUDIO)
+ || (typeflags == MEDIA_CAPABILITY_VIDEO);
if (just_google || one_media_type)
- typeflags |= TP_CHANNEL_MEDIA_CAPABILITY_IMMUTABLE_STREAMS;
+ typeflags |= MEDIA_CAPABILITY_IMMUTABLE_STREAMS;
return typeflags;
}
-void
-_gabble_media_factory_typeflags_to_caps (TpChannelMediaCapabilities flags,
- GabbleCapabilitySet *caps)
-{
- DEBUG ("adding Jingle caps %u", flags);
-
- /* The client name just appears in a debug message, so use something that
- * won't, in practice, clash with any client that uses ContactCapabilities */
- gabble_media_factory_add_caps (caps, "<legacy Capabilities>",
- (flags & TP_CHANNEL_MEDIA_CAPABILITY_AUDIO) != 0,
- (flags & TP_CHANNEL_MEDIA_CAPABILITY_VIDEO) != 0,
- (flags & TP_CHANNEL_MEDIA_CAPABILITY_NAT_TRAVERSAL_GTALK_P2P) != 0,
- (flags & TP_CHANNEL_MEDIA_CAPABILITY_NAT_TRAVERSAL_ICE_UDP) != 0,
- TRUE /* assume we have H.264 for now */);
-}
-
static void
gabble_media_factory_get_contact_caps (GabbleCapsChannelManager *manager,
TpHandle handle,
const GabbleCapabilitySet *caps,
GPtrArray *arr)
{
- TpChannelMediaCapabilities typeflags =
+ MediaCapabilities typeflags =
_gabble_media_factory_caps_to_typeflags (caps);
GValueArray *va;
- const gchar * const *streamed_media_allowed;
const gchar * const *call_allowed;
- typeflags &= (TP_CHANNEL_MEDIA_CAPABILITY_AUDIO |
- TP_CHANNEL_MEDIA_CAPABILITY_VIDEO |
- TP_CHANNEL_MEDIA_CAPABILITY_IMMUTABLE_STREAMS);
+ typeflags &= (MEDIA_CAPABILITY_AUDIO |
+ MEDIA_CAPABILITY_VIDEO |
+ MEDIA_CAPABILITY_IMMUTABLE_STREAMS);
/* This switch is over the values of several bits from a
* bitfield-represented-as-an-enum, simultaneously, which upsets gcc-4.5;
@@ -1148,28 +785,24 @@ gabble_media_factory_get_contact_caps (GabbleCapsChannelManager *manager,
case 0:
return;
- case TP_CHANNEL_MEDIA_CAPABILITY_AUDIO
- | TP_CHANNEL_MEDIA_CAPABILITY_IMMUTABLE_STREAMS:
- streamed_media_allowed = audio_allowed;
+ case MEDIA_CAPABILITY_AUDIO
+ | MEDIA_CAPABILITY_IMMUTABLE_STREAMS:
call_allowed = call_audio_allowed;
break;
- case TP_CHANNEL_MEDIA_CAPABILITY_VIDEO
- | TP_CHANNEL_MEDIA_CAPABILITY_IMMUTABLE_STREAMS:
- streamed_media_allowed = video_allowed;
+ case MEDIA_CAPABILITY_VIDEO
+ | MEDIA_CAPABILITY_IMMUTABLE_STREAMS:
call_allowed = call_video_allowed;
break;
- case TP_CHANNEL_MEDIA_CAPABILITY_AUDIO
- | TP_CHANNEL_MEDIA_CAPABILITY_VIDEO: /* both */
- streamed_media_allowed = both_allowed;
+ case MEDIA_CAPABILITY_AUDIO
+ | MEDIA_CAPABILITY_VIDEO: /* both */
call_allowed = call_both_allowed;
break;
- case TP_CHANNEL_MEDIA_CAPABILITY_AUDIO /* both but immutable */
- | TP_CHANNEL_MEDIA_CAPABILITY_VIDEO
- | TP_CHANNEL_MEDIA_CAPABILITY_IMMUTABLE_STREAMS:
- streamed_media_allowed = both_allowed_immutable;
+ case MEDIA_CAPABILITY_AUDIO /* both but immutable */
+ | MEDIA_CAPABILITY_VIDEO
+ | MEDIA_CAPABILITY_IMMUTABLE_STREAMS:
call_allowed = call_both_allowed_immutable;
break;
@@ -1177,18 +810,6 @@ gabble_media_factory_get_contact_caps (GabbleCapsChannelManager *manager,
g_assert_not_reached ();
}
- /* Streamed Media channel */
- va = g_value_array_new (2);
- g_value_array_append (va, NULL);
- g_value_array_append (va, NULL);
- g_value_init (va->values + 0, TP_HASH_TYPE_CHANNEL_CLASS);
- g_value_init (va->values + 1, G_TYPE_STRV);
- g_value_take_boxed (va->values + 0,
- gabble_media_factory_streamed_media_channel_class ());
- g_value_set_static_boxed (va->values + 1, streamed_media_allowed);
-
- g_ptr_array_add (arr, va);
-
/* Call channel */
va = g_value_array_new (2);
g_value_array_append (va, NULL);
@@ -1210,25 +831,18 @@ gabble_media_factory_represent_client (GabbleCapsChannelManager *manager,
GabbleCapabilitySet *cap_set,
GPtrArray *data_forms)
{
- static GQuark q_gtalk_p2p = 0, q_ice_udp = 0, q_h264 = 0;
static GQuark qc_gtalk_p2p = 0, qc_ice_udp = 0, qc_h264 = 0;
gboolean gtalk_p2p = FALSE, h264 = FALSE, audio = FALSE, video = FALSE,
ice_udp = FALSE;
guint i;
/* One-time initialization - turn the tokens we care about into quarks */
- if (G_UNLIKELY (q_gtalk_p2p == 0))
+ if (G_UNLIKELY (qc_gtalk_p2p == 0))
{
- q_gtalk_p2p = g_quark_from_static_string (
- TP_IFACE_CHANNEL_INTERFACE_MEDIA_SIGNALLING "/gtalk-p2p");
qc_gtalk_p2p = g_quark_from_static_string (
TP_IFACE_CHANNEL_TYPE_CALL "/gtalk-p2p");
- q_ice_udp = g_quark_from_static_string (
- TP_IFACE_CHANNEL_INTERFACE_MEDIA_SIGNALLING "/ice-udp");
qc_ice_udp = g_quark_from_static_string (
TP_IFACE_CHANNEL_TYPE_CALL "/ice-udp");
- q_h264 = g_quark_from_static_string (
- TP_IFACE_CHANNEL_INTERFACE_MEDIA_SIGNALLING "/video/h264");
qc_h264 = g_quark_from_static_string (
TP_IFACE_CHANNEL_TYPE_CALL "/video/h264");
}
@@ -1244,9 +858,9 @@ gabble_media_factory_represent_client (GabbleCapsChannelManager *manager,
GQuark quark;
gboolean *cap;
} q2cap[] = {
- { q_gtalk_p2p, &gtalk_p2p }, { qc_gtalk_p2p, &gtalk_p2p },
- { q_ice_udp, &ice_udp }, { qc_ice_udp, &ice_udp },
- { q_h264, &h264 }, { qc_h264, &h264 },
+ { qc_gtalk_p2p, &gtalk_p2p },
+ { qc_ice_udp, &ice_udp },
+ { qc_h264, &h264 },
{ 0, NULL },
};
@@ -1273,27 +887,12 @@ gabble_media_factory_represent_client (GabbleCapsChannelManager *manager,
if (tp_strdiff (tp_asv_get_string (filter,
TP_PROP_CHANNEL_CHANNEL_TYPE),
- TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA)
- && tp_strdiff (tp_asv_get_string (filter,
- TP_PROP_CHANNEL_CHANNEL_TYPE),
TP_IFACE_CHANNEL_TYPE_CALL))
{
/* not interesting to this channel manager */
continue;
}
-#ifdef ENABLE_CHANNEL_TYPE_CALL
- /* If there is a handler that can support Call channels, use those for
- * incoming channels */
- if (!tp_strdiff (tp_asv_get_string (filter,
- TP_PROP_CHANNEL_CHANNEL_TYPE),
- TP_IFACE_CHANNEL_TYPE_CALL))
- {
- GabbleMediaFactory *self = GABBLE_MEDIA_FACTORY (manager);
- self->priv->use_call_channels = TRUE;
- }
-#endif
-
if (tp_asv_lookup (filter, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE)
!= NULL &&
tp_asv_get_uint32 (filter, TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
@@ -1306,14 +905,10 @@ gabble_media_factory_represent_client (GabbleCapsChannelManager *manager,
}
if (tp_asv_get_boolean (filter,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_AUDIO, NULL)
- || tp_asv_get_boolean (filter,
TP_PROP_CHANNEL_TYPE_CALL_INITIAL_AUDIO, NULL))
audio = TRUE;
if (tp_asv_get_boolean (filter,
- TP_PROP_CHANNEL_TYPE_STREAMED_MEDIA_INITIAL_VIDEO, NULL)
- || tp_asv_get_boolean (filter,
TP_PROP_CHANNEL_TYPE_CALL_INITIAL_VIDEO, NULL))
video = TRUE;
diff --git a/src/media-factory.h b/src/media-factory.h
index 98007f60c..b02b4b575 100644
--- a/src/media-factory.h
+++ b/src/media-factory.h
@@ -22,7 +22,10 @@
#include <glib-object.h>
-#include "media-channel.h"
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#include "gabble/capabilities-set.h"
G_BEGIN_DECLS
@@ -59,19 +62,6 @@ GType gabble_media_factory_get_type (void);
(G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_MEDIA_FACTORY,\
GabbleMediaFactoryClass))
-const gchar * _gabble_media_factory_allocate_sid (GabbleMediaFactory *fac,
- GabbleMediaChannel *chan);
-const gchar * _gabble_media_factory_register_sid (GabbleMediaFactory *fac,
- const gchar *sid, GabbleMediaChannel *chan);
-void _gabble_media_factory_free_sid (GabbleMediaFactory *fac,
- const gchar *sid);
-
-void _gabble_media_factory_typeflags_to_caps (TpChannelMediaCapabilities flags,
- GabbleCapabilitySet *caps);
-
-TpChannelMediaCapabilities
-_gabble_media_factory_caps_to_typeflags (const GabbleCapabilitySet *caps);
-
const gchar * const * gabble_media_factory_call_channel_allowed_properties (
void);
diff --git a/src/media-stream.c b/src/media-stream.c
deleted file mode 100644
index 426aa8a20..000000000
--- a/src/media-stream.c
+++ /dev/null
@@ -1,2085 +0,0 @@
-/*
- * gabble-media-stream.c - Source for GabbleMediaStream
- * Copyright © 2006-2009 Collabora Ltd.
- * Copyright © 2006-2009 Nokia Corporation
- * @author Ole Andre Vadla Ravnaas <ole.andre.ravnaas@collabora.co.uk>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include "media-stream.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <dbus/dbus-glib.h>
-
-#include <telepathy-glib/telepathy-glib.h>
-#include <telepathy-glib/telepathy-glib-dbus.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#include "connection.h"
-#include "debug.h"
-#include "gabble-signals-marshal.h"
-#include "media-channel.h"
-#include "namespaces.h"
-#include "util.h"
-
-static void stream_handler_iface_init (gpointer, gpointer);
-
-G_DEFINE_TYPE_WITH_CODE(GabbleMediaStream,
- gabble_media_stream,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_MEDIA_STREAM_HANDLER,
- stream_handler_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
- )
-
-/* signal enum */
-enum
-{
- ERROR,
- UNHOLD_FAILED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-/* properties */
-enum
-{
- PROP_DBUS_DAEMON = 1,
- PROP_OBJECT_PATH,
- PROP_NAME,
- PROP_ID,
- PROP_MEDIA_TYPE,
- PROP_CONNECTION_STATE,
- PROP_READY,
- PROP_PLAYING,
- PROP_COMBINED_DIRECTION,
- PROP_LOCAL_HOLD,
- PROP_CONTENT,
- PROP_STUN_SERVERS,
- PROP_RELAY_INFO,
- PROP_NAT_TRAVERSAL,
- PROP_CREATED_LOCALLY,
- LAST_PROPERTY
-};
-
-/* private structure */
-
-struct _GabbleMediaStreamPrivate
-{
- WockyJingleContent *content;
-
- TpDBusDaemon *dbus_daemon;
- gchar *object_path;
- guint id;
- guint media_type;
-
- gboolean local_codecs_set;
-
- /* Whether we're waiting for a codec intersection from the streaming
- * implementation. If FALSE, SupportedCodecs is a no-op.
- */
- gboolean awaiting_intersection;
-
- GValue local_rtp_hdrexts;
- GValue local_feedback_messages;
-
- GValue remote_codecs;
- GValue remote_rtp_hdrexts;
- GValue remote_feedback_messages;
- GValue remote_candidates;
-
- guint remote_candidate_count;
-
- /* source ID for initial codecs/candidates getter */
- gulong initial_getter_id;
-
- gchar *nat_traversal;
- /* GPtrArray(GValueArray(STRING, UINT)) */
- GPtrArray *stun_servers;
- /* GPtrArray(GHashTable(string => GValue)) */
- GPtrArray *relay_info;
-
- gboolean on_hold;
-
- /* These are really booleans, but gboolean is signed. Thanks, GLib */
- unsigned closed:1;
- unsigned dispose_has_run:1;
- unsigned local_hold:1;
- unsigned ready:1;
- unsigned sending:1;
- unsigned created_locally:1;
-};
-
-static void push_remote_media_description (GabbleMediaStream *stream);
-static void push_remote_candidates (GabbleMediaStream *stream);
-static void push_playing (GabbleMediaStream *stream);
-static void push_sending (GabbleMediaStream *stream);
-
-static void new_remote_candidates_cb (WockyJingleContent *content,
- GList *clist, GabbleMediaStream *stream);
-static void new_remote_media_description_cb (WockyJingleContent *content,
- WockyJingleMediaDescription *md, GabbleMediaStream *stream);
-static void content_state_changed_cb (WockyJingleContent *c,
- GParamSpec *pspec, GabbleMediaStream *stream);
-static void content_senders_changed_cb (WockyJingleContent *c,
- GParamSpec *pspec, GabbleMediaStream *stream);
-static void remote_state_changed_cb (WockyJingleSession *session,
- GabbleMediaStream *stream);
-static void content_removed_cb (WockyJingleContent *content,
- GabbleMediaStream *stream);
-static void update_direction (GabbleMediaStream *stream, WockyJingleContent *c);
-static void update_sending (GabbleMediaStream *stream, gboolean start_sending);
-
-GabbleMediaStream *
-gabble_media_stream_new (
- TpDBusDaemon *dbus_daemon,
- const gchar *object_path,
- WockyJingleContent *content,
- const gchar *name,
- guint id,
- const gchar *nat_traversal,
- const GPtrArray *relay_info,
- gboolean local_hold)
-{
- GPtrArray *empty = NULL;
- GabbleMediaStream *result;
-
- g_return_val_if_fail (WOCKY_IS_JINGLE_MEDIA_RTP (content), NULL);
-
- if (relay_info == NULL)
- {
- empty = g_ptr_array_sized_new (0);
- relay_info = empty;
- }
-
- result = g_object_new (GABBLE_TYPE_MEDIA_STREAM,
- "dbus-daemon", dbus_daemon,
- "object-path", object_path,
- "content", content,
- "name", name,
- "id", id,
- "nat-traversal", nat_traversal,
- "relay-info", relay_info,
- "local-hold", local_hold,
- NULL);
-
- if (empty != NULL)
- g_ptr_array_unref (empty);
-
- return result;
-}
-
-TpMediaStreamType
-gabble_media_stream_get_media_type (GabbleMediaStream *self)
-{
- return self->priv->media_type;
-}
-
-static void
-gabble_media_stream_init (GabbleMediaStream *self)
-{
- GabbleMediaStreamPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- GABBLE_TYPE_MEDIA_STREAM, GabbleMediaStreamPrivate);
- GType candidate_list_type =
- TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE_LIST;
- GType codec_list_type =
- TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CODEC_LIST;
- GType rtp_hdrext_list_type = TP_ARRAY_TYPE_RTP_HEADER_EXTENSIONS_LIST;
- GType fb_msg_map_type = TP_HASH_TYPE_RTCP_FEEDBACK_MESSAGE_MAP;
-
- self->priv = priv;
-
- g_value_init (&priv->local_rtp_hdrexts, rtp_hdrext_list_type);
- g_value_init (&priv->local_feedback_messages, fb_msg_map_type);
-
- g_value_init (&priv->remote_codecs, codec_list_type);
- g_value_take_boxed (&priv->remote_codecs,
- dbus_g_type_specialized_construct (codec_list_type));
-
- g_value_init (&priv->remote_rtp_hdrexts, rtp_hdrext_list_type);
- g_value_take_boxed (&priv->remote_rtp_hdrexts,
- dbus_g_type_specialized_construct (rtp_hdrext_list_type));
-
- g_value_init (&priv->remote_feedback_messages, fb_msg_map_type);
- g_value_take_boxed (&priv->remote_feedback_messages,
- dbus_g_type_specialized_construct (fb_msg_map_type));
-
- g_value_init (&priv->remote_candidates, candidate_list_type);
- g_value_take_boxed (&priv->remote_candidates,
- dbus_g_type_specialized_construct (candidate_list_type));
-
- priv->stun_servers = g_ptr_array_sized_new (1);
-}
-
-static gboolean
-_get_initial_codecs_and_candidates (gpointer user_data)
-{
- GabbleMediaStream *stream = GABBLE_MEDIA_STREAM (user_data);
- GabbleMediaStreamPrivate *priv = stream->priv;
- WockyJingleMediaDescription *md;
-
- priv->initial_getter_id = 0;
-
- /* we can immediately get the codecs if we're responder */
- md = wocky_jingle_media_rtp_get_remote_media_description (
- WOCKY_JINGLE_MEDIA_RTP (priv->content));
- if (md != NULL)
- new_remote_media_description_cb (priv->content, md, stream);
-
- /* if any candidates arrived before idle loop had the chance to excute
- * us (e.g. specified in session-initiate/content-add), we don't want to
- * miss them */
- new_remote_candidates_cb (priv->content,
- wocky_jingle_content_get_remote_candidates (priv->content), stream);
-
- return FALSE;
-}
-
-static GObject *
-gabble_media_stream_constructor (GType type, guint n_props,
- GObjectConstructParam *props)
-{
- GObject *obj;
- GabbleMediaStream *stream;
- GabbleMediaStreamPrivate *priv;
- WockyJingleFactory *jf;
- GList *stun_servers;
-
- /* call base class constructor */
- obj = G_OBJECT_CLASS (gabble_media_stream_parent_class)->
- constructor (type, n_props, props);
- stream = GABBLE_MEDIA_STREAM (obj);
- priv = stream->priv;
-
- g_assert (priv->content != NULL);
-
- /* STUN servers are needed as soon as the stream appears, so there's little
- * point in waiting for them - either they've already been resolved, or
- * we're too late to use them for this stream */
- jf = wocky_jingle_session_get_factory (priv->content->session);
- stun_servers = wocky_jingle_info_get_stun_servers (
- wocky_jingle_factory_get_jingle_info (jf));
- while (stun_servers != NULL)
- {
- WockyStunServer *stun_server = stun_servers->data;
- GValueArray *va = tp_value_array_build (2,
- G_TYPE_STRING, stun_server->address,
- G_TYPE_UINT, (guint) stun_server->port,
- G_TYPE_INVALID);
-
- g_ptr_array_add (priv->stun_servers, va);
-
- stun_servers = g_list_delete_link (stun_servers, stun_servers);
- }
-
- /* go for the bus */
- g_assert (priv->dbus_daemon != NULL);
- tp_dbus_daemon_register_object (priv->dbus_daemon, priv->object_path, obj);
-
- update_direction (stream, priv->content);
-
- /* MediaStream is created as soon as WockyJingleContent is
- * created, but we want to let it parse the initiation (if
- * initiated by remote end) before we pick up initial
- * codecs and candidates.
- * FIXME: add API for ordering IQs rather than using g_idle_add.
- */
- priv->initial_getter_id =
- g_idle_add (_get_initial_codecs_and_candidates, stream);
-
- if (priv->created_locally)
- {
- g_object_set (stream, "combined-direction",
- MAKE_COMBINED_DIRECTION (TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- 0), NULL);
- }
- else
- {
- priv->awaiting_intersection = TRUE;
- }
-
- return obj;
-}
-
-static void
-gabble_media_stream_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GabbleMediaStream *stream = GABBLE_MEDIA_STREAM (object);
- GabbleMediaStreamPrivate *priv = stream->priv;
-
- switch (property_id) {
- case PROP_DBUS_DAEMON:
- g_value_set_object (value, priv->dbus_daemon);
- break;
- case PROP_OBJECT_PATH:
- g_value_set_string (value, priv->object_path);
- break;
- case PROP_NAME:
- g_value_set_string (value, stream->name);
- break;
- case PROP_ID:
- g_value_set_uint (value, priv->id);
- break;
- case PROP_MEDIA_TYPE:
- g_value_set_uint (value, priv->media_type);
- break;
- case PROP_CONNECTION_STATE:
- g_value_set_uint (value, stream->connection_state);
- break;
- case PROP_READY:
- g_value_set_boolean (value, priv->ready);
- break;
- case PROP_PLAYING:
- g_value_set_boolean (value, stream->playing);
- break;
- case PROP_COMBINED_DIRECTION:
- g_value_set_uint (value, stream->combined_direction);
- break;
- case PROP_LOCAL_HOLD:
- g_value_set_boolean (value, priv->local_hold);
- break;
- case PROP_CONTENT:
- g_value_set_object (value, priv->content);
- break;
- case PROP_STUN_SERVERS:
- g_value_set_boxed (value, priv->stun_servers);
- break;
- case PROP_NAT_TRAVERSAL:
- g_value_set_string (value, priv->nat_traversal);
- break;
- case PROP_CREATED_LOCALLY:
- g_value_set_boolean (value, priv->created_locally);
- break;
- case PROP_RELAY_INFO:
- g_value_set_boxed (value, priv->relay_info);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-gabble_media_stream_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GabbleMediaStream *stream = GABBLE_MEDIA_STREAM (object);
- GabbleMediaStreamPrivate *priv = stream->priv;
-
- switch (property_id) {
- case PROP_OBJECT_PATH:
- g_free (priv->object_path);
- priv->object_path = g_value_dup_string (value);
- break;
- case PROP_DBUS_DAEMON:
- g_assert (priv->dbus_daemon == NULL);
- priv->dbus_daemon = g_value_dup_object (value);
- break;
- case PROP_NAME:
- g_free (stream->name);
- stream->name = g_value_dup_string (value);
- break;
- case PROP_ID:
- priv->id = g_value_get_uint (value);
- break;
- case PROP_CONNECTION_STATE:
- DEBUG ("stream %s connection state %d",
- stream->name, stream->connection_state);
- stream->connection_state = g_value_get_uint (value);
- break;
- case PROP_READY:
- priv->ready = g_value_get_boolean (value);
- break;
- case PROP_PLAYING:
- {
- gboolean old = stream->playing;
- stream->playing = g_value_get_boolean (value);
- if (stream->playing != old)
- push_playing (stream);
- }
- break;
- case PROP_COMBINED_DIRECTION:
- DEBUG ("changing combined direction from %u to %u",
- stream->combined_direction, g_value_get_uint (value));
- stream->combined_direction = g_value_get_uint (value);
- break;
- case PROP_CONTENT:
- g_assert (priv->content == NULL);
-
- priv->content = g_value_dup_object (value);
-
- {
- guint jtype;
- gboolean locally_created;
-
- g_object_get (priv->content,
- "media-type", &jtype,
- "locally-created", &locally_created,
- NULL);
-
- if (jtype == WOCKY_JINGLE_MEDIA_TYPE_VIDEO)
- priv->media_type = TP_MEDIA_STREAM_TYPE_VIDEO;
- else
- priv->media_type = TP_MEDIA_STREAM_TYPE_AUDIO;
-
- priv->created_locally = locally_created;
- }
-
- DEBUG ("%p: connecting to content %p signals", stream, priv->content);
-
- gabble_signal_connect_weak (priv->content, "new-candidates",
- (GCallback) new_remote_candidates_cb, object);
-
- /* we need this also, if we're the initiator of the stream
- * (so remote codecs arrive later) */
- gabble_signal_connect_weak (priv->content, "remote-media-description",
- (GCallback) new_remote_media_description_cb, object);
-
- gabble_signal_connect_weak (priv->content, "notify::state",
- (GCallback) content_state_changed_cb, object);
-
- gabble_signal_connect_weak (priv->content, "notify::senders",
- (GCallback) content_senders_changed_cb, object);
-
- gabble_signal_connect_weak (priv->content->session,
- "remote-state-changed", (GCallback) remote_state_changed_cb, object);
-
- gabble_signal_connect_weak (priv->content, "removed",
- (GCallback) content_removed_cb, object);
- break;
- case PROP_NAT_TRAVERSAL:
- g_assert (priv->nat_traversal == NULL);
- priv->nat_traversal = g_value_dup_string (value);
- break;
- case PROP_RELAY_INFO:
- g_assert (priv->relay_info == NULL);
- priv->relay_info = g_value_dup_boxed (value);
- break;
- case PROP_LOCAL_HOLD:
- priv->local_hold = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void gabble_media_stream_dispose (GObject *object);
-static void gabble_media_stream_finalize (GObject *object);
-
-static void
-gabble_media_stream_class_init (GabbleMediaStreamClass *gabble_media_stream_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (gabble_media_stream_class);
- GParamSpec *param_spec;
- static TpDBusPropertiesMixinPropImpl stream_handler_props[] = {
- { "RelayInfo", "relay-info", NULL },
- { "STUNServers", "stun-servers", NULL },
- { "NATTraversal", "nat-traversal", NULL },
- { "CreatedLocally", "created-locally", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
- { TP_IFACE_MEDIA_STREAM_HANDLER,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- stream_handler_props,
- },
- { NULL }
- };
-
- g_type_class_add_private (gabble_media_stream_class,
- sizeof (GabbleMediaStreamPrivate));
-
- object_class->constructor = gabble_media_stream_constructor;
-
- object_class->get_property = gabble_media_stream_get_property;
- object_class->set_property = gabble_media_stream_set_property;
-
- object_class->dispose = gabble_media_stream_dispose;
- object_class->finalize = gabble_media_stream_finalize;
-
- param_spec = g_param_spec_object ("dbus-daemon", "TpDBusDaemon",
- "Bus on which to export this object",
- TP_TYPE_DBUS_DAEMON,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_DBUS_DAEMON, param_spec);
-
- param_spec = g_param_spec_string ("object-path", "D-Bus object path",
- "The D-Bus object path used for this "
- "object on the bus.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_OBJECT_PATH, param_spec);
-
- param_spec = g_param_spec_string ("name", "Stream name",
- "An opaque name for the stream used in the signalling.", NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_NAME, param_spec);
-
- param_spec = g_param_spec_uint ("id", "Stream ID",
- "A stream number for the stream used in the "
- "D-Bus API.",
- 0, G_MAXUINT, 0,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_ID, param_spec);
-
- param_spec = g_param_spec_uint ("media-type", "Stream media type",
- "A constant indicating which media type the stream carries.",
- TP_MEDIA_STREAM_TYPE_AUDIO, TP_MEDIA_STREAM_TYPE_VIDEO,
- TP_MEDIA_STREAM_TYPE_AUDIO,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_MEDIA_TYPE, param_spec);
-
- param_spec = g_param_spec_uint ("connection-state", "Stream connection state",
- "An integer indicating the state of the"
- "stream's connection.",
- TP_MEDIA_STREAM_STATE_DISCONNECTED,
- TP_MEDIA_STREAM_STATE_CONNECTED,
- TP_MEDIA_STREAM_STATE_DISCONNECTED,
- G_PARAM_CONSTRUCT |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_CONNECTION_STATE,
- param_spec);
-
- param_spec = g_param_spec_boolean ("ready", "Ready?",
- "A boolean signifying whether the user "
- "is ready to handle signals from this "
- "object.",
- FALSE,
- G_PARAM_CONSTRUCT |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_READY, param_spec);
-
- param_spec = g_param_spec_boolean ("playing", "Set playing",
- "A boolean signifying whether the stream "
- "has been set playing yet.",
- FALSE,
- G_PARAM_CONSTRUCT |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_PLAYING, param_spec);
-
- param_spec = g_param_spec_uint ("combined-direction",
- "Combined direction",
- "An integer indicating the directions the stream currently sends in, "
- "and the peers who have been asked to send.",
- TP_MEDIA_STREAM_DIRECTION_NONE,
- MAKE_COMBINED_DIRECTION (TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- TP_MEDIA_STREAM_PENDING_LOCAL_SEND |
- TP_MEDIA_STREAM_PENDING_REMOTE_SEND),
- TP_MEDIA_STREAM_DIRECTION_NONE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_COMBINED_DIRECTION,
- param_spec);
-
- param_spec = g_param_spec_boolean ("local-hold", "Local hold?",
- "True if resources used for this stream have been freed.", FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK);
- g_object_class_install_property (object_class, PROP_LOCAL_HOLD, param_spec);
-
- param_spec = g_param_spec_object ("content", "WockyJingleContent object",
- "Jingle content signalling this media stream.",
- WOCKY_TYPE_JINGLE_CONTENT,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_CONTENT, param_spec);
-
- param_spec = g_param_spec_boxed ("stun-servers", "STUN servers",
- "Array of (STRING: address literal, UINT: port) pairs",
- /* FIXME: use correct macro when available */
- tp_type_dbus_array_su (),
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STUN_SERVERS, param_spec);
-
- param_spec = g_param_spec_boxed ("relay-info", "Relay info",
- "Array of mappings containing relay server information",
- TP_ARRAY_TYPE_STRING_VARIANT_MAP_LIST,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_RELAY_INFO, param_spec);
-
- param_spec = g_param_spec_string ("nat-traversal", "NAT traversal",
- "NAT traversal mechanism for this stream", NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_NAT_TRAVERSAL,
- param_spec);
-
- param_spec = g_param_spec_boolean ("created-locally", "Created locally?",
- "True if this stream was created by the local user", FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CREATED_LOCALLY,
- param_spec);
-
- /* signals not exported by D-Bus interface */
-
- signals[ERROR] =
- g_signal_new ("error",
- G_OBJECT_CLASS_TYPE (gabble_media_stream_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- 0,
- NULL, NULL,
- gabble_marshal_VOID__UINT_STRING,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_STRING);
-
- signals[UNHOLD_FAILED] = g_signal_new ("unhold-failed",
- G_OBJECT_CLASS_TYPE (gabble_media_stream_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-
- gabble_media_stream_class->props_class.interfaces = prop_interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (GabbleMediaStreamClass, props_class));
-}
-
-void
-gabble_media_stream_dispose (GObject *object)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (object);
- GabbleMediaStreamPrivate *priv = self->priv;
-
- DEBUG ("called");
-
- if (priv->dispose_has_run)
- return;
-
- if (priv->initial_getter_id != 0)
- {
- g_source_remove (priv->initial_getter_id);
- priv->initial_getter_id = 0;
- }
-
- gabble_media_stream_close (self);
-
- priv->dispose_has_run = TRUE;
-
- tp_clear_object (&priv->content);
- tp_clear_pointer (&self->name, g_free);
- g_clear_object (&priv->dbus_daemon);
-
- if (G_OBJECT_CLASS (gabble_media_stream_parent_class)->dispose)
- G_OBJECT_CLASS (gabble_media_stream_parent_class)->dispose (object);
-}
-
-void
-gabble_media_stream_finalize (GObject *object)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (object);
- GabbleMediaStreamPrivate *priv = self->priv;
-
- g_free (priv->object_path);
- g_free (priv->nat_traversal);
-
- /* FIXME: use correct macro when available */
- if (priv->stun_servers != NULL)
- g_boxed_free (tp_type_dbus_array_su (), priv->stun_servers);
-
- if (priv->relay_info != NULL)
- g_boxed_free (TP_ARRAY_TYPE_STRING_VARIANT_MAP_LIST, priv->relay_info);
-
- g_value_unset (&priv->local_rtp_hdrexts);
- g_value_unset (&priv->local_feedback_messages);
-
- g_value_unset (&priv->remote_codecs);
- g_value_unset (&priv->remote_rtp_hdrexts);
- g_value_unset (&priv->remote_feedback_messages);
- g_value_unset (&priv->remote_candidates);
-
- G_OBJECT_CLASS (gabble_media_stream_parent_class)->finalize (object);
-}
-
-/**
- * gabble_media_stream_codec_choice
- *
- * Implements D-Bus method CodecChoice
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_codec_choice (TpSvcMediaStreamHandler *iface,
- guint codec_id,
- DBusGMethodInvocation *context)
-{
- tp_svc_media_stream_handler_return_from_codec_choice (context);
-}
-
-
-gboolean
-gabble_media_stream_error (GabbleMediaStream *self,
- guint errnum,
- const gchar *message,
- GError **error)
-{
- g_assert (GABBLE_IS_MEDIA_STREAM (self));
-
- DEBUG ( "Media.StreamHandler::Error called, error %u (%s) -- emitting signal",
- errnum, message);
- g_signal_emit (self, signals[ERROR], 0, errnum, message);
-
- return TRUE;
-}
-
-
-/**
- * gabble_media_stream_error
- *
- * Implements D-Bus method Error
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_error_async (TpSvcMediaStreamHandler *iface,
- guint errnum,
- const gchar *message,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
- GError *error = NULL;
-
- if (gabble_media_stream_error (self, errnum, message, &error))
- {
- tp_svc_media_stream_handler_return_from_error (context);
- }
- else
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-
-/**
- * gabble_media_stream_hold:
- *
- * Tell streaming clients that the stream is going on hold, so they should
- * stop streaming and free up any resources they are currently holding
- * (e.g. close hardware devices); or that the stream is coming off hold,
- * so they should reacquire those resources.
- */
-void
-gabble_media_stream_hold (GabbleMediaStream *self,
- gboolean hold)
-{
- tp_svc_media_stream_handler_emit_set_stream_held (self, hold);
-}
-
-
-/**
- * gabble_media_stream_hold_state:
- *
- * Called by streaming clients when the stream's hold state has been changed
- * successfully in response to SetStreamHeld.
- */
-static void
-gabble_media_stream_hold_state (TpSvcMediaStreamHandler *iface,
- gboolean hold_state,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
- GabbleMediaStreamPrivate *priv = self->priv;
-
- DEBUG ("%p: %s", self, hold_state ? "held" : "unheld");
- priv->local_hold = hold_state;
-
- g_object_notify ((GObject *) self, "local-hold");
-
- tp_svc_media_stream_handler_return_from_hold_state (context);
-}
-
-
-/**
- * gabble_media_stream_unhold_failure:
- *
- * Called by streaming clients when an attempt to reacquire the necessary
- * hardware or software resources to unhold the stream, in response to
- * SetStreamHeld, has failed.
- */
-static void
-gabble_media_stream_unhold_failure (TpSvcMediaStreamHandler *iface,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
- GabbleMediaStreamPrivate *priv = self->priv;
-
- DEBUG ("%p", self);
-
- priv->local_hold = TRUE;
-
- g_signal_emit (self, signals[UNHOLD_FAILED], 0);
- g_object_notify ((GObject *) self, "local-hold");
-
- tp_svc_media_stream_handler_return_from_unhold_failure (context);
-}
-
-
-/**
- * gabble_media_stream_native_candidates_prepared
- *
- * Implements D-Bus method NativeCandidatesPrepared
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_native_candidates_prepared (TpSvcMediaStreamHandler *iface,
- DBusGMethodInvocation *context)
-{
- tp_svc_media_stream_handler_return_from_native_candidates_prepared (context);
-}
-
-
-/**
- * gabble_media_stream_new_active_candidate_pair
- *
- * Implements D-Bus method NewActiveCandidatePair
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_new_active_candidate_pair (TpSvcMediaStreamHandler *iface,
- const gchar *native_candidate_id,
- const gchar *remote_candidate_id,
- DBusGMethodInvocation *context)
-{
- DEBUG ("called (%s, %s); this is a no-op on Jingle", native_candidate_id,
- remote_candidate_id);
-
- tp_svc_media_stream_handler_return_from_new_active_candidate_pair (context);
-}
-
-
-/**
- * gabble_media_stream_new_native_candidate
- *
- * Implements D-Bus method NewNativeCandidate
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_new_native_candidate (TpSvcMediaStreamHandler *iface,
- const gchar *candidate_id,
- const GPtrArray *transports,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
- GabbleMediaStreamPrivate *priv;
- WockyJingleState state;
- GList *li = NULL;
- guint i;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (self));
-
- priv = self->priv;
-
- g_object_get (priv->content->session, "state", &state, NULL);
-
- /* FIXME: maybe this should be an assertion in case the channel
- * isn't closed early enough right now? */
- if (state > WOCKY_JINGLE_STATE_ACTIVE)
- {
- DEBUG ("state > WOCKY_JINGLE_STATE_ACTIVE, doing nothing");
- tp_svc_media_stream_handler_return_from_new_native_candidate (context);
- return;
- }
-
- for (i = 0; i < transports->len; i++)
- {
- GValueArray *transport;
- guint component;
- const gchar *addr;
- WockyJingleCandidate *c;
-
- transport = g_ptr_array_index (transports, i);
- component = g_value_get_uint (g_value_array_get_nth (transport, 0));
-
- /* Farsight 1 compatibility */
- if (component == 0)
- component = 1;
-
- /* We understand RTP and RTCP, and silently ignore the rest */
- if ((component != 1) && (component != 2))
- continue;
-
- addr = g_value_get_string (g_value_array_get_nth (transport, 1));
- if (!strcmp (addr, "127.0.0.1"))
- {
- DEBUG ("ignoring native localhost candidate");
- continue;
- }
-
- c = wocky_jingle_candidate_new (
- /* protocol */
- g_value_get_uint (g_value_array_get_nth (transport, 3)),
- /* candidate type, we're relying on 1:1 candidate type mapping */
- g_value_get_uint (g_value_array_get_nth (transport, 7)),
- /* id */
- candidate_id,
- /* component */
- component,
- /* address */
- g_value_get_string (g_value_array_get_nth (transport, 1)),
- /* port */
- g_value_get_uint (g_value_array_get_nth (transport, 2)),
- /* generation */
- 0,
- /* preference */
- (int) (g_value_get_double (g_value_array_get_nth (transport, 6)) * 65536),
- /* username */
- g_value_get_string (g_value_array_get_nth (transport, 8)),
- /* password */
- g_value_get_string (g_value_array_get_nth (transport, 9)),
- /* network */
- 0);
-
- li = g_list_prepend (li, c);
- }
-
- if (li != NULL)
- wocky_jingle_content_add_candidates (priv->content, li);
-
- tp_svc_media_stream_handler_return_from_new_native_candidate (context);
-}
-
-static void gabble_media_stream_set_local_codecs (TpSvcMediaStreamHandler *,
- const GPtrArray *codecs, DBusGMethodInvocation *);
-
-/**
- * gabble_media_stream_ready
- *
- * Implements D-Bus method Ready
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_ready (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
- GabbleMediaStreamPrivate *priv;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (self));
-
- priv = self->priv;
-
- DEBUG ("ready called");
-
- if (priv->ready == FALSE)
- {
- g_object_set (self, "ready", TRUE, NULL);
-
- push_remote_media_description (self);
- push_remote_candidates (self);
- push_playing (self);
- push_sending (self);
-
- /* If a new stream is added while the call's on hold, it will have
- * local_hold set at construct time. So once tp-fs has called Ready(), we
- * should let it know this stream's on hold.
- */
- if (priv->local_hold)
- gabble_media_stream_hold (self, priv->local_hold);
- }
- else
- {
- DEBUG ("Ready called twice, running plain SetLocalCodecs instead");
- }
-
- /* set_local_codecs and ready return the same thing, so we can do... */
- gabble_media_stream_set_local_codecs (iface, codecs, context);
-}
-
-static gboolean
-pass_local_codecs (GabbleMediaStream *stream,
- const GPtrArray *codecs,
- gboolean ready,
- GError **error)
-{
- GabbleMediaStreamPrivate *priv = stream->priv;
- guint i;
- WockyJingleMediaDescription *md;
- const GPtrArray *hdrexts;
- GHashTable *fbs;
- GError *wocky_error = NULL;
-
- DEBUG ("putting list of %d supported codecs from stream-engine into cache",
- codecs->len);
-
- md = wocky_jingle_media_description_new ();
-
- fbs = g_value_get_boxed (&priv->local_feedback_messages);
-
- for (i = 0; i < codecs->len; i++)
- {
- GType codec_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CODEC;
-
- GValue codec = { 0, };
- guint id, clock_rate, channels;
- gchar *name;
- GHashTable *params;
- WockyJingleCodec *c;
- GValueArray *fb_codec;
-
- g_value_init (&codec, codec_struct_type);
- g_value_set_static_boxed (&codec, g_ptr_array_index (codecs, i));
-
- dbus_g_type_struct_get (&codec,
- 0, &id,
- 1, &name,
- 3, &clock_rate,
- 4, &channels,
- 5, &params,
- G_MAXUINT);
-
- c = jingle_media_rtp_codec_new (id, name,
- clock_rate, channels, params);
-
- if (fbs != NULL)
- {
- fb_codec = g_hash_table_lookup (fbs, GUINT_TO_POINTER (id));
- if (fb_codec != NULL)
- {
- if (G_VALUE_HOLDS_UINT (
- g_value_array_get_nth (fb_codec, 0)) &&
- G_VALUE_TYPE (g_value_array_get_nth (fb_codec, 1)) ==
- TP_ARRAY_TYPE_RTCP_FEEDBACK_MESSAGE_LIST)
- {
- GValue *val;
- const GPtrArray *fb_array;
- guint j;
-
- val = g_value_array_get_nth (fb_codec, 0);
- c->trr_int = g_value_get_uint (val);
-
- val = g_value_array_get_nth (fb_codec, 1);
- fb_array = g_value_get_boxed (val);
-
- for (j = 0; j < fb_array->len; j++)
- {
- GValueArray *message = g_ptr_array_index (fb_array, j);
- const gchar *type;
- const gchar *subtype;
-
- val = g_value_array_get_nth (message, 0);
- type = g_value_get_string (val);
-
- val = g_value_array_get_nth (message, 1);
- subtype = g_value_get_string (val);
-
- c->feedback_msgs = g_list_append (c->feedback_msgs,
- wocky_jingle_feedback_message_new (type, subtype));
- }
- }
- }
- }
- DEBUG ("adding codec %s (%u %u %u)", c->name, c->id, c->clockrate, c->channels);
- md->codecs = g_list_append (md->codecs, c);
- g_free (name);
- g_hash_table_unref (params);
- }
-
- if (fbs != NULL)
- g_value_reset (&priv->local_feedback_messages);
-
- hdrexts = g_value_get_boxed (&priv->local_rtp_hdrexts);
-
- if (hdrexts != NULL)
- {
- gboolean have_initiator = FALSE;
- gboolean initiated_by_us;
-
- for (i = 0; i < hdrexts->len; i++)
- {
- GValueArray *hdrext;
- guint id;
- guint direction;
- WockyJingleContentSenders senders;
- gchar *uri;
- gchar *params;
-
- hdrext = g_ptr_array_index (hdrexts, i);
-
- g_assert (hdrext);
- g_assert (hdrext->n_values == 4);
- g_assert (G_VALUE_HOLDS_UINT (g_value_array_get_nth (hdrext, 0)));
- g_assert (G_VALUE_HOLDS_UINT (g_value_array_get_nth (hdrext, 1)));
- g_assert (G_VALUE_HOLDS_STRING (g_value_array_get_nth (hdrext, 2)));
- g_assert (G_VALUE_HOLDS_STRING (g_value_array_get_nth (hdrext, 3)));
-
- tp_value_array_unpack (hdrext, 4,
- &id,
- &direction,
- &uri,
- &params);
-
- if (!have_initiator)
- {
- g_object_get (priv->content->session, "local-initiator",
- &initiated_by_us, NULL);
- have_initiator = TRUE;
- }
-
- switch (direction)
- {
- case TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL:
- senders = WOCKY_JINGLE_CONTENT_SENDERS_BOTH;
- break;
- case TP_MEDIA_STREAM_DIRECTION_NONE:
- senders = WOCKY_JINGLE_CONTENT_SENDERS_NONE;
- break;
- case TP_MEDIA_STREAM_DIRECTION_SEND:
- senders = initiated_by_us ? WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR :
- WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER;
- break;
- case TP_MEDIA_STREAM_DIRECTION_RECEIVE:
- senders = initiated_by_us ? WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER :
- WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR;
- break;
- default:
- g_assert_not_reached ();
- }
-
- md->hdrexts = g_list_append (md->hdrexts,
- wocky_jingle_rtp_header_extension_new (id, senders, uri));
- }
- /* Can only be used once */
- g_value_reset (&priv->local_rtp_hdrexts);
- }
-
- wocky_jingle_media_description_simplify (md);
-
- if (jingle_media_rtp_set_local_media_description (
- WOCKY_JINGLE_MEDIA_RTP (priv->content), md, ready, &wocky_error))
- return TRUE;
-
- g_set_error_literal (error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
- wocky_error->message);
- g_clear_error (&wocky_error);
- return FALSE;
-}
-
-/**
- * gabble_media_stream_set_local_codecs
- *
- * Implements D-Bus method SetLocalCodecs
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_set_local_codecs (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
- GabbleMediaStreamPrivate *priv = self->priv;
- GError *error = NULL;
-
- DEBUG ("called");
-
- if (codecs->len == 0)
- goto done;
-
- priv->local_codecs_set = TRUE;
-
- if (wocky_jingle_content_is_created_by_us (self->priv->content))
- {
- if (!pass_local_codecs (self, codecs, self->priv->created_locally,
- &error))
- {
- DEBUG ("failed: %s", error->message);
-
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
- }
- else
- {
- DEBUG ("ignoring local codecs, waiting for codec intersection");
- }
- done:
-
- tp_svc_media_stream_handler_return_from_set_local_codecs (context);
-}
-
-/**
- * gabble_media_stream_stream_state
- *
- * Implements D-Bus method StreamState
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_stream_state (TpSvcMediaStreamHandler *iface,
- guint connection_state,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
- GabbleMediaStreamPrivate *priv = self->priv;
- WockyJingleTransportState ts = WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED;
-
- switch (connection_state) {
- case TP_MEDIA_STREAM_STATE_DISCONNECTED:
- ts = WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED;
- break;
- case TP_MEDIA_STREAM_STATE_CONNECTING:
- ts = WOCKY_JINGLE_TRANSPORT_STATE_CONNECTING;
- break;
- case TP_MEDIA_STREAM_STATE_CONNECTED:
- ts = WOCKY_JINGLE_TRANSPORT_STATE_CONNECTED;
- break;
- default:
- DEBUG ("ignoring unknown connection state %u", connection_state);
- goto OUT;
- }
-
- g_object_set (self, "connection-state", connection_state, NULL);
- wocky_jingle_content_set_transport_state (priv->content, ts);
-
-OUT:
- tp_svc_media_stream_handler_return_from_stream_state (context);
-}
-
-
-/**
- * gabble_media_stream_supported_codecs
- *
- * Implements D-Bus method SupportedCodecs
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_supported_codecs (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
- GabbleMediaStreamPrivate *priv = self->priv;
- GError *error = NULL;
-
- DEBUG ("called");
-
- if (codecs->len == 0)
- {
- GError e = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
- "SupportedCodecs must have a non-empty list of codecs" };
-
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- priv->local_codecs_set = TRUE;
-
- if (priv->awaiting_intersection)
- {
- if (!pass_local_codecs (self, codecs, TRUE, &error))
- {
- DEBUG ("failed: %s", error->message);
-
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- priv->awaiting_intersection = FALSE;
- }
- else
- {
- /* If we created the stream, we don't need to send the intersection. If
- * we didn't create it, but have already sent the intersection once, we
- * don't need to send it again. In either case, extra calls to
- * SupportedCodecs are in response to an incoming description-info, which
- * can only change parameters and which XEP-0167 §10 says is purely
- * advisory.
- */
- DEBUG ("we already sent, or don't need to send, our codecs");
- }
-
- tp_svc_media_stream_handler_return_from_supported_codecs (context);
-}
-
-/**
- * gabble_media_stream_codecs_updated
- *
- * Implements D-Bus method CodecsUpdated
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_codecs_updated (TpSvcMediaStreamHandler *iface,
- const GPtrArray *codecs,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
- GError *error = NULL;
-
- if (!self->priv->local_codecs_set)
- {
- GError e = { TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "CodecsUpdated may only be called once an initial set of codecs "
- "has been set" };
-
- dbus_g_method_return_error (context, &e);
- return;
- }
-
- if (self->priv->awaiting_intersection)
- {
- /* When awaiting an intersection the initial set of codecs should be set
- * by calling SupportedCodecs as that is the canonical set of codecs,
- * updates are only meaningful afterwards */
- tp_svc_media_stream_handler_return_from_codecs_updated (context);
- return;
- }
-
- if (pass_local_codecs (self, codecs, self->priv->created_locally, &error))
- {
- tp_svc_media_stream_handler_return_from_codecs_updated (context);
- }
- else
- {
- DEBUG ("failed: %s", error->message);
-
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/**
- * gabble_media_stream_supported_header_extensions
- *
- * Implements D-Bus method SupportedHeaderExtensions
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_supported_header_extensions (TpSvcMediaStreamHandler *iface,
- const GPtrArray *hdrexts,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
-
- g_value_set_boxed (&self->priv->local_rtp_hdrexts, hdrexts);
-
- tp_svc_media_stream_handler_return_from_supported_header_extensions (context);
-}
-
-/**
- * gabble_media_stream_supported_feedback_messages
- *
- * Implements D-Bus method SupportedFeedbackMessages
- * on interface org.freedesktop.Telepathy.Media.StreamHandler
- */
-static void
-gabble_media_stream_supported_feedback_messages (TpSvcMediaStreamHandler *iface,
- GHashTable *messages,
- DBusGMethodInvocation *context)
-{
- GabbleMediaStream *self = GABBLE_MEDIA_STREAM (iface);
-
- g_value_set_boxed (&self->priv->local_feedback_messages, messages);
-
- tp_svc_media_stream_handler_return_from_supported_feedback_messages (context);
-}
-
-void
-gabble_media_stream_close (GabbleMediaStream *stream)
-{
- GabbleMediaStreamPrivate *priv;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
-
- priv = stream->priv;
-
- if (!priv->closed)
- {
- priv->closed = TRUE;
- tp_svc_media_stream_handler_emit_close (stream);
- }
-}
-
-static void
-insert_feedback_message (WockyJingleFeedbackMessage *fb, GPtrArray *fb_msgs)
-{
- GValueArray *msg;
-
- msg = tp_value_array_build (3,
- G_TYPE_STRING, fb->type,
- G_TYPE_STRING, fb->subtype,
- G_TYPE_STRING, "",
- G_TYPE_INVALID);
-
- g_ptr_array_add (fb_msgs, msg);
-}
-
-static void
-new_remote_media_description_cb (WockyJingleContent *content,
- WockyJingleMediaDescription *md, GabbleMediaStream *stream)
-{
- GabbleMediaStreamPrivate *priv;
- GList *li;
- GPtrArray *codecs;
- GPtrArray *hdrexts;
- GHashTable *fbs;
- GType codec_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CODEC;
- gboolean have_initiator = FALSE;
- gboolean initiated_by_us;
-
- DEBUG ("called");
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
-
- priv = stream->priv;
-
- codecs = g_value_get_boxed (&priv->remote_codecs);
-
- if (codecs->len != 0)
- {
- /* We already had some codecs; let's free the old list and make a new,
- * empty one to fill in.
- */
- g_value_reset (&priv->remote_codecs);
- codecs = dbus_g_type_specialized_construct (
- TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CODEC_LIST);
- g_value_take_boxed (&priv->remote_codecs, codecs);
- }
-
- hdrexts = g_value_get_boxed (&priv->remote_rtp_hdrexts);
-
- if (hdrexts->len != 0)
- {
- /* We already had some rtp hdrext; let's free the old list and make a new,
- * empty one to fill in.
- */
- g_value_reset (&priv->remote_rtp_hdrexts);
- hdrexts = dbus_g_type_specialized_construct (
- TP_ARRAY_TYPE_RTP_HEADER_EXTENSIONS_LIST);
- g_value_take_boxed (&priv->remote_rtp_hdrexts, hdrexts);
- }
-
- fbs = g_value_get_boxed (&priv->remote_feedback_messages);
-
- if (g_hash_table_size (fbs) != 0)
- {
- /* We already had some rtp hdrext; let's free the old list and make a new,
- * empty one to fill in.
- */
- g_value_reset (&priv->remote_feedback_messages);
- fbs = dbus_g_type_specialized_construct (
- TP_HASH_TYPE_RTCP_FEEDBACK_MESSAGE_MAP);
- g_value_take_boxed (&priv->remote_feedback_messages, fbs);
- }
-
- for (li = md->codecs; li; li = li->next)
- {
- GValue codec = { 0, };
- WockyJingleCodec *c = li->data;
-
- g_value_init (&codec, codec_struct_type);
- g_value_take_boxed (&codec,
- dbus_g_type_specialized_construct (codec_struct_type));
-
- DEBUG ("new remote %s codec: %u '%s' %u %u %u",
- priv->media_type == TP_MEDIA_STREAM_TYPE_AUDIO ? "audio" : "video",
- c->id, c->name, priv->media_type, c->clockrate, c->channels);
-
- dbus_g_type_struct_set (&codec,
- 0, c->id,
- 1, c->name,
- 2, priv->media_type,
- 3, c->clockrate,
- 4, c->channels,
- 5, c->params,
- G_MAXUINT);
-
- if (md->trr_int != G_MAXUINT || c->trr_int != G_MAXUINT ||
- md->feedback_msgs != NULL || c->feedback_msgs != NULL)
- {
- GValueArray *fb_msg_props;
- guint trr_int;
- GPtrArray *fb_msgs = g_ptr_array_new ();
-
- if (c->trr_int != G_MAXUINT)
- trr_int = c->trr_int;
- else
- trr_int = md->trr_int;
-
- g_list_foreach (md->feedback_msgs, (GFunc) insert_feedback_message,
- fb_msgs);
- g_list_foreach (c->feedback_msgs, (GFunc) insert_feedback_message,
- fb_msgs);
-
- fb_msg_props = tp_value_array_build (2,
- G_TYPE_UINT, trr_int,
- TP_ARRAY_TYPE_RTCP_FEEDBACK_MESSAGE_LIST, fb_msgs,
- G_TYPE_INVALID);
-
- g_boxed_free (TP_ARRAY_TYPE_RTCP_FEEDBACK_MESSAGE_LIST, fb_msgs);
-
- g_hash_table_insert (fbs, GUINT_TO_POINTER (c->id), fb_msg_props);
- }
-
- g_ptr_array_add (codecs, g_value_get_boxed (&codec));
- }
-
- for (li = md->hdrexts; li; li = li->next)
- {
- WockyJingleRtpHeaderExtension *h = li->data;
- TpMediaStreamDirection direction;
-
- if (!have_initiator)
- {
- g_object_get (priv->content->session, "local-initiator",
- &initiated_by_us, NULL);
- have_initiator = TRUE;
- }
-
- switch (h->senders)
- {
- case WOCKY_JINGLE_CONTENT_SENDERS_BOTH:
- direction = TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL;
- break;
- case WOCKY_JINGLE_CONTENT_SENDERS_NONE:
- direction = TP_MEDIA_STREAM_DIRECTION_NONE;
- break;
- case WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR:
- direction = initiated_by_us ? TP_MEDIA_STREAM_DIRECTION_SEND :
- TP_MEDIA_STREAM_DIRECTION_RECEIVE;
- break;
- case WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER:
- direction = initiated_by_us ? TP_MEDIA_STREAM_DIRECTION_RECEIVE :
- TP_MEDIA_STREAM_DIRECTION_SEND;
- break;
- default:
- g_assert_not_reached ();
- }
-
- DEBUG ("new RTP header ext : %u %s", h->id, h->uri);
-
- g_ptr_array_add (hdrexts,
- tp_value_array_build (4,
- G_TYPE_UINT, h->id,
- G_TYPE_UINT, direction,
- G_TYPE_STRING, h->uri,
- G_TYPE_STRING, "", /* No protocol defines parameters */
- G_TYPE_INVALID));
- }
-
- DEBUG ("pushing remote codecs");
-
- push_remote_media_description (stream);
-}
-
-
-static void
-push_remote_media_description (GabbleMediaStream *stream)
-{
- GabbleMediaStreamPrivate *priv;
- GPtrArray *codecs;
- GPtrArray *hdrexts;
- GHashTable *fbs;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
-
- priv = stream->priv;
-
- if (!priv->ready)
- return;
-
- codecs = g_value_get_boxed (&priv->remote_codecs);
- if (codecs->len == 0)
- return;
-
- hdrexts = g_value_get_boxed (&priv->remote_rtp_hdrexts);
-
- fbs = g_value_get_boxed (&priv->remote_feedback_messages);
-
- DEBUG ("passing %d remote codecs to stream-engine",
- codecs->len);
-
- tp_svc_media_stream_handler_emit_set_remote_header_extensions (stream,
- hdrexts);
- tp_svc_media_stream_handler_emit_set_remote_feedback_messages (stream, fbs);
- tp_svc_media_stream_handler_emit_set_remote_codecs (stream, codecs);
-}
-
-static void
-new_remote_candidates_cb (WockyJingleContent *content,
- GList *clist, GabbleMediaStream *stream)
-{
- GabbleMediaStreamPrivate *priv = stream->priv;
- GPtrArray *candidates;
- GList *li;
-
- candidates = g_value_get_boxed (&priv->remote_candidates);
-
- DEBUG ("got new remote candidates");
-
- for (li = clist; li; li = li->next)
- {
- gchar *candidate_id;
- GValue candidate = { 0, };
- GPtrArray *transports;
- GValue transport = { 0, };
- WockyJingleCandidate *c = li->data;
- GType transport_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_TRANSPORT;
- GType candidate_struct_type = TP_STRUCT_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE;
-
- g_value_init (&transport, transport_struct_type);
- g_value_take_boxed (&transport,
- dbus_g_type_specialized_construct (transport_struct_type));
-
- dbus_g_type_struct_set (&transport,
- 0, c->component,
- 1, c->address,
- 2, c->port,
- 3, c->protocol == WOCKY_JINGLE_TRANSPORT_PROTOCOL_UDP ? 0 : 1,
- 4, "RTP",
- 5, "AVP",
- 6, (gdouble) (c->preference / 65536.0),
- 7, c->type, /* FIXME: we're relying on 1:1 tp/jingle candidate type enums */
- 8, c->username,
- 9, c->password,
- G_MAXUINT);
-
- transports = g_ptr_array_sized_new (1);
- g_ptr_array_add (transports, g_value_get_boxed (&transport));
-
- g_value_init (&candidate, candidate_struct_type);
- g_value_take_boxed (&candidate,
- dbus_g_type_specialized_construct (candidate_struct_type));
-
- if (c->id == NULL)
- /* FIXME: is this naming scheme sensible? */
- candidate_id = g_strdup_printf ("R%d", ++priv->remote_candidate_count);
- else
- candidate_id = c->id;
-
- dbus_g_type_struct_set (&candidate,
- 0, candidate_id,
- 1, transports,
- G_MAXUINT);
-
- g_free (candidate_id);
- g_value_unset (&transport);
- g_ptr_array_unref (transports);
-
- g_ptr_array_add (candidates, g_value_get_boxed (&candidate));
- }
-
- push_remote_candidates (stream);
-}
-
-static void
-content_state_changed_cb (WockyJingleContent *c,
- GParamSpec *pspec,
- GabbleMediaStream *stream)
-{
- GabbleMediaStreamPrivate *priv = stream->priv;
- WockyJingleContentState state;
-
- g_object_get (c, "state", &state, NULL);
-
- DEBUG ("called");
-
- switch (state) {
- case WOCKY_JINGLE_CONTENT_STATE_ACKNOWLEDGED:
- /* connected stream means we can play, but sending is determined
- * by content senders (in update_senders) */
- stream->playing = TRUE;
- update_sending (stream, TRUE);
- push_playing (stream);
- push_sending (stream);
- break;
- case WOCKY_JINGLE_CONTENT_STATE_REMOVING:
- stream->playing = FALSE;
- priv->sending = FALSE;
- push_playing (stream);
- break;
- default:
- /* so gcc doesn't cry */
- break;
- }
-}
-
-static void
-push_remote_candidates (GabbleMediaStream *stream)
-{
- GabbleMediaStreamPrivate *priv;
- GPtrArray *candidates;
- guint i;
- GType candidate_list_type =
- TP_ARRAY_TYPE_MEDIA_STREAM_HANDLER_CANDIDATE_LIST;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
-
- priv = stream->priv;
-
- candidates = g_value_get_boxed (&priv->remote_candidates);
-
- if (candidates->len == 0)
- return;
-
- if (!priv->ready)
- return;
-
- for (i = 0; i < candidates->len; i++)
- {
- GValueArray *candidate = g_ptr_array_index (candidates, i);
- const gchar *candidate_id;
- const GPtrArray *transports;
-
- candidate_id = g_value_get_string (g_value_array_get_nth (candidate, 0));
- transports = g_value_get_boxed (g_value_array_get_nth (candidate, 1));
-
- DEBUG ("passing 1 remote candidate to stream engine: %s", candidate_id);
- tp_svc_media_stream_handler_emit_add_remote_candidate (
- stream, candidate_id, transports);
- }
-
- g_value_take_boxed (&priv->remote_candidates,
- dbus_g_type_specialized_construct (candidate_list_type));
-}
-
-static void
-push_playing (GabbleMediaStream *stream)
-{
- GabbleMediaStreamPrivate *priv;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
-
- priv = stream->priv;
-
- if (!priv->ready)
- return;
-
- DEBUG ("stream %s emitting SetStreamPlaying(%s)",
- stream->name, stream->playing ? "true" : "false");
-
- tp_svc_media_stream_handler_emit_set_stream_playing (
- stream, stream->playing);
-}
-
-static void
-push_sending (GabbleMediaStream *stream)
-{
- GabbleMediaStreamPrivate *priv;
- gboolean emit;
-
- g_assert (GABBLE_IS_MEDIA_STREAM (stream));
-
- priv = stream->priv;
-
- if (!priv->ready)
- return;
-
- emit = (priv->sending && !(priv->on_hold));
- DEBUG ("stream %s emitting SetStreamSending(%s); sending=%s, on_hold=%s",
- stream->name, emit ? "true" : "false", priv->sending ? "true" : "false",
- priv->on_hold ? "true" : "false");
-
- tp_svc_media_stream_handler_emit_set_stream_sending (
- stream, emit);
-}
-
-static void
-update_direction (GabbleMediaStream *stream, WockyJingleContent *c)
-{
- CombinedStreamDirection new_combined_dir;
- TpMediaStreamDirection requested_dir, current_dir;
- TpMediaStreamPendingSend pending_send;
- WockyJingleContentSenders senders;
- gboolean local_initiator;
-
- DEBUG ("called");
-
- g_object_get (c, "senders", &senders, NULL);
- g_object_get (c->session, "local-initiator", &local_initiator, NULL);
-
- switch (senders) {
- case WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR:
- requested_dir = local_initiator ?
- TP_MEDIA_STREAM_DIRECTION_SEND : TP_MEDIA_STREAM_DIRECTION_RECEIVE;
- break;
- case WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER:
- requested_dir = local_initiator ?
- TP_MEDIA_STREAM_DIRECTION_RECEIVE : TP_MEDIA_STREAM_DIRECTION_SEND;
- break;
- case WOCKY_JINGLE_CONTENT_SENDERS_BOTH:
- requested_dir = TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL;
- break;
- default:
- requested_dir = TP_MEDIA_STREAM_DIRECTION_NONE;
- }
-
- current_dir = COMBINED_DIRECTION_GET_DIRECTION (stream->combined_direction);
- pending_send = COMBINED_DIRECTION_GET_PENDING_SEND
- (stream->combined_direction);
-
- /* if local sending has been added, remove it,
- * and set the pending local send flag */
- if (((current_dir & TP_MEDIA_STREAM_DIRECTION_SEND) == 0) &&
- ((requested_dir & TP_MEDIA_STREAM_DIRECTION_SEND) != 0))
- {
- DEBUG ("setting pending local send flag");
- requested_dir &= ~TP_MEDIA_STREAM_DIRECTION_SEND;
- pending_send |= TP_MEDIA_STREAM_PENDING_LOCAL_SEND;
- }
-
- /* make any necessary changes */
- new_combined_dir = MAKE_COMBINED_DIRECTION (requested_dir, pending_send);
- if (new_combined_dir != stream->combined_direction)
- {
- g_object_set (stream, "combined-direction", new_combined_dir, NULL);
- update_sending (stream, FALSE);
- }
-
-}
-
-static void
-content_senders_changed_cb (WockyJingleContent *c,
- GParamSpec *pspec,
- GabbleMediaStream *stream)
-{
- update_direction (stream, c);
-}
-
-static void
-remote_state_changed_cb (WockyJingleSession *session,
- GabbleMediaStream *stream)
-{
- GabbleMediaStreamPrivate *priv = stream->priv;
- gboolean old_hold = priv->on_hold;
-
- priv->on_hold = wocky_jingle_session_get_remote_hold (session);
-
- if (old_hold != priv->on_hold)
- push_sending (stream);
-}
-
-static void
-content_removed_cb (WockyJingleContent *content, GabbleMediaStream *stream)
-{
- gabble_media_stream_close (stream);
-}
-
-
-gboolean
-gabble_media_stream_change_direction (GabbleMediaStream *stream,
- guint requested_dir, GError **error)
-{
- GabbleMediaStreamPrivate *priv = stream->priv;
- CombinedStreamDirection new_combined_dir;
- TpMediaStreamDirection current_dir;
- TpMediaStreamPendingSend pending_send;
- WockyJingleContentSenders senders;
- gboolean local_initiator;
-
- current_dir = COMBINED_DIRECTION_GET_DIRECTION (stream->combined_direction);
- pending_send = COMBINED_DIRECTION_GET_PENDING_SEND
- (stream->combined_direction);
-
- /* if we're awaiting a local decision on sending... */
- if ((pending_send & TP_MEDIA_STREAM_PENDING_LOCAL_SEND) != 0)
- {
- /* clear the flag */
- pending_send &= ~TP_MEDIA_STREAM_PENDING_LOCAL_SEND;
-
- /* make our current_dir match what other end thinks (he thinks we're
- * bidirectional) so that we send the correct transitions */
- current_dir ^= TP_MEDIA_STREAM_DIRECTION_SEND;
- }
-
- /* make any necessary changes */
- new_combined_dir = MAKE_COMBINED_DIRECTION (requested_dir, pending_send);
- if (new_combined_dir != stream->combined_direction)
- {
- WockyJingleContentState state;
- gboolean start_sending;
-
- g_object_set (stream, "combined-direction", new_combined_dir, NULL);
-
- /* We would like to emit SetStreamSending(True) (if appropriate) only if:
- * - the content was locally created, or
- * - the user explicitly okayed the content.
- * This appears to be the meaning of Acknowledged. :-)
- */
- g_object_get (stream->priv->content, "state", &state, NULL);
- start_sending = (state == WOCKY_JINGLE_CONTENT_STATE_ACKNOWLEDGED);
-
- update_sending (stream, start_sending);
- }
-
- DEBUG ("current_dir: %u, requested_dir: %u", current_dir, requested_dir);
-
- /* short-circuit sending a request if we're not asking for anything new */
- if (current_dir == requested_dir)
- return TRUE;
-
- g_object_get (priv->content->session, "local-initiator", &local_initiator, NULL);
-
- switch (requested_dir)
- {
- case TP_MEDIA_STREAM_DIRECTION_SEND:
- senders = local_initiator ?
- WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR : WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER;
- break;
-
- case TP_MEDIA_STREAM_DIRECTION_RECEIVE:
- senders = local_initiator ?
- WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER : WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR;
- break;
-
- case TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL:
- senders = WOCKY_JINGLE_CONTENT_SENDERS_BOTH;
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- if (!wocky_jingle_content_change_direction (priv->content, senders))
- {
- g_set_error (error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
- "stream direction invalid for the Jingle dialect in use");
- return FALSE;
- }
-
- return TRUE;
-}
-
-void
-gabble_media_stream_accept_pending_local_send (GabbleMediaStream *stream)
-{
- CombinedStreamDirection combined_dir = stream->combined_direction;
- TpMediaStreamDirection current_dir;
- TpMediaStreamPendingSend pending_send;
-
- current_dir = COMBINED_DIRECTION_GET_DIRECTION (combined_dir);
- pending_send = COMBINED_DIRECTION_GET_PENDING_SEND (combined_dir);
-
- if ((pending_send & TP_MEDIA_STREAM_PENDING_LOCAL_SEND) != 0)
- {
- DEBUG ("accepting pending local send on stream %s", stream->name);
-
- gabble_media_stream_change_direction (stream,
- current_dir | TP_MEDIA_STREAM_DIRECTION_SEND, NULL);
- }
- else
- {
- DEBUG ("stream %s not pending local send", stream->name);
- }
-}
-
-static void
-update_sending (GabbleMediaStream *stream, gboolean start_sending)
-{
- GabbleMediaStreamPrivate *priv = stream->priv;
- gboolean new_sending;
-
- new_sending =
- ((stream->combined_direction & TP_MEDIA_STREAM_DIRECTION_SEND) != 0);
-
- if (priv->sending == new_sending)
- return;
-
- if (new_sending && !start_sending)
- return;
-
- priv->sending = new_sending;
- push_sending (stream);
-}
-
-static void
-stream_handler_iface_init (gpointer g_iface, gpointer iface_data)
-{
- TpSvcMediaStreamHandlerClass *klass =
- (TpSvcMediaStreamHandlerClass *) g_iface;
-
-#define IMPLEMENT(x,suffix) tp_svc_media_stream_handler_implement_##x (\
- klass, gabble_media_stream_##x##suffix)
- IMPLEMENT(codec_choice,);
- IMPLEMENT(error,_async);
- IMPLEMENT(hold_state,);
- IMPLEMENT(native_candidates_prepared,);
- IMPLEMENT(new_active_candidate_pair,);
- IMPLEMENT(new_native_candidate,);
- IMPLEMENT(ready,);
- IMPLEMENT(set_local_codecs,);
- IMPLEMENT(stream_state,);
- IMPLEMENT(supported_codecs,);
- IMPLEMENT(unhold_failure,);
- IMPLEMENT(codecs_updated,);
- IMPLEMENT(supported_header_extensions,);
- IMPLEMENT(supported_feedback_messages,);
-#undef IMPLEMENT
-}
-
-WockyJingleMediaRtp *
-gabble_media_stream_get_content (GabbleMediaStream *self)
-{
- /* FIXME: we should fix this whole class up. It relies throughout on
- * self->priv->content actually secretly being a WockyJingleMediaRtp.
- */
- return WOCKY_JINGLE_MEDIA_RTP (self->priv->content);
-}
-
-void
-gabble_media_stream_start_telephony_event (GabbleMediaStream *self,
- guchar event)
-{
- DEBUG ("stream %s: %c", self->name, tp_dtmf_event_to_char (event));
-
- tp_svc_media_stream_handler_emit_start_telephony_event (
- (TpSvcMediaStreamHandler *) self, event);
-}
-
-void
-gabble_media_stream_stop_telephony_event (GabbleMediaStream *self)
-{
- DEBUG ("stream %s", self->name);
-
- tp_svc_media_stream_handler_emit_stop_telephony_event (
- (TpSvcMediaStreamHandler *) self);
-}
-
-void
-gabble_media_stream_add_dtmf_player (GabbleMediaStream *self,
- TpDTMFPlayer *dtmf_player)
-{
- tp_g_signal_connect_object (dtmf_player, "started-tone",
- G_CALLBACK (gabble_media_stream_start_telephony_event), self,
- G_CONNECT_SWAPPED);
- tp_g_signal_connect_object (dtmf_player, "stopped-tone",
- G_CALLBACK (gabble_media_stream_stop_telephony_event), self,
- G_CONNECT_SWAPPED);
-}
diff --git a/src/media-stream.h b/src/media-stream.h
deleted file mode 100644
index 2174f52df..000000000
--- a/src/media-stream.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * gabble-media-stream.h - Header for GabbleMediaStream
- * Copyright (C) 2006 Collabora Ltd.
- * Copyright (C) 2006 Nokia Corporation
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __GABBLE_MEDIA_STREAM_H__
-#define __GABBLE_MEDIA_STREAM_H__
-
-#include <glib-object.h>
-#include <telepathy-glib/telepathy-glib.h>
-#include <wocky/wocky.h>
-
-G_BEGIN_DECLS
-
-typedef enum
-{
- STREAM_SIG_STATE_NEW,
- STREAM_SIG_STATE_SENT,
- STREAM_SIG_STATE_ACKNOWLEDGED,
- STREAM_SIG_STATE_REMOVING
-} StreamSignallingState;
-
-typedef guint32 CombinedStreamDirection;
-
-typedef struct _GabbleMediaStream GabbleMediaStream;
-typedef struct _GabbleMediaStreamClass GabbleMediaStreamClass;
-typedef struct _GabbleMediaStreamPrivate GabbleMediaStreamPrivate;
-
-struct _GabbleMediaStreamClass {
- GObjectClass parent_class;
-
- TpDBusPropertiesMixinClass props_class;
-};
-
-struct _GabbleMediaStream {
- GObject parent;
-
- gchar *name;
-
- TpMediaStreamState connection_state;
-
- CombinedStreamDirection combined_direction;
- gboolean playing;
-
- GabbleMediaStreamPrivate *priv;
-};
-
-GType gabble_media_stream_get_type (void);
-
-/* TYPE MACROS */
-#define GABBLE_TYPE_MEDIA_STREAM \
- (gabble_media_stream_get_type ())
-#define GABBLE_MEDIA_STREAM(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), GABBLE_TYPE_MEDIA_STREAM, \
- GabbleMediaStream))
-#define GABBLE_MEDIA_STREAM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), GABBLE_TYPE_MEDIA_STREAM, \
- GabbleMediaStreamClass))
-#define GABBLE_IS_MEDIA_STREAM(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), GABBLE_TYPE_MEDIA_STREAM))
-#define GABBLE_IS_MEDIA_STREAM_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), GABBLE_TYPE_MEDIA_STREAM))
-#define GABBLE_MEDIA_STREAM_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_MEDIA_STREAM, \
- GabbleMediaStreamClass))
-
-#define COMBINED_DIRECTION_GET_DIRECTION(d) \
- ((TpMediaStreamDirection) ((d) & TP_MEDIA_STREAM_DIRECTION_BIDIRECTIONAL))
-#define COMBINED_DIRECTION_GET_PENDING_SEND(d) \
- ((TpMediaStreamPendingSend) ((d) >> 2))
-#define MAKE_COMBINED_DIRECTION(d, p) \
- ((CombinedStreamDirection) ((d) | ((p) << 2)))
-
-gboolean gabble_media_stream_error (GabbleMediaStream *self, guint errno,
- const gchar *message, GError **error);
-
-void gabble_media_stream_close (GabbleMediaStream *close);
-void gabble_media_stream_hold (GabbleMediaStream *stream, gboolean hold);
-gboolean gabble_media_stream_change_direction (GabbleMediaStream *stream,
- guint requested_dir, GError **error);
-void gabble_media_stream_accept_pending_local_send (GabbleMediaStream *stream);
-
-GabbleMediaStream *gabble_media_stream_new (
- TpDBusDaemon *dbus_daemon,
- const gchar *object_path,
- WockyJingleContent *content,
- const gchar *name,
- guint id,
- const gchar *nat_traversal,
- const GPtrArray *relay_info,
- gboolean local_hold);
-TpMediaStreamType gabble_media_stream_get_media_type (GabbleMediaStream *self);
-
-void gabble_media_stream_add_dtmf_player (GabbleMediaStream *self,
- TpDTMFPlayer *dtmf_player);
-
-WockyJingleMediaRtp *gabble_media_stream_get_content (GabbleMediaStream *self);
-
-void gabble_media_stream_start_telephony_event (GabbleMediaStream *self, guchar event);
-void gabble_media_stream_stop_telephony_event (GabbleMediaStream *self);
-
-G_END_DECLS
-
-#endif /* #ifndef __GABBLE_MEDIA_STREAM_H__*/
diff --git a/src/message-util.c b/src/message-util.c
index 01bb71735..6b80708f7 100644
--- a/src/message-util.c
+++ b/src/message-util.c
@@ -118,7 +118,7 @@ gabble_message_util_build_stanza (TpMessage *message,
if (!result)
RETURN_INVALID_ARGUMENT ("message-type must be a 32-bit unsigned integer");
- if (type >= NUM_TP_CHANNEL_TEXT_MESSAGE_TYPES)
+ if (type >= TP_NUM_CHANNEL_TEXT_MESSAGE_TYPES)
RETURN_INVALID_ARGUMENT ("invalid message type: %u", type);
n_parts = tp_message_count_parts (message);
diff --git a/src/muc-channel.c b/src/muc-channel.c
index 15c337b07..78f79c74d 100644
--- a/src/muc-channel.c
+++ b/src/muc-channel.c
@@ -815,7 +815,7 @@ tube_pre_presence (GabbleMucChannel *gmuc,
GabbleTubeIface *tube = value;
TpTubeChannelState state;
WockyNode *tube_node;
- TpTubeType type;
+ TubeType type;
TpHandle initiator;
g_object_get (tube,
@@ -827,7 +827,7 @@ tube_pre_presence (GabbleMucChannel *gmuc,
if (state != TP_TUBE_CHANNEL_STATE_OPEN)
continue;
- if (type == TP_TUBE_TYPE_STREAM
+ if (type == TUBE_TYPE_STREAM
&& initiator != TP_GROUP_MIXIN (gmuc)->self_handle)
/* We only announce stream tubes we initiated */
continue;
@@ -1971,7 +1971,7 @@ tube_closed_cb (GabbleTubeIface *tube,
static GabbleTubeIface *
create_new_tube (GabbleMucChannel *gmuc,
- TpTubeType type,
+ TubeType type,
TpHandle initiator,
const gchar *service,
GHashTable *parameters,
@@ -1990,13 +1990,13 @@ create_new_tube (GabbleMucChannel *gmuc,
switch (type)
{
- case TP_TUBE_TYPE_DBUS:
+ case TUBE_TYPE_DBUS:
tube = GABBLE_TUBE_IFACE (gabble_tube_dbus_new (conn,
handle, TP_HANDLE_TYPE_ROOM, self_handle, initiator,
service, parameters, stream_id, tube_id, bytestream, gmuc,
requested));
break;
- case TP_TUBE_TYPE_STREAM:
+ case TUBE_TYPE_STREAM:
tube = GABBLE_TUBE_IFACE (gabble_tube_stream_new (conn,
handle, TP_HANDLE_TYPE_ROOM, self_handle, initiator,
service, parameters, tube_id, gmuc, requested));
@@ -2044,7 +2044,7 @@ gabble_muc_channel_tube_request (GabbleMucChannel *self,
GHashTable *parameters = NULL;
guint64 tube_id;
gchar *stream_id;
- TpTubeType type;
+ TubeType type;
tube_id = generate_tube_id (self);
@@ -2053,14 +2053,14 @@ gabble_muc_channel_tube_request (GabbleMucChannel *self,
if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE))
{
- type = TP_TUBE_TYPE_STREAM;
+ type = TUBE_TYPE_STREAM;
service = tp_asv_get_string (request_properties,
TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE);
}
else if (! tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE))
{
- type = TP_TUBE_TYPE_DBUS;
+ type = TUBE_TYPE_DBUS;
service = tp_asv_get_string (request_properties,
TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME);
}
@@ -2231,7 +2231,7 @@ tubes_presence_update (GabbleMucChannel *gmuc,
const gchar *stream_id;
GabbleTubeIface *tube;
guint64 tube_id;
- TpTubeType type;
+ TubeType type;
stream_id = wocky_node_get_attribute (tube_node, "stream-id");
@@ -2255,13 +2255,13 @@ tubes_presence_update (GabbleMucChannel *gmuc,
contact_repo, tube_node, &type, &initiator_handle,
&service, &parameters, NULL))
{
- if (type == TP_TUBE_TYPE_DBUS && initiator_handle == 0)
+ if (type == TUBE_TYPE_DBUS && initiator_handle == 0)
{
DEBUG ("D-Bus tube initiator missing");
/* skip to the next child of <tubes> */
continue;
}
- else if (type == TP_TUBE_TYPE_STREAM)
+ else if (type == TUBE_TYPE_STREAM)
{
initiator_handle = contact;
}
@@ -2287,7 +2287,7 @@ tubes_presence_update (GabbleMucChannel *gmuc,
g_object_get (tube, "type", &type, NULL);
- if (type == TP_TUBE_TYPE_DBUS)
+ if (type == TUBE_TYPE_DBUS)
{
/* Update mapping of handle -> D-Bus name. */
if (!gabble_tube_dbus_handle_in_names (GABBLE_TUBE_DBUS (tube),
diff --git a/src/muc-factory.c b/src/muc-factory.c
index 0f1dbcb07..39f468509 100644
--- a/src/muc-factory.c
+++ b/src/muc-factory.c
@@ -266,56 +266,51 @@ muc_ready_cb (GabbleMucChannel *text_chan,
{
GabbleMucFactory *fac = GABBLE_MUC_FACTORY (data);
GabbleMucFactoryPrivate *priv = fac->priv;
- GHashTable *channels;
TpBaseChannel *base = TP_BASE_CHANNEL (text_chan);
-
GSList *requests_satisfied_text = NULL;
GQueue *tube_channels;
DEBUG ("text chan=%p", text_chan);
- channels = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, (GDestroyNotify) g_slist_free);
-
requests_satisfied_text = g_hash_table_lookup (
priv->queued_requests, text_chan);
g_hash_table_steal (priv->queued_requests, text_chan);
requests_satisfied_text = g_slist_reverse (requests_satisfied_text);
+ /* only announce channels which are on the bus (requested or
+ * requested with an invite, not channels only around because they
+ * have to be) */
+ if (tp_base_channel_is_registered (base))
+ {
+ tp_channel_manager_emit_new_channel (fac,
+ TP_EXPORTABLE_CHANNEL (text_chan), requests_satisfied_text);
+ }
+
/* Announce tube channels now */
tube_channels = g_hash_table_lookup (priv->text_needed_for_tube, text_chan);
+
if (tube_channels != NULL)
{
GList *l;
for (l = tube_channels->head; l != NULL; l = l->next)
{
- GabbleTubeIface *tube_chan = GABBLE_TUBE_IFACE (l->data);
+ TpExportableChannel *tube_chan = TP_EXPORTABLE_CHANNEL (l->data);
GSList *requests_satisfied_tube;
requests_satisfied_tube = g_hash_table_lookup (
priv->queued_requests, tube_chan);
g_hash_table_steal (priv->queued_requests, tube_chan);
+
requests_satisfied_tube = g_slist_reverse (requests_satisfied_tube);
- g_hash_table_insert (channels, tube_chan, requests_satisfied_tube);
+ tp_channel_manager_emit_new_channel (fac, tube_chan,
+ requests_satisfied_tube);
+ g_slist_free (requests_satisfied_tube);
}
g_hash_table_remove (priv->text_needed_for_tube, text_chan);
}
-
- /* only announce channels which are on the bus (requested or
- * requested with an invite, not channels only around because they
- * have to be) */
- if (tp_base_channel_is_registered (base))
- {
- tp_channel_manager_emit_new_channel (fac,
- TP_EXPORTABLE_CHANNEL (text_chan), requests_satisfied_text);
- }
-
- tp_channel_manager_emit_new_channels (fac, channels);
-
- g_hash_table_unref (channels);
}
static void
diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c
index 48b421165..b70f1b069 100644
--- a/src/private-tubes-factory.c
+++ b/src/private-tubes-factory.c
@@ -89,8 +89,6 @@ struct _GabblePrivateTubesFactoryPrivate
gboolean dispose_has_run;
};
-#define GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE(obj) ((obj)->priv)
-
static const gchar * const tubes_channel_fixed_properties[] = {
TP_PROP_CHANNEL_CHANNEL_TYPE,
TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
@@ -107,7 +105,7 @@ gboolean
gabble_private_tubes_factory_extract_tube_information (
TpHandleRepoIface *contact_repo,
WockyNode *tube_node,
- TpTubeType *type,
+ TubeType *type,
TpHandle *initiator_handle,
const gchar **service,
GHashTable **parameters,
@@ -121,11 +119,11 @@ gabble_private_tubes_factory_extract_tube_information (
if (!tp_strdiff (_type, "stream"))
{
- *type = TP_TUBE_TYPE_STREAM;
+ *type = TUBE_TYPE_STREAM;
}
else if (!tp_strdiff (_type, "dbus"))
{
- *type = TP_TUBE_TYPE_DBUS;
+ *type = TUBE_TYPE_DBUS;
}
else
{
@@ -197,16 +195,14 @@ gabble_private_tubes_factory_extract_tube_information (
static void
gabble_private_tubes_factory_init (GabblePrivateTubesFactory *self)
{
- GabblePrivateTubesFactoryPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
GABBLE_TYPE_PRIVATE_TUBES_FACTORY, GabblePrivateTubesFactoryPrivate);
- self->priv = priv;
-
- priv->tubes = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ self->priv->tubes = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify) g_object_unref);
- priv->conn = NULL;
- priv->dispose_has_run = FALSE;
+ self->priv->conn = NULL;
+ self->priv->dispose_has_run = FALSE;
}
@@ -220,15 +216,15 @@ porter_available_cb (
gpointer user_data)
{
GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (user_data);
- GabblePrivateTubesFactoryPrivate *priv = self->priv;
- priv->msg_tube_cb = wocky_porter_register_handler_from_anyone (porter,
+ self->priv->msg_tube_cb = wocky_porter_register_handler_from_anyone (porter,
WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE,
WOCKY_PORTER_HANDLER_PRIORITY_MAX,
private_tubes_factory_msg_tube_cb, self,
'(', "tube", ':', NS_TUBES,
')', NULL);
- priv->msg_close_cb = wocky_porter_register_handler_from_anyone (porter,
+
+ self->priv->msg_close_cb = wocky_porter_register_handler_from_anyone (porter,
WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE,
WOCKY_PORTER_HANDLER_PRIORITY_MAX,
private_tubes_factory_tube_close_cb, self,
@@ -258,17 +254,15 @@ gabble_private_tubes_factory_constructor (GType type,
{
GObject *obj;
GabblePrivateTubesFactory *self;
- GabblePrivateTubesFactoryPrivate *priv;
obj = G_OBJECT_CLASS (gabble_private_tubes_factory_parent_class)->
constructor (type, n_props, props);
self = GABBLE_PRIVATE_TUBES_FACTORY (obj);
- priv = GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
self->priv->status_changed_id = g_signal_connect (self->priv->conn,
"status-changed", (GCallback) connection_status_changed_cb, obj);
- tp_g_signal_connect_object (priv->conn, "porter-available",
+ tp_g_signal_connect_object (self->priv->conn, "porter-available",
(GCallback) porter_available_cb, obj, 0);
return obj;
@@ -278,18 +272,16 @@ gabble_private_tubes_factory_constructor (GType type,
static void
gabble_private_tubes_factory_dispose (GObject *object)
{
- GabblePrivateTubesFactory *fac = GABBLE_PRIVATE_TUBES_FACTORY (object);
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (fac);
+ GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (object);
- if (priv->dispose_has_run)
+ if (self->priv->dispose_has_run)
return;
DEBUG ("dispose called");
- priv->dispose_has_run = TRUE;
+ self->priv->dispose_has_run = TRUE;
- gabble_private_tubes_factory_close_all (fac);
- g_assert (priv->tubes == NULL);
+ gabble_private_tubes_factory_close_all (self);
+ g_assert (self->priv->tubes == NULL);
if (G_OBJECT_CLASS (gabble_private_tubes_factory_parent_class)->dispose)
G_OBJECT_CLASS (gabble_private_tubes_factory_parent_class)->dispose (
@@ -302,14 +294,12 @@ gabble_private_tubes_factory_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
- GabblePrivateTubesFactory *fac = GABBLE_PRIVATE_TUBES_FACTORY (object);
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (fac);
+ GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (object);
switch (property_id)
{
case PROP_CONNECTION:
- g_value_set_object (value, priv->conn);
+ g_value_set_object (value, self->priv->conn);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -323,14 +313,12 @@ gabble_private_tubes_factory_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- GabblePrivateTubesFactory *fac = GABBLE_PRIVATE_TUBES_FACTORY (object);
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (fac);
+ GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (object);
switch (property_id)
{
case PROP_CONNECTION:
- priv->conn = g_value_get_object (value);
+ self->priv->conn = g_value_get_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -366,37 +354,35 @@ gabble_private_tubes_factory_class_init (
}
static void
-gabble_private_tubes_factory_close_all (GabblePrivateTubesFactory *fac)
+gabble_private_tubes_factory_close_all (GabblePrivateTubesFactory *self)
{
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (fac);
-
DEBUG ("closing 1-1 tubes channels");
- if (priv->status_changed_id != 0)
+ if (self->priv->status_changed_id != 0)
{
- g_signal_handler_disconnect (priv->conn,
- priv->status_changed_id);
- priv->status_changed_id = 0;
+ g_signal_handler_disconnect (self->priv->conn,
+ self->priv->status_changed_id);
+ self->priv->status_changed_id = 0;
}
- if (priv->msg_tube_cb != 0)
+ if (self->priv->msg_tube_cb != 0)
{
- WockyPorter *porter = wocky_session_get_porter (priv->conn->session);
+ WockyPorter *porter = wocky_session_get_porter (
+ self->priv->conn->session);
- wocky_porter_unregister_handler (porter, priv->msg_tube_cb);
- priv->msg_tube_cb = 0;
- wocky_porter_unregister_handler (porter, priv->msg_close_cb);
- priv->msg_close_cb = 0;
+ wocky_porter_unregister_handler (porter, self->priv->msg_tube_cb);
+ self->priv->msg_tube_cb = 0;
+ wocky_porter_unregister_handler (porter, self->priv->msg_close_cb);
+ self->priv->msg_close_cb = 0;
}
- tp_clear_pointer (&priv->tubes, g_hash_table_unref);
+ tp_clear_pointer (&self->priv->tubes, g_hash_table_unref);
}
static void
add_service_to_array (const gchar *service,
GPtrArray *arr,
- TpTubeType type,
+ TubeType type,
TpHandle handle)
{
GValue monster = {0, };
@@ -410,7 +396,7 @@ add_service_to_array (const gchar *service,
NULL
};
- g_assert (type == TP_TUBE_TYPE_STREAM || type == TP_TUBE_TYPE_DBUS);
+ g_assert (type == TUBE_TYPE_STREAM || type == TUBE_TYPE_DBUS);
g_value_init (&monster, TP_STRUCT_TYPE_REQUESTABLE_CHANNEL_CLASS);
g_value_take_boxed (&monster,
@@ -421,7 +407,7 @@ add_service_to_array (const gchar *service,
(GDestroyNotify) tp_g_value_slice_free);
channel_type_value = tp_g_value_slice_new (G_TYPE_STRING);
- if (type == TP_TUBE_TYPE_STREAM)
+ if (type == TUBE_TYPE_STREAM)
g_value_set_static_string (channel_type_value,
TP_IFACE_CHANNEL_TYPE_STREAM_TUBE);
else
@@ -437,7 +423,7 @@ add_service_to_array (const gchar *service,
target_handle_type_value = tp_g_value_slice_new (G_TYPE_STRING);
g_value_set_string (target_handle_type_value, service);
- if (type == TP_TUBE_TYPE_STREAM)
+ if (type == TUBE_TYPE_STREAM)
g_hash_table_insert (fixed_properties,
TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE,
target_handle_type_value);
@@ -546,10 +532,10 @@ get_contact_caps_foreach (gpointer data,
if (g_str_has_prefix (ns, STREAM_CAP_PREFIX))
add_service_to_array (ns + strlen (STREAM_CAP_PREFIX), closure->arr,
- TP_TUBE_TYPE_STREAM, closure->handle);
+ TUBE_TYPE_STREAM, closure->handle);
else if (g_str_has_prefix (ns, DBUS_CAP_PREFIX))
add_service_to_array (ns + strlen (DBUS_CAP_PREFIX), closure->arr,
- TP_TUBE_TYPE_DBUS, closure->handle);
+ TUBE_TYPE_DBUS, closure->handle);
}
static void
@@ -591,8 +577,7 @@ gabble_private_tubes_factory_add_cap (GabbleCapsChannelManager *manager,
TP_PROP_CHANNEL_CHANNEL_TYPE);
/* this channel is not for this factory */
- if (tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_TUBES) &&
- tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE) &&
+ if (tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE) &&
tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_DBUS_TUBE))
return;
@@ -665,15 +650,13 @@ gabble_private_tubes_factory_foreach_channel (TpChannelManager *manager,
TpExportableChannelFunc foreach,
gpointer user_data)
{
- GabblePrivateTubesFactory *fac = GABBLE_PRIVATE_TUBES_FACTORY (manager);
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (fac);
+ GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (manager);
struct _ForeachData data;
data.user_data = user_data;
data.foreach = foreach;
- g_hash_table_foreach (priv->tubes, _foreach_slave, &data);
+ g_hash_table_foreach (self->priv->tubes, _foreach_slave, &data);
}
void
@@ -684,9 +667,8 @@ gabble_private_tubes_factory_handle_si_tube_request (
const gchar *stream_id,
WockyStanza *msg)
{
- GabblePrivateTubesFactoryPrivate *priv = self->priv;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
+ (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT);
WockyNode *si_node, *tube_node;
WockyStanzaType stanza_type;
WockyStanzaSubType sub_type;
@@ -718,7 +700,7 @@ gabble_private_tubes_factory_handle_si_tube_request (
return;
}
- tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id));
+ tube = g_hash_table_lookup (self->priv->tubes, GUINT_TO_POINTER (tube_id));
if (tube != NULL)
{
GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
@@ -742,10 +724,8 @@ gabble_private_tubes_factory_handle_si_stream_request (
const gchar *stream_id,
WockyStanza *msg)
{
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
+ (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT);
const gchar *tmp;
guint64 tube_id;
WockyNode *si_node, *stream_node;
@@ -789,7 +769,7 @@ gabble_private_tubes_factory_handle_si_stream_request (
return;
}
- tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id));
+ tube = g_hash_table_lookup (self->priv->tubes, GUINT_TO_POINTER (tube_id));
if (tube == NULL)
{
GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
@@ -814,10 +794,8 @@ tube_msg_checks (GabblePrivateTubesFactory *self,
TpHandle *out_handle,
guint64 *out_tube_id)
{
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
+ (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT);
const gchar *from, *tmp;
TpHandle handle;
guint64 tube_id;
@@ -867,8 +845,6 @@ private_tubes_factory_msg_tube_cb (
gpointer user_data)
{
GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (user_data);
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
WockyNode *node;
guint64 tube_id;
GabbleTubeIface *channel;
@@ -881,7 +857,7 @@ private_tubes_factory_msg_tube_cb (
if (!tube_msg_checks (self, msg, node, &handle, &tube_id))
return FALSE;
- channel = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id));
+ channel = g_hash_table_lookup (self->priv->tubes, GUINT_TO_POINTER (tube_id));
if (channel != NULL)
{
@@ -914,12 +890,10 @@ private_tubes_factory_tube_close_cb (
gpointer user_data)
{
GabblePrivateTubesFactory *self = GABBLE_PRIVATE_TUBES_FACTORY (user_data);
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
WockyNode *node;
guint64 tube_id;
GabbleTubeIface *channel;
- TpTubeType type;
+ TubeType type;
node = wocky_node_get_child_ns (
wocky_stanza_get_top_node (msg), "close", NS_TUBES);
@@ -928,7 +902,7 @@ private_tubes_factory_tube_close_cb (
if (!tube_msg_checks (self, msg, node, NULL, &tube_id))
return FALSE;
- channel = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id));
+ channel = g_hash_table_lookup (self->priv->tubes, GUINT_TO_POINTER (tube_id));
if (channel == NULL)
{
@@ -937,7 +911,7 @@ private_tubes_factory_tube_close_cb (
}
g_object_get (channel, "type", &type, NULL);
- if (type != TP_TUBE_TYPE_STREAM)
+ if (type != TUBE_TYPE_STREAM)
{
DEBUG ("Only stream tubes can be closed using a close message");
return TRUE;
@@ -955,12 +929,10 @@ gabble_private_tubes_factory_lookup (GabblePrivateTubesFactory *self,
TpHandle handle,
const gchar *service)
{
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
GHashTableIter iter;
gpointer value;
- g_hash_table_iter_init (&iter, priv->tubes);
+ g_hash_table_iter_init (&iter, self->priv->tubes);
while (g_hash_table_iter_next (&iter, NULL, &value))
{
GabbleTubeIface *tube = value;
@@ -994,9 +966,7 @@ static void
channel_closed_cb (GabbleTubeIface *tube,
GabblePrivateTubesFactory *self)
{
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
- guint id;
+ guint64 id;
g_object_get (tube,
"id", &id,
@@ -1005,15 +975,13 @@ channel_closed_cb (GabbleTubeIface *tube,
tp_channel_manager_emit_channel_closed_for_object (self,
TP_EXPORTABLE_CHANNEL (tube));
- if (priv->tubes != NULL)
- g_hash_table_remove (priv->tubes, GUINT_TO_POINTER (id));
+ if (self->priv->tubes != NULL)
+ g_hash_table_remove (self->priv->tubes, GUINT_TO_POINTER (id));
}
static guint64
generate_tube_id (GabblePrivateTubesFactory *self)
{
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
guint out;
/* probably totally overkill */
@@ -1021,7 +989,7 @@ generate_tube_id (GabblePrivateTubesFactory *self)
{
out = g_random_int_range (1, G_MAXINT32);
}
- while (g_hash_table_lookup (priv->tubes,
+ while (g_hash_table_lookup (self->priv->tubes,
GUINT_TO_POINTER (out)) != NULL);
return out;
@@ -1033,10 +1001,8 @@ static GabbleTubeIface *
new_channel_from_request (GabblePrivateTubesFactory *self,
GHashTable *request)
{
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
GabbleTubeIface *tube;
- TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn);
+ TpBaseConnection *base_conn = TP_BASE_CONNECTION (self->priv->conn);
gchar *stream_id;
@@ -1063,7 +1029,7 @@ new_channel_from_request (GabblePrivateTubesFactory *self,
service = tp_asv_get_string (request,
TP_PROP_CHANNEL_TYPE_STREAM_TUBE_SERVICE);
- tube = GABBLE_TUBE_IFACE (gabble_tube_stream_new (priv->conn,
+ tube = GABBLE_TUBE_IFACE (gabble_tube_stream_new (self->priv->conn,
handle, handle_type,
tp_base_connection_get_self_handle (base_conn),
tp_base_connection_get_self_handle (base_conn),
@@ -1076,7 +1042,7 @@ new_channel_from_request (GabblePrivateTubesFactory *self,
stream_id = gabble_bytestream_factory_generate_stream_id ();
- tube = GABBLE_TUBE_IFACE (gabble_tube_dbus_new (priv->conn,
+ tube = GABBLE_TUBE_IFACE (gabble_tube_dbus_new (self->priv->conn,
handle, handle_type,
tp_base_connection_get_self_handle (base_conn),
tp_base_connection_get_self_handle (base_conn),
@@ -1094,7 +1060,7 @@ new_channel_from_request (GabblePrivateTubesFactory *self,
g_signal_connect (tube, "closed",
G_CALLBACK (channel_closed_cb), self);
- g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id),
+ g_hash_table_insert (self->priv->tubes, GUINT_TO_POINTER (tube_id),
tube);
g_hash_table_unref (parameters);
@@ -1107,15 +1073,13 @@ send_tube_close_msg (GabblePrivateTubesFactory *self,
const gchar *jid,
guint64 tube_id)
{
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
WockyPorter *porter;
WockyStanza *msg;
gchar *id_str;
id_str = g_strdup_printf ("%" G_GUINT64_FORMAT, tube_id);
- porter = gabble_connection_dup_porter (priv->conn);
+ porter = gabble_connection_dup_porter (self->priv->conn);
/* Send the close message */
msg = wocky_stanza_build (WOCKY_STANZA_TYPE_MESSAGE, WOCKY_STANZA_SUB_TYPE_NONE,
@@ -1143,14 +1107,12 @@ new_channel_from_stanza (GabblePrivateTubesFactory *self,
guint64 tube_id,
GabbleBytestreamIface *bytestream)
{
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
GabbleTubeIface *tube;
- TpBaseConnection *base_conn = TP_BASE_CONNECTION (priv->conn);
+ TpBaseConnection *base_conn = TP_BASE_CONNECTION (self->priv->conn);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
+ (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT);
- TpTubeType type;
+ TubeType type;
TpHandle handle;
const gchar *service;
GHashTable *parameters;
@@ -1169,13 +1131,13 @@ new_channel_from_stanza (GabblePrivateTubesFactory *self,
return NULL;
}
- if (bytestream == NULL && type != TP_TUBE_TYPE_STREAM)
+ if (bytestream == NULL && type != TUBE_TYPE_STREAM)
{
DEBUG ("Only stream tubes are allowed to be created using messages");
send_tube_close_msg (self, wocky_stanza_get_from (stanza), tube_id);
return NULL;
}
- else if (bytestream != NULL && type != TP_TUBE_TYPE_DBUS)
+ else if (bytestream != NULL && type != TUBE_TYPE_DBUS)
{
GError e = { WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_FORBIDDEN,
"Only D-Bus tubes are allowed to be created using SI" };
@@ -1185,9 +1147,9 @@ new_channel_from_stanza (GabblePrivateTubesFactory *self,
return NULL;
}
- if (type == TP_TUBE_TYPE_STREAM)
+ if (type == TUBE_TYPE_STREAM)
{
- tube = GABBLE_TUBE_IFACE (gabble_tube_stream_new (priv->conn,
+ tube = GABBLE_TUBE_IFACE (gabble_tube_stream_new (self->priv->conn,
handle, TP_HANDLE_TYPE_CONTACT,
tp_base_connection_get_self_handle (base_conn),
handle, service, parameters, tube_id, NULL, FALSE));
@@ -1204,7 +1166,7 @@ new_channel_from_stanza (GabblePrivateTubesFactory *self,
stream_id = wocky_node_get_attribute (si_node, "id");
g_return_val_if_fail (stream_id != NULL, NULL);
- tube = GABBLE_TUBE_IFACE (gabble_tube_dbus_new (priv->conn,
+ tube = GABBLE_TUBE_IFACE (gabble_tube_dbus_new (self->priv->conn,
handle, TP_HANDLE_TYPE_CONTACT,
tp_base_connection_get_self_handle (base_conn),
handle, service, parameters,
@@ -1216,7 +1178,7 @@ new_channel_from_stanza (GabblePrivateTubesFactory *self,
g_signal_connect (tube, "closed",
G_CALLBACK (channel_closed_cb), self);
- g_hash_table_insert (priv->tubes, GUINT_TO_POINTER (tube_id),
+ g_hash_table_insert (self->priv->tubes, GUINT_TO_POINTER (tube_id),
tube);
g_hash_table_unref (parameters);
diff --git a/src/private-tubes-factory.h b/src/private-tubes-factory.h
index d9e01f17a..5725b7f94 100644
--- a/src/private-tubes-factory.h
+++ b/src/private-tubes-factory.h
@@ -23,9 +23,11 @@
#include <glib-object.h>
#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
#include "connection.h"
#include "bytestream-iface.h"
+#include "tube-iface.h"
G_BEGIN_DECLS
@@ -77,7 +79,7 @@ void gabble_private_tubes_factory_handle_si_stream_request (
gboolean gabble_private_tubes_factory_extract_tube_information (
TpHandleRepoIface *contact_repo, WockyNode *tube_node,
- TpTubeType *type, TpHandle *initiator_handle,
+ TubeType *type, TpHandle *initiator_handle,
const gchar **service, GHashTable **parameters,
guint64 *tube_id);
diff --git a/src/protocol.c b/src/protocol.c
index deeaa8d9e..d89b8a11b 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -30,6 +30,7 @@
#include "extensions/extensions.h"
+#include "conn-avatars.h"
#include "conn-presence.h"
#include "connection.h"
@@ -330,6 +331,7 @@ get_interfaces_array (TpBaseProtocol *self)
g_ptr_array_add (interfaces, TP_IFACE_PROTOCOL_INTERFACE_PRESENCE);
g_ptr_array_add (interfaces, TP_IFACE_PROTOCOL_INTERFACE_ADDRESSING);
+ g_ptr_array_add (interfaces, TP_IFACE_PROTOCOL_INTERFACE_AVATARS);
return interfaces;
}
@@ -454,6 +456,21 @@ addressing_normalize_contact_uri (TpBaseProtocol *self,
}
static void
+get_avatar_details (TpBaseProtocol *base,
+ GStrv *supported_mime_types,
+ guint *min_height,
+ guint *min_width,
+ guint *rec_height,
+ guint *rec_width,
+ guint *max_height,
+ guint *max_width,
+ guint *max_bytes)
+{
+ gabble_connection_dup_avatar_requirements (supported_mime_types, min_height,
+ min_width, rec_height, rec_width, max_height, max_width, max_bytes);
+}
+
+static void
gabble_jabber_protocol_class_init (GabbleJabberProtocolClass *klass)
{
TpBaseProtocolClass *base_class =
@@ -467,6 +484,7 @@ gabble_jabber_protocol_class_init (GabbleJabberProtocolClass *klass)
base_class->get_connection_details = get_connection_details;
base_class->get_statuses = get_presence_statuses;
base_class->dup_authentication_types = dup_authentication_types;
+ base_class->get_avatar_details = get_avatar_details;
}
TpBaseProtocol *
diff --git a/src/roster.c b/src/roster.c
index d2cc4dae8..4c7300be2 100644
--- a/src/roster.c
+++ b/src/roster.c
@@ -63,7 +63,8 @@ struct _GabbleRosterPrivate
guint presence_cb;
GHashTable *items;
- TpHandleSet *groups;
+ /* Used as a set of own (gchar *) */
+ GHashTable *groups;
/* set of contacts whose subscription requests will automatically be
* accepted during this session */
@@ -114,8 +115,8 @@ struct _GabbleRosterItemEdit
/* if TRUE, disregard new_name and remove name='' from the roster item */
gboolean remove_name;
- TpHandleSet *add_to_groups;
- TpHandleSet *remove_from_groups;
+ GHashTable *add_to_groups;
+ GHashTable *remove_from_groups;
gboolean remove_from_all_other_groups;
};
@@ -127,7 +128,7 @@ struct _GabbleRosterItem
GoogleItemType google_type;
gchar *name;
gchar *alias_for;
- TpHandleSet *groups;
+ GHashTable *groups;
/* if TRUE, an edit attempt is already "in-flight" so we can't send off
* edits immediately - instead, store them in unsent_edits */
gboolean edits_in_flight;
@@ -230,7 +231,7 @@ _gabble_roster_item_free (GabbleRosterItem *item)
{
g_assert (item != NULL);
- tp_handle_set_destroy (item->groups);
+ g_hash_table_unref (item->groups);
item_edit_free (item->unsent_edits);
g_free (item->name);
g_free (item->alias_for);
@@ -288,13 +289,11 @@ _parse_item_subscription (WockyNode *item_node)
}
}
-static TpHandleSet *
+static GHashTable *
_parse_item_groups (WockyNode *item_node, TpBaseConnection *conn)
{
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- conn, TP_HANDLE_TYPE_GROUP);
- TpHandleSet *groups = tp_handle_set_new (group_repo);
- TpHandle handle;
+ GHashTable *groups = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
WockyNodeIter i;
WockyNode *group_node;
@@ -306,10 +305,7 @@ _parse_item_groups (WockyNode *item_node, TpBaseConnection *conn)
if (NULL == value)
continue;
- handle = tp_handle_ensure (group_repo, value, NULL, NULL);
- if (!handle)
- continue;
- tp_handle_set_add (groups, handle);
+ g_hash_table_add (groups, g_strdup (value));
}
return groups;
@@ -409,8 +405,6 @@ _gabble_roster_item_ensure (GabbleRoster *roster,
TpHandle handle)
{
GabbleRosterPrivate *priv = roster->priv;
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_GROUP);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
(TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
GabbleRosterItem *item;
@@ -444,7 +438,8 @@ _gabble_roster_item_ensure (GabbleRoster *roster,
item->subscribe = TP_SUBSCRIPTION_STATE_NO;
item->publish = TP_SUBSCRIPTION_STATE_NO;
item->name = alias;
- item->groups = tp_handle_set_new (group_repo);
+ item->groups = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
g_hash_table_insert (priv->items, GUINT_TO_POINTER (handle), item);
}
@@ -500,6 +495,87 @@ _gabble_roster_item_maybe_remove (GabbleRoster *roster,
return TRUE;
}
+/* Add all the groups from @set to @add using @copy to duplicate them into
+ * @set.
+ * Returns (transfer full) the groups which have been actually added.
+ */
+static GHashTable *
+group_set_update (GHashTable *set,
+ GHashTable *add)
+{
+ GHashTable *added = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+ GHashTableIter iter;
+ gpointer k;
+
+ g_hash_table_iter_init (&iter, add);
+ while (g_hash_table_iter_next (&iter, &k, NULL))
+ {
+ if (!g_hash_table_contains (set, k))
+ {
+ g_hash_table_add (set, g_strdup (k));
+ g_hash_table_add (added, g_strdup (k));
+ }
+ }
+
+ return added;
+}
+
+static void
+group_set_difference_update (GHashTable *set,
+ GHashTable *other)
+{
+ GHashTableIter iter;
+ gpointer k;
+
+ g_hash_table_iter_init (&iter, other);
+ while (g_hash_table_iter_next (&iter, &k, NULL))
+ {
+ g_hash_table_remove (set, k);
+ }
+}
+
+/* Returns (transfer full) the set of groups which are in @left and not
+ * in @right */
+static GHashTable *
+group_set_difference (GHashTable *left,
+ GHashTable *right)
+{
+ GHashTable *diff = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+ GHashTableIter iter;
+ gpointer k;
+
+ g_hash_table_iter_init (&iter, left);
+ while (g_hash_table_iter_next (&iter, &k, NULL))
+ {
+ if (!g_hash_table_contains (right, k))
+ g_hash_table_add (diff, g_strdup (k));
+ }
+
+ return diff;
+}
+
+static gboolean
+group_set_is_equal (GHashTable *left,
+ GHashTable *right)
+{
+ GHashTableIter iter;
+ gpointer k;
+
+ if (g_hash_table_size (left) != g_hash_table_size (right))
+ return FALSE;
+
+ g_hash_table_iter_init (&iter, left);
+ while (g_hash_table_iter_next (&iter, &k, NULL))
+ {
+ if (!g_hash_table_contains (right, k))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static GabbleRosterItem *
_gabble_roster_item_update (GabbleRoster *roster,
TpHandle contact_handle,
@@ -510,13 +586,10 @@ _gabble_roster_item_update (GabbleRoster *roster,
GabbleRosterPrivate *priv = roster->priv;
GabbleRosterItem *item;
const gchar *ask, *name;
- TpIntset *new_groups, *added_to, *removed_from, *removed_from2;
- TpHandleSet *new_groups_handle_set, *old_groups;
+ GHashTable *new_groups, *removed_from, *added_to;
TpBaseContactList *base = (TpBaseContactList *) roster;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
(TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_GROUP);
g_assert (roster != NULL);
g_assert (GABBLE_IS_ROSTER (roster));
@@ -560,40 +633,36 @@ _gabble_roster_item_update (GabbleRoster *roster,
*nickname_updated = FALSE;
}
- new_groups_handle_set = _parse_item_groups (node,
+ new_groups = _parse_item_groups (node,
(TpBaseConnection *) priv->conn);
- new_groups = tp_handle_set_peek (new_groups_handle_set);
- old_groups = tp_handle_set_copy (item->groups);
- removed_from = tp_intset_difference (tp_handle_set_peek (item->groups),
- new_groups);
- added_to = tp_handle_set_update (item->groups, new_groups);
- removed_from2 = tp_handle_set_difference_update (item->groups, removed_from);
+ removed_from = group_set_difference (item->groups, new_groups);
+ added_to = group_set_update (item->groups, new_groups);
+ group_set_difference_update (item->groups, removed_from);
if (roster->priv->groups != NULL)
{
- TpIntset *created_groups = tp_handle_set_update (roster->priv->groups,
- new_groups);
+ GHashTable *created_groups;
+
+ created_groups = group_set_update (roster->priv->groups, new_groups);
/* we don't need to do this work if TpBaseContactList will just be
* ignoring it, as it will before we've received the roster */
if (tp_base_contact_list_get_state ((TpBaseContactList *) roster,
NULL) == TP_CONTACT_LIST_STATE_SUCCESS &&
- !tp_intset_is_empty (created_groups))
+ g_hash_table_size (created_groups) > 0)
{
- GPtrArray *strv = g_ptr_array_sized_new (tp_intset_size (
+ GPtrArray *strv = g_ptr_array_sized_new (g_hash_table_size (
created_groups));
- TpIntsetFastIter iter;
- TpHandle group;
-
- tp_intset_fast_iter_init (&iter, created_groups);
+ GHashTableIter iter;
+ gpointer k;
- while (tp_intset_fast_iter_next (&iter, &group))
+ g_hash_table_iter_init (&iter, created_groups);
+ while (g_hash_table_iter_next (&iter, &k, NULL))
{
- const gchar *group_name = tp_handle_inspect (group_repo,
- group);
+ const gchar *group_name = k;
- DEBUG ("Group was just created: #%u '%s'", group, group_name);
+ DEBUG ("Group was just created: '%s'", group_name);
g_ptr_array_add (strv, (gchar *) group_name);
}
@@ -603,7 +672,7 @@ _gabble_roster_item_update (GabbleRoster *roster,
g_ptr_array_unref (strv);
}
- tp_clear_pointer (&created_groups, tp_intset_destroy);
+ tp_clear_pointer (&created_groups, g_hash_table_unref);
}
/* We emit one GroupsChanged signal per contact, because that's most natural
@@ -614,38 +683,35 @@ _gabble_roster_item_update (GabbleRoster *roster,
* recover state. */
if (tp_base_contact_list_get_state (base, NULL) ==
TP_CONTACT_LIST_STATE_SUCCESS &&
- (!tp_intset_is_empty (added_to) || !tp_intset_is_empty (removed_from)))
+ (g_hash_table_size (added_to) > 0 ||
+ g_hash_table_size (removed_from) > 0))
{
- GPtrArray *added_names = g_ptr_array_sized_new (tp_intset_size (added_to));
+ GPtrArray *added_names = g_ptr_array_sized_new (
+ g_hash_table_size (added_to));
GPtrArray *removed_names = g_ptr_array_sized_new (
- tp_intset_size (removed_from));
+ g_hash_table_size (removed_from));
TpHandleSet *the_contact = tp_handle_set_new (contact_repo);
- TpIntsetFastIter iter;
- TpHandle group;
+ GHashTableIter iter;
+ gpointer k;
tp_handle_set_add (the_contact, contact_handle);
- tp_intset_fast_iter_init (&iter, added_to);
-
- while (tp_intset_fast_iter_next (&iter, &group))
+ g_hash_table_iter_init (&iter, added_to);
+ while (g_hash_table_iter_next (&iter, &k, NULL))
{
- const gchar *group_name = tp_handle_inspect (group_repo,
- group);
+ const gchar *group_name = k;
- DEBUG ("Contact #%u added to group #%u '%s'", contact_handle, group,
- group_name);
+ DEBUG ("Contact #%u added to group '%s'", contact_handle, group_name);
g_ptr_array_add (added_names, (gchar *) group_name);
}
- tp_intset_fast_iter_init (&iter, removed_from);
-
- while (tp_intset_fast_iter_next (&iter, &group))
+ g_hash_table_iter_init (&iter, removed_from);
+ while (g_hash_table_iter_next (&iter, &k, NULL))
{
- const gchar *group_name = tp_handle_inspect (group_repo,
- group);
+ const gchar *group_name = k;
- DEBUG ("Contact #%u removed from group #%u '%s'", contact_handle,
- group, group_name);
+ DEBUG ("Contact #%u removed from group '%s'", contact_handle,
+ group_name);
g_ptr_array_add (removed_names, (gchar *) group_name);
}
@@ -655,12 +721,9 @@ _gabble_roster_item_update (GabbleRoster *roster,
(const gchar * const *) removed_names->pdata, removed_names->len);
}
- tp_intset_destroy (added_to);
- tp_intset_destroy (removed_from);
- tp_intset_destroy (removed_from2);
- new_groups = NULL;
- tp_handle_set_destroy (new_groups_handle_set);
- tp_handle_set_destroy (old_groups);
+ g_hash_table_unref (added_to);
+ g_hash_table_unref (removed_from);
+ g_hash_table_unref (new_groups);
return item;
}
@@ -668,9 +731,13 @@ _gabble_roster_item_update (GabbleRoster *roster,
#ifdef ENABLE_DEBUG
static void
-_gabble_roster_item_dump_group (guint handle, gpointer user_data)
+_gabble_roster_item_dump_group (gpointer k,
+ gpointer v,
+ gpointer user_data)
{
- g_string_append_printf ((GString *) user_data, "group#%u ", handle);
+ const gchar *group = k;
+
+ g_string_append_printf ((GString *) user_data, "group '%s'", group);
}
static gchar *
@@ -696,8 +763,7 @@ _gabble_roster_item_dump (GabbleRosterItem *item)
if (item->groups)
{
- tp_intset_foreach (tp_handle_set_peek (item->groups),
- _gabble_roster_item_dump_group, str);
+ g_hash_table_foreach (item->groups, _gabble_roster_item_dump_group, str);
}
return g_string_free (str, FALSE);
@@ -743,21 +809,15 @@ _gabble_roster_message_new (GabbleRoster *roster,
}
-struct _ItemToMessageContext {
- TpBaseConnection *conn;
- WockyNode *item_node;
-};
-
static void
-_gabble_roster_item_put_group_in_message (guint handle, gpointer user_data)
+_gabble_roster_item_put_group_in_message (gpointer k,
+ gpointer v,
+ gpointer user_data)
{
- struct _ItemToMessageContext *ctx =
- (struct _ItemToMessageContext *)user_data;
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- ctx->conn, TP_HANDLE_TYPE_GROUP);
- const char *name = tp_handle_inspect (group_repo, handle);
+ const char *name = k;
+ WockyNode *item_node = user_data;
- wocky_node_add_child_with_content (ctx->item_node, "group", name);
+ wocky_node_add_child_with_content (item_node, "group", name);
}
/*
@@ -780,9 +840,6 @@ _gabble_roster_item_to_message (GabbleRoster *roster,
WockyStanza *message;
WockyNode *query_node, *item_node;
const gchar *jid;
- struct _ItemToMessageContext ctx = {
- (TpBaseConnection *) priv->conn,
- };
g_assert (roster != NULL);
g_assert (GABBLE_IS_ROSTER (roster));
@@ -793,7 +850,6 @@ _gabble_roster_item_to_message (GabbleRoster *roster,
&query_node);
item_node = wocky_node_add_child (query_node, "item");
- ctx.item_node = item_node;
jid = tp_handle_inspect (contact_repo, handle);
wocky_node_set_attribute (item_node, "jid", jid);
@@ -825,9 +881,8 @@ _gabble_roster_item_to_message (GabbleRoster *roster,
if (item->groups)
{
- tp_intset_foreach (tp_handle_set_peek (item->groups),
- _gabble_roster_item_put_group_in_message,
- (void *)&ctx);
+ g_hash_table_foreach (item->groups,
+ _gabble_roster_item_put_group_in_message, item_node);
}
DONE:
@@ -1685,7 +1740,7 @@ gabble_roster_close_all (GabbleRoster *self)
self->priv->porter_available_id = 0;
}
- tp_clear_pointer (&priv->groups, tp_handle_set_destroy);
+ tp_clear_pointer (&priv->groups, g_hash_table_unref);
tp_clear_pointer (&priv->pre_authorized, tp_handle_set_destroy);
if (self->priv->cancel_on_disconnect != NULL)
@@ -1814,7 +1869,6 @@ gabble_roster_constructed (GObject *obj)
TpBaseContactList *base = TP_BASE_CONTACT_LIST (obj);
void (*chain_up)(GObject *) =
((GObjectClass *) gabble_roster_parent_class)->constructed;
- TpHandleRepoIface *group_repo;
TpHandleRepoIface *contact_repo;
if (chain_up != NULL)
@@ -1830,8 +1884,6 @@ gabble_roster_constructed (GObject *obj)
base, NULL));
g_assert (GABBLE_IS_CONNECTION (self->priv->conn));
- group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP);
contact_repo = tp_base_connection_get_handles (
(TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT);
@@ -1840,7 +1892,8 @@ gabble_roster_constructed (GObject *obj)
self->priv->porter_available_id = g_signal_connect (self->priv->conn,
"porter-available", G_CALLBACK (gabble_roster_porter_available_cb), obj);
- self->priv->groups = tp_handle_set_new (group_repo);
+ self->priv->groups = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
self->priv->pre_authorized = tp_handle_set_new (contact_repo);
}
@@ -1886,8 +1939,8 @@ item_edit_free (GabbleRosterItemEdit *edits)
g_slist_free (edits->results);
g_object_unref (edits->contact_repo);
- tp_clear_pointer (&edits->add_to_groups, tp_handle_set_destroy);
- tp_clear_pointer (&edits->remove_from_groups, tp_handle_set_destroy);
+ tp_clear_pointer (&edits->add_to_groups, g_hash_table_unref);
+ tp_clear_pointer (&edits->remove_from_groups, g_hash_table_unref);
g_free (edits->new_name);
g_slice_free (GabbleRosterItemEdit, edits);
}
@@ -1947,10 +2000,7 @@ roster_item_apply_edits (GabbleRoster *roster,
{
gboolean altered = FALSE;
GabbleRosterItem edited_item;
- TpIntset *intset;
GabbleRosterPrivate *priv = roster->priv;
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_GROUP);
GabbleRosterItemEdit *edits = item->unsent_edits;
WockyStanza *message;
@@ -2066,8 +2116,8 @@ roster_item_apply_edits (GabbleRoster *roster,
if (edits->add_to_groups != NULL)
{
GString *str = g_string_new ("Adding to groups: ");
- tp_intset_foreach (tp_handle_set_peek (edits->add_to_groups),
- _gabble_roster_item_dump_group, str);
+ g_hash_table_foreach (edits->add_to_groups,
+ _gabble_roster_item_dump_group, str);
DEBUG("%s", g_string_free (str, FALSE));
}
else
@@ -2083,8 +2133,8 @@ roster_item_apply_edits (GabbleRoster *roster,
if (edits->remove_from_groups != NULL)
{
GString *str = g_string_new ("Removing from groups: ");
- tp_intset_foreach (tp_handle_set_peek (edits->remove_from_groups),
- _gabble_roster_item_dump_group, str);
+ g_hash_table_foreach (edits->remove_from_groups,
+ _gabble_roster_item_dump_group, str);
DEBUG("%s", g_string_free (str, FALSE));
}
else
@@ -2093,31 +2143,33 @@ roster_item_apply_edits (GabbleRoster *roster,
}
}
#endif
- edited_item.groups = tp_handle_set_new (group_repo);
+ edited_item.groups = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
if (!edits->remove_from_all_other_groups)
{
- intset = tp_handle_set_update (edited_item.groups,
- tp_handle_set_peek (item->groups));
- tp_intset_destroy (intset);
+ GHashTable *added;
+
+ added = group_set_update (edited_item.groups, item->groups);
+ g_hash_table_unref (added);
}
if (edits->add_to_groups)
{
- intset = tp_handle_set_update (edited_item.groups,
- tp_handle_set_peek (edits->add_to_groups));
- tp_intset_destroy (intset);
+ GHashTable *added;
+
+ added = group_set_update (edited_item.groups,
+ edits->add_to_groups);
+ g_hash_table_unref (added);
}
if (edits->remove_from_groups)
{
- intset = tp_handle_set_difference_update (edited_item.groups,
- tp_handle_set_peek (edits->remove_from_groups));
- tp_intset_destroy (intset);
+ group_set_difference_update (edited_item.groups,
+ edits->remove_from_groups);
}
- if (!tp_intset_is_equal (tp_handle_set_peek (edited_item.groups),
- tp_handle_set_peek (item->groups)))
+ if (!group_set_is_equal (edited_item.groups, item->groups))
altered = TRUE;
}
@@ -2168,7 +2220,7 @@ roster_item_apply_edits (GabbleRoster *roster,
if (edited_item.groups != item->groups)
{
- tp_handle_set_destroy (edited_item.groups);
+ g_hash_table_unref (edited_item.groups);
}
}
@@ -2453,42 +2505,40 @@ gabble_roster_handle_add (GabbleRoster *roster,
static void
gabble_roster_handle_add_to_group (GabbleRoster *roster,
- TpHandle handle,
- TpHandle group,
- GSimpleAsyncResult *result)
+ TpHandle handle,
+ const gchar *group,
+ GSimpleAsyncResult *result)
{
GabbleRosterPrivate *priv = roster->priv;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
(TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_GROUP);
GabbleRosterItem *item;
g_return_if_fail (roster != NULL);
g_return_if_fail (GABBLE_IS_ROSTER (roster));
g_return_if_fail (tp_handle_is_valid (contact_repo, handle, NULL));
- g_return_if_fail (tp_handle_is_valid (group_repo, group, NULL));
item = _gabble_roster_item_ensure (roster, handle);
if (item->unsent_edits == NULL)
item->unsent_edits = item_edit_new (contact_repo, handle);
- DEBUG ("queue edit to contact#%u - add to group#%u", handle, group);
+ DEBUG ("queue edit to contact#%u - add to group '%s'", handle, group);
gabble_simple_async_countdown_inc (result);
item->unsent_edits->results = g_slist_prepend (
item->unsent_edits->results, g_object_ref (result));
if (!item->unsent_edits->add_to_groups)
{
- item->unsent_edits->add_to_groups = tp_handle_set_new (group_repo);
+ item->unsent_edits->add_to_groups = g_hash_table_new_full (g_str_hash,
+ g_str_equal, g_free, NULL);
}
- tp_handle_set_add (item->unsent_edits->add_to_groups, group);
+ g_hash_table_add (item->unsent_edits->add_to_groups, g_strdup (group));
if (item->unsent_edits->remove_from_groups)
{
- tp_handle_set_remove (item->unsent_edits->remove_from_groups, group);
+ g_hash_table_remove (item->unsent_edits->remove_from_groups, group);
}
/* maybe we can apply the edit immediately? */
@@ -2497,28 +2547,25 @@ gabble_roster_handle_add_to_group (GabbleRoster *roster,
static void
gabble_roster_handle_remove_from_group (GabbleRoster *roster,
- TpHandle handle,
- TpHandle group,
- GSimpleAsyncResult *result)
+ TpHandle handle,
+ const gchar *group,
+ GSimpleAsyncResult *result)
{
GabbleRosterPrivate *priv = roster->priv;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
(TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_GROUP);
GabbleRosterItem *item;
g_return_if_fail (roster != NULL);
g_return_if_fail (GABBLE_IS_ROSTER (roster));
g_return_if_fail (tp_handle_is_valid (contact_repo, handle, NULL));
- g_return_if_fail (tp_handle_is_valid (group_repo, group, NULL));
item = _gabble_roster_item_ensure (roster, handle);
if (item->unsent_edits == NULL)
item->unsent_edits = item_edit_new (contact_repo, handle);
- DEBUG ("queue edit to contact#%u - remove from group#%u", handle, group);
+ DEBUG ("queue edit to contact#%u - remove from group '%s'", handle, group);
gabble_simple_async_countdown_inc (result);
item->unsent_edits->results = g_slist_prepend (
@@ -2526,15 +2573,15 @@ gabble_roster_handle_remove_from_group (GabbleRoster *roster,
if (!item->unsent_edits->remove_from_groups)
{
- item->unsent_edits->remove_from_groups = tp_handle_set_new (
- group_repo);
+ item->unsent_edits->remove_from_groups = g_hash_table_new_full (
+ g_str_hash, g_str_equal, g_free, NULL);
}
- tp_handle_set_add (item->unsent_edits->remove_from_groups, group);
+ g_hash_table_add (item->unsent_edits->remove_from_groups, g_strdup (group));
if (item->unsent_edits->add_to_groups)
{
- tp_handle_set_remove (item->unsent_edits->add_to_groups, group);
+ g_hash_table_remove (item->unsent_edits->add_to_groups, group);
}
/* maybe we can apply the edit immediately? */
@@ -3058,25 +3105,23 @@ static GStrv
gabble_roster_dup_groups (TpBaseContactList *base)
{
GabbleRoster *self = GABBLE_ROSTER (base);
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP);
GPtrArray *ret;
if (self->priv->groups != NULL)
{
- TpIntsetFastIter iter;
- TpHandle group;
+ GHashTableIter iter;
+ gpointer k;
ret = g_ptr_array_sized_new (
- tp_handle_set_size (self->priv->groups) + 1);
+ g_hash_table_size (self->priv->groups) + 1);
- tp_intset_fast_iter_init (&iter,
- tp_handle_set_peek (self->priv->groups));
+ g_hash_table_iter_init (&iter, self->priv->groups);
- while (tp_intset_fast_iter_next (&iter, &group))
+ while (g_hash_table_iter_next (&iter, &k, NULL))
{
- g_ptr_array_add (ret, g_strdup (tp_handle_inspect (group_repo,
- group)));
+ const gchar *group = k;
+
+ g_ptr_array_add (ret, g_strdup (group));
}
}
else
@@ -3098,19 +3143,15 @@ gabble_roster_dup_contact_groups (TpBaseContactList *base,
if (item != NULL && item->groups != NULL)
{
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP);
- TpIntsetFastIter iter;
- TpHandle group;
-
- ret = g_ptr_array_sized_new (tp_handle_set_size (item->groups) + 1);
+ GHashTableIter iter;
+ gpointer k;
- tp_intset_fast_iter_init (&iter, tp_handle_set_peek (item->groups));
+ ret = g_ptr_array_sized_new (g_hash_table_size (item->groups) + 1);
- while (tp_intset_fast_iter_next (&iter, &group))
+ g_hash_table_iter_init (&iter, item->groups);
+ while (g_hash_table_iter_next (&iter, &k, NULL))
{
- g_ptr_array_add (ret,
- g_strdup (tp_handle_inspect (group_repo, group)));
+ g_ptr_array_add (ret, g_strdup (k));
}
}
else
@@ -3130,9 +3171,6 @@ gabble_roster_dup_group_members (TpBaseContactList *base,
TpHandleSet *set;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
(TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT);
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP);
- TpHandle group_handle;
GHashTableIter iter;
gpointer k, v;
@@ -3140,20 +3178,12 @@ gabble_roster_dup_group_members (TpBaseContactList *base,
g_hash_table_iter_init (&iter, self->priv->items);
- group_handle = tp_handle_lookup (group_repo, group, NULL, NULL);
-
- if (G_UNLIKELY (group_handle == 0))
- {
- /* clearly it doesn't have members */
- return set;
- }
-
while (g_hash_table_iter_next (&iter, &k, &v))
{
GabbleRosterItem *item = v;
if (item->groups != NULL &&
- tp_handle_set_is_member (item->groups, group_handle))
+ g_hash_table_lookup (item->groups, group) != NULL)
tp_handle_set_add (set, GPOINTER_TO_UINT (k));
}
@@ -3172,9 +3202,8 @@ gabble_roster_set_contact_groups_async (TpBaseContactList *base,
GabbleRosterItem *item = _gabble_roster_item_ensure (self, contact);
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
(TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT);
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP);
- TpHandleSet *groups_set = tp_handle_set_new (group_repo);
+ GHashTable *groups_set = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
GPtrArray *groups_created = g_ptr_array_new ();
guint i;
GSimpleAsyncResult *result = gabble_simple_async_countdown_new (self,
@@ -3182,17 +3211,11 @@ gabble_roster_set_contact_groups_async (TpBaseContactList *base,
for (i = 0; i < n; i++)
{
- TpHandle group_handle = tp_handle_ensure (group_repo, groups[i], NULL,
- NULL);
+ g_hash_table_add (groups_set, g_strdup (groups[i]));
- if (G_UNLIKELY (group_handle == 0))
- continue;
-
- tp_handle_set_add (groups_set, group_handle);
-
- if (!tp_handle_set_is_member (self->priv->groups, group_handle))
+ if (g_hash_table_lookup (self->priv->groups, groups[i]) == NULL)
{
- tp_handle_set_add (self->priv->groups, group_handle);
+ g_hash_table_add (self->priv->groups, g_strdup (groups[i]));
g_ptr_array_add (groups_created, (gchar *) groups[i]);
}
@@ -3212,13 +3235,13 @@ gabble_roster_set_contact_groups_async (TpBaseContactList *base,
DEBUG ("queue edit to contact#%u - set %" G_GSIZE_FORMAT
"contact groups", contact, n);
- tp_clear_pointer (&item->unsent_edits->add_to_groups, tp_handle_set_destroy);
+ tp_clear_pointer (&item->unsent_edits->add_to_groups, g_hash_table_unref);
item->unsent_edits->add_to_groups = groups_set;
item->unsent_edits->remove_from_all_other_groups = TRUE;
tp_clear_pointer (&item->unsent_edits->remove_from_groups,
- tp_handle_set_destroy);
+ g_hash_table_unref);
gabble_simple_async_countdown_inc (result);
item->unsent_edits->results = g_slist_prepend (
@@ -3238,28 +3261,16 @@ gabble_roster_set_group_members_async (TpBaseContactList *base,
gpointer user_data)
{
GabbleRoster *self = GABBLE_ROSTER (base);
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP);
- TpHandle group_handle = tp_handle_ensure (group_repo, group, NULL,
- NULL);
GSimpleAsyncResult *result = gabble_simple_async_countdown_new (self,
callback, user_data, gabble_roster_set_group_members_async, 1);
GHashTableIter iter;
gpointer k;
- /* You can't add people to an invalid group. */
- if (G_UNLIKELY (group_handle == 0))
- {
- g_simple_async_result_set_error (result, TP_ERROR,
- TP_ERROR_INVALID_ARGUMENT, "Invalid group name: %s", group);
- goto finally;
- }
-
/* we create the group even if @contacts is empty, as the base class
* requires */
- if (!tp_handle_set_is_member (self->priv->groups, group_handle))
+ if (g_hash_table_lookup (self->priv->groups, group) == NULL)
{
- tp_handle_set_add (self->priv->groups, group_handle);
+ g_hash_table_add (self->priv->groups, g_strdup (group));
tp_base_contact_list_groups_created (base, &group, 1);
}
@@ -3270,14 +3281,11 @@ gabble_roster_set_group_members_async (TpBaseContactList *base,
TpHandle contact = GPOINTER_TO_UINT (k);
if (tp_handle_set_is_member (contacts, contact))
- gabble_roster_handle_add_to_group (self, contact, group_handle,
- result);
+ gabble_roster_handle_add_to_group (self, contact, group, result);
else
- gabble_roster_handle_remove_from_group (self, contact, group_handle,
- result);
+ gabble_roster_handle_remove_from_group (self, contact, group, result);
}
-finally:
gabble_simple_async_countdown_dec (result);
g_object_unref (result);
}
@@ -3292,26 +3300,14 @@ gabble_roster_add_to_group_async (TpBaseContactList *base,
GabbleRoster *self = GABBLE_ROSTER (base);
TpIntsetFastIter iter;
TpHandle contact;
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP);
- TpHandle group_handle = tp_handle_ensure (group_repo, group, NULL,
- NULL);
GSimpleAsyncResult *result = gabble_simple_async_countdown_new (self,
callback, user_data, gabble_roster_add_to_group_async, 1);
- /* You can't add people to an invalid group. */
- if (G_UNLIKELY (group_handle == 0))
- {
- g_simple_async_result_set_error (result, TP_ERROR,
- TP_ERROR_INVALID_ARGUMENT, "Invalid group name: %s", group);
- goto finally;
- }
-
/* we create the group even if @contacts is empty, as the base class
* requires */
- if (!tp_handle_set_is_member (self->priv->groups, group_handle))
+ if (g_hash_table_lookup (self->priv->groups, group) == NULL)
{
- tp_handle_set_add (self->priv->groups, group_handle);
+ g_hash_table_add (self->priv->groups, g_strdup (group));
tp_base_contact_list_groups_created (base, &group, 1);
}
@@ -3320,10 +3316,9 @@ gabble_roster_add_to_group_async (TpBaseContactList *base,
while (tp_intset_fast_iter_next (&iter, &contact))
{
/* we ignore any NetworkError */
- gabble_roster_handle_add_to_group (self, contact, group_handle, result);
+ gabble_roster_handle_add_to_group (self, contact, group, result);
}
-finally:
gabble_simple_async_countdown_dec (result);
g_object_unref (result);
}
@@ -3338,31 +3333,22 @@ gabble_roster_remove_from_group_async (TpBaseContactList *base,
GabbleRoster *self = GABBLE_ROSTER (base);
TpIntsetFastIter iter;
TpHandle contact;
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP);
- TpHandle group_handle = tp_handle_lookup (group_repo, group, NULL, NULL);
GSimpleAsyncResult *result = gabble_simple_async_countdown_new (self,
callback, user_data, gabble_roster_remove_from_group_async, 1);
- /* if the group didn't exist then we have nothing to do */
- if (group_handle == 0)
- goto finally;
-
tp_intset_fast_iter_init (&iter, tp_handle_set_peek (contacts));
while (tp_intset_fast_iter_next (&iter, &contact))
{
- gabble_roster_handle_remove_from_group (self, contact, group_handle,
- result);
+ gabble_roster_handle_remove_from_group (self, contact, group, result);
}
-finally:
gabble_simple_async_countdown_dec (result);
g_object_unref (result);
}
typedef struct {
- TpHandle group_handle;
+ gchar *group;
GAsyncReadyCallback callback;
gpointer user_data;
TpHandleSet *contacts;
@@ -3376,12 +3362,8 @@ gabble_roster_remove_group_removed_cb (GObject *source,
GabbleRoster *self = GABBLE_ROSTER (source);
RemoveGroupContext *context = user_data;
- if (context->group_handle != 0)
+ if (context->group != NULL)
{
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP);
- const gchar *group = tp_handle_inspect (group_repo,
- context->group_handle);
GHashTableIter iter;
gpointer k, v;
TpHandle remaining_member = 0;
@@ -3406,8 +3388,8 @@ gabble_roster_remove_group_removed_cb (GObject *source,
TpHandle contact = GPOINTER_TO_UINT (k);
GabbleRosterItem *item = v;
- if (item->groups != NULL && tp_handle_set_is_member (item->groups,
- context->group_handle))
+ if (item->groups != NULL && g_hash_table_lookup (item->groups,
+ context->group) != NULL)
{
if (!tp_handle_set_is_member (context->contacts, contact))
remaining_member = contact;
@@ -3416,9 +3398,10 @@ gabble_roster_remove_group_removed_cb (GObject *source,
if (remaining_member == 0)
{
- tp_handle_set_remove (self->priv->groups, context->group_handle);
+ g_hash_table_remove (self->priv->groups, context->group);
+
tp_base_contact_list_groups_removed ((TpBaseContactList *) self,
- &group, 1);
+ (const gchar * const *) &context->group, 1);
g_hash_table_iter_init (&iter, self->priv->items);
@@ -3427,20 +3410,21 @@ gabble_roster_remove_group_removed_cb (GObject *source,
GabbleRosterItem *item = v;
if (item->groups != NULL &&
- tp_handle_set_is_member (item->groups,
- context->group_handle))
- tp_handle_set_remove (item->groups, context->group_handle);
+ g_hash_table_lookup (item->groups,
+ context->group) != NULL)
+ g_hash_table_remove (item->groups, context->group);
}
}
else
{
DEBUG ("contact #%u is still a member of group '%s', not removing",
- remaining_member, group);
+ remaining_member, context->group);
}
}
context->callback (source, result, context->user_data);
tp_clear_pointer (&context->contacts, tp_handle_set_destroy);
+ g_free (context->group);
g_slice_free (RemoveGroupContext, context);
}
@@ -3455,13 +3439,11 @@ gabble_roster_remove_group_async (TpBaseContactList *base,
gpointer k, v;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
(TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_CONTACT);
- TpHandleRepoIface *group_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) self->priv->conn, TP_HANDLE_TYPE_GROUP);
GSimpleAsyncResult *result;
RemoveGroupContext *context;
context = g_slice_new0 (RemoveGroupContext);
- context->group_handle = tp_handle_lookup (group_repo, group, NULL, NULL);
+ context->group = g_strdup (group);
context->callback = callback;
context->user_data = user_data;
context->contacts = tp_handle_set_new (contact_repo);
@@ -3471,8 +3453,8 @@ gabble_roster_remove_group_async (TpBaseContactList *base,
context, gabble_roster_remove_group_async, 1);
/* if the group didn't exist then we have nothing to do */
- if (context->group_handle == 0 ||
- !tp_handle_set_is_member (self->priv->groups, context->group_handle))
+ if (context->group == NULL ||
+ g_hash_table_lookup (self->priv->groups, context->group) == NULL)
goto finally;
g_hash_table_iter_init (&iter, self->priv->items);
@@ -3482,12 +3464,12 @@ gabble_roster_remove_group_async (TpBaseContactList *base,
TpHandle contact = GPOINTER_TO_UINT (k);
GabbleRosterItem *item = v;
- if (item->groups != NULL && tp_handle_set_is_member (item->groups,
- context->group_handle))
+ if (item->groups != NULL && g_hash_table_lookup (item->groups,
+ context->group) != NULL)
{
tp_handle_set_add (context->contacts, contact);
- gabble_roster_handle_remove_from_group (self, contact,
- context->group_handle, result);
+ gabble_roster_handle_remove_from_group (self, contact, context->group,
+ result);
}
}
diff --git a/src/server-sasl-channel.c b/src/server-sasl-channel.c
index 3eb4f66f2..9ff85054a 100644
--- a/src/server-sasl-channel.c
+++ b/src/server-sasl-channel.c
@@ -382,7 +382,7 @@ gabble_server_sasl_channel_class_init (GabbleServerSaslChannelClass *klass)
param_spec = g_param_spec_uint ("sasl-status", "SASLStatus",
"Status of this channel",
- 0, NUM_TP_SASL_STATUSES, 0,
+ 0, TP_NUM_SASL_STATUSES, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_SASL_STATUS,
param_spec);
diff --git a/src/tls-certificate.c b/src/tls-certificate.c
index 303b70644..c00bac7a8 100644
--- a/src/tls-certificate.c
+++ b/src/tls-certificate.c
@@ -216,7 +216,7 @@ gabble_tls_certificate_class_init (GabbleTLSCertificateClass *klass)
pspec = g_param_spec_uint ("state",
"State of this certificate",
"The state of this TLS certificate.",
- 0, NUM_TP_TLS_CERTIFICATE_STATES - 1,
+ 0, TP_NUM_TLS_CERTIFICATE_STATES - 1,
TP_TLS_CERTIFICATE_STATE_PENDING,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (oclass, PROP_STATE, pspec);
diff --git a/src/tube-dbus.c b/src/tube-dbus.c
index d982e7902..3b6197ebc 100644
--- a/src/tube-dbus.c
+++ b/src/tube-dbus.c
@@ -611,7 +611,7 @@ gabble_tube_dbus_get_property (GObject *object,
g_value_set_string (value, priv->stream_id);
break;
case PROP_TYPE:
- g_value_set_uint (value, TP_TUBE_TYPE_DBUS);
+ g_value_set_uint (value, TUBE_TYPE_DBUS);
break;
case PROP_SERVICE:
g_value_set_string (value, priv->service);
diff --git a/src/tube-iface.c b/src/tube-iface.c
index 7faf514ea..aef131e09 100644
--- a/src/tube-iface.c
+++ b/src/tube-iface.c
@@ -84,7 +84,7 @@ gabble_tube_iface_base_init (gpointer klass)
param_spec = g_param_spec_uint (
"type",
"Tube type",
- "The TpTubeType this tube object.",
+ "The TubeType this tube object.",
0, G_MAXUINT32, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_interface_install_property (klass, param_spec);
@@ -150,7 +150,7 @@ gabble_tube_iface_publish_in_node (GabbleTubeIface *tube,
{
WockyNode *parameters_node;
GHashTable *parameters;
- TpTubeType type;
+ TubeType type;
gchar *service, *id_str;
guint64 tube_id;
TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
@@ -176,7 +176,7 @@ gabble_tube_iface_publish_in_node (GabbleTubeIface *tube,
switch (type)
{
- case TP_TUBE_TYPE_DBUS:
+ case TUBE_TYPE_DBUS:
{
gchar *name, *stream_id;
@@ -198,7 +198,7 @@ gabble_tube_iface_publish_in_node (GabbleTubeIface *tube,
g_free (stream_id);
}
break;
- case TP_TUBE_TYPE_STREAM:
+ case TUBE_TYPE_STREAM:
{
wocky_node_set_attribute (node, "type", "stream");
}
diff --git a/src/tube-iface.h b/src/tube-iface.h
index b727f391d..6cfa8ca55 100644
--- a/src/tube-iface.h
+++ b/src/tube-iface.h
@@ -27,6 +27,12 @@
G_BEGIN_DECLS
+typedef enum
+{
+ TUBE_TYPE_DBUS = 0,
+ TUBE_TYPE_STREAM
+} TubeType;
+
typedef struct _GabbleTubeIface GabbleTubeIface;
typedef struct _GabbleTubeIfaceClass GabbleTubeIfaceClass;
diff --git a/src/tube-stream.c b/src/tube-stream.c
index e1d2289de..c62381366 100644
--- a/src/tube-stream.c
+++ b/src/tube-stream.c
@@ -1234,7 +1234,7 @@ gabble_tube_stream_get_property (GObject *object,
g_value_set_uint64 (value, priv->id);
break;
case PROP_TYPE:
- g_value_set_uint (value, TP_TUBE_TYPE_STREAM);
+ g_value_set_uint (value, TUBE_TYPE_STREAM);
break;
case PROP_SERVICE:
g_value_set_string (value, priv->service);
@@ -1483,7 +1483,7 @@ gabble_tube_stream_class_init (GabbleTubeStreamClass *gabble_tube_stream_class)
"address type",
"a TpSocketAddressType representing the type of the listening"
"address of the local service",
- 0, NUM_TP_SOCKET_ADDRESS_TYPES - 1,
+ 0, TP_NUM_SOCKET_ADDRESS_TYPES - 1,
TP_SOCKET_ADDRESS_TYPE_UNIX,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_ADDRESS_TYPE,
@@ -1502,7 +1502,7 @@ gabble_tube_stream_class_init (GabbleTubeStreamClass *gabble_tube_stream_class)
"access control",
"a TpSocketAccessControl representing the access control "
"the local service applies to the local socket",
- 0, NUM_TP_SOCKET_ACCESS_CONTROLS - 1,
+ 0, TP_NUM_SOCKET_ACCESS_CONTROLS - 1,
TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_ACCESS_CONTROL,
diff --git a/src/vcard-manager.c b/src/vcard-manager.c
index 74e933e9c..9f40b7523 100644
--- a/src/vcard-manager.c
+++ b/src/vcard-manager.c
@@ -46,8 +46,6 @@ static guint default_request_timeout = 180;
* the same recipient */
static guint request_wait_delay = 5 * 60;
-static const gchar *NO_ALIAS = "none";
-
struct _GabbleVCardManagerEditInfo {
/* name of element to edit */
gchar *element_name;
@@ -100,7 +98,13 @@ struct _GabbleVCardManagerPrivate
gboolean dispose_has_run;
GabbleConnection *connection;
- /* TpHandle borrowed from the entry => owned (GabbleVCardCacheEntry *) */
+ /* TpHandle => owned string, or NULL for negative cache
+ * Note that NULL as an item is considered to be distinct from
+ * a missing item. We keep aliases indefinitely, whereas
+ * the rest of the vCard is cached for a finite time. */
+ GHashTable *alias_cache;
+
+ /* TpHandle => owned (GabbleVCardCacheEntry *) */
GHashTable *cache;
/* Those (GabbleVCardCacheEntry *) s that have not expired, ordered by
@@ -199,15 +203,6 @@ gabble_vcard_manager_error_quark (void)
return quark;
}
-GQuark
-gabble_vcard_manager_cache_quark (void)
-{
- static GQuark quark = 0;
- if (!quark)
- quark = g_quark_from_static_string ("gabble-vcard-manager-cache");
- return quark;
-}
-
static void cache_entry_free (void *data);
static gint cache_entry_compare (gconstpointer a, gconstpointer b);
static void manager_patch_vcard (
@@ -223,6 +218,7 @@ gabble_vcard_manager_init (GabbleVCardManager *obj)
GabbleVCardManagerPrivate);
obj->priv = priv;
+ priv->alias_cache = g_hash_table_new_full (NULL, NULL, NULL, g_free);
priv->cache = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
cache_entry_free);
/* no destructor here - the hash table is responsible for freeing it */
@@ -576,7 +572,12 @@ gabble_vcard_manager_dispose (GObject *object)
static void
gabble_vcard_manager_finalize (GObject *object)
{
+ GabbleVCardManager *self = GABBLE_VCARD_MANAGER (object);
+
DEBUG ("%p", object);
+
+ tp_clear_pointer (&self->priv->alias_cache, g_hash_table_unref);
+
G_OBJECT_CLASS (gabble_vcard_manager_parent_class)->finalize (object);
}
@@ -804,8 +805,6 @@ observe_vcard (GabbleConnection *conn,
TpHandle handle,
WockyNode *vcard_node)
{
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- (TpBaseConnection *) conn, TP_HANDLE_TYPE_CONTACT);
const gchar *field = "<NICKNAME>";
gchar *alias;
const gchar *old_alias;
@@ -846,15 +845,16 @@ observe_vcard (GabbleConnection *conn,
handle, field);
/* takes ownership of alias */
- tp_handle_set_qdata (contact_repo, handle,
- gabble_vcard_manager_cache_quark (), alias, g_free);
+ g_hash_table_insert (manager->priv->alias_cache,
+ GUINT_TO_POINTER (handle), alias);
}
else
{
DEBUG ("got no vCard alias for handle %u", handle);
- tp_handle_set_qdata (contact_repo, handle,
- gabble_vcard_manager_cache_quark (), (gchar *) NO_ALIAS, NULL);
+ /* cache negatively */
+ g_hash_table_insert (manager->priv->alias_cache,
+ GUINT_TO_POINTER (handle), NULL);
}
if ((old_alias != NULL) || (alias != NULL))
@@ -1649,7 +1649,6 @@ gabble_vcard_manager_get_cached_alias (GabbleVCardManager *self,
{
GabbleVCardManagerPrivate *priv;
TpHandleRepoIface *contact_repo;
- const gchar *s;
g_return_val_if_fail (GABBLE_IS_VCARD_MANAGER (self), NULL);
@@ -1659,13 +1658,8 @@ gabble_vcard_manager_get_cached_alias (GabbleVCardManager *self,
g_return_val_if_fail (tp_handle_is_valid (contact_repo, handle, NULL), NULL);
- s = tp_handle_get_qdata (contact_repo, handle,
- gabble_vcard_manager_cache_quark ());
-
- if (s == NO_ALIAS)
- s = NULL;
-
- return s;
+ /* Return NULL for uncached or negatively cached contacts. */
+ return g_hash_table_lookup (priv->alias_cache, GUINT_TO_POINTER (handle));
}
/**
@@ -1677,7 +1671,6 @@ gabble_vcard_manager_has_cached_alias (GabbleVCardManager *self,
{
GabbleVCardManagerPrivate *priv;
TpHandleRepoIface *contact_repo;
- gpointer p;
g_return_val_if_fail (GABBLE_IS_VCARD_MANAGER (self), FALSE);
@@ -1688,10 +1681,8 @@ gabble_vcard_manager_has_cached_alias (GabbleVCardManager *self,
g_return_val_if_fail (tp_handle_is_valid (contact_repo, handle, NULL),
FALSE);
- p = tp_handle_get_qdata (contact_repo, handle,
- gabble_vcard_manager_cache_quark ());
-
- return p != NULL;
+ /* Return TRUE for positively or negatively cached contacts. */
+ return g_hash_table_contains (priv->alias_cache, GUINT_TO_POINTER (handle));
}
/* For unit tests only */
diff --git a/src/write-mgr-file.c b/src/write-mgr-file.c
index b097316ba..90da9fd2a 100644
--- a/src/write-mgr-file.c
+++ b/src/write-mgr-file.c
@@ -26,6 +26,7 @@
#include <dbus/dbus-glib.h>
#include <dbus/dbus-protocol.h>
#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
#include "extensions/extensions.h"
#include "protocol.h"
@@ -214,14 +215,6 @@ generate_group_name (GHashTable *props)
handle_type_name = "-multi";
break;
- case TP_HANDLE_TYPE_GROUP:
- handle_type_name = "-group";
- break;
-
- case TP_HANDLE_TYPE_LIST:
- handle_type_name = "-list";
- break;
-
default:
handle_type_name = "";
}
@@ -277,6 +270,45 @@ write_rccs (GKeyFile *f, const gchar *section_name, GHashTable *props)
g_strfreev (group_names);
}
+static void
+write_presence (GKeyFile *f,
+ const gchar *section_name,
+ GHashTable *props)
+{
+ GHashTable *statuses;
+ GHashTableIter iter;
+ gpointer k, v;
+
+ statuses = tp_asv_get_boxed (props,
+ TP_PROP_PROTOCOL_INTERFACE_PRESENCE_STATUSES,
+ TP_HASH_TYPE_SIMPLE_STATUS_SPEC_MAP);
+ g_return_if_fail (statuses != NULL);
+
+ g_hash_table_iter_init (&iter, statuses);
+ while (g_hash_table_iter_next (&iter, &k, &v))
+ {
+ const gchar *id = k;
+ GValueArray *status = v;
+ TpConnectionPresenceType type;
+ gboolean may_set_on_self, can_have_msg;
+ gchar *key, *value;
+
+ key = g_strdup_printf ("status-%s", id);
+
+ tp_value_array_unpack (status, 3, &type, &may_set_on_self, &can_have_msg);
+
+ value = g_strdup_printf ("%u%s%s",
+ type,
+ may_set_on_self ? " settable" : "",
+ can_have_msg ? " message" : "");
+
+ g_key_file_set_string (f, section_name, key, value);
+
+ g_free (key);
+ g_free (value);
+ }
+}
+
static gchar *
mgr_file_contents (const char *busname,
const char *objpath,
@@ -302,6 +334,7 @@ mgr_file_contents (const char *busname,
const gchar * const *addr_vcard_fields;
const gchar * const *addr_uri_schemes;
const gchar * const *auth_types;
+ const gchar * const *mime_types;
g_object_get (G_OBJECT (protocol),
"immutable-properties", &props,
@@ -319,6 +352,8 @@ mgr_file_contents (const char *busname,
TP_PROP_PROTOCOL_INTERFACE_ADDRESSING_ADDRESSABLE_VCARD_FIELDS);
addr_uri_schemes = tp_asv_get_strv (props,
TP_PROP_PROTOCOL_INTERFACE_ADDRESSING_ADDRESSABLE_URI_SCHEMES);
+ mime_types = tp_asv_get_strv (props,
+ TP_PROP_PROTOCOL_INTERFACE_AVATARS_SUPPORTED_AVATAR_MIME_TYPES);
write_parameters (f, section_name, TP_BASE_PROTOCOL (protocol));
write_rccs (f, section_name, props);
@@ -334,6 +369,40 @@ mgr_file_contents (const char *busname,
g_key_file_set_string_list (f, section_name, "AddressableURISchemes",
addr_uri_schemes, g_strv_length ((gchar **) addr_uri_schemes));
+ /* Avatars */
+ g_key_file_set_string_list (f, section_name, "SupportedAvatarMIMETypes",
+ mime_types, g_strv_length ((gchar **) mime_types));
+ g_key_file_set_integer (f, section_name, "MinimumAvatarHeight",
+ tp_asv_get_uint32 (props,
+ TP_PROP_PROTOCOL_INTERFACE_AVATARS_MINIMUM_AVATAR_HEIGHT,
+ NULL));
+ g_key_file_set_integer (f, section_name, "RecommendedAvatarHeight",
+ tp_asv_get_uint32 (props,
+ TP_PROP_PROTOCOL_INTERFACE_AVATARS_RECOMMENDED_AVATAR_HEIGHT,
+ NULL));
+ g_key_file_set_integer (f, section_name, "MaximumAvatarHeight",
+ tp_asv_get_uint32 (props,
+ TP_PROP_PROTOCOL_INTERFACE_AVATARS_MAXIMUM_AVATAR_HEIGHT,
+ NULL));
+ g_key_file_set_integer (f, section_name, "MinimumAvatarWidth",
+ tp_asv_get_uint32 (props,
+ TP_PROP_PROTOCOL_INTERFACE_AVATARS_MINIMUM_AVATAR_WIDTH,
+ NULL));
+ g_key_file_set_integer (f, section_name, "RecommendedAvatarWidth",
+ tp_asv_get_uint32 (props,
+ TP_PROP_PROTOCOL_INTERFACE_AVATARS_RECOMMENDED_AVATAR_WIDTH,
+ NULL));
+ g_key_file_set_integer (f, section_name, "MaximumAvatarWidth",
+ tp_asv_get_uint32 (props,
+ TP_PROP_PROTOCOL_INTERFACE_AVATARS_MAXIMUM_AVATAR_WIDTH,
+ NULL));
+ g_key_file_set_integer (f, section_name, "MaximumAvatarBytes",
+ tp_asv_get_uint32 (props,
+ TP_PROP_PROTOCOL_INTERFACE_AVATARS_MAXIMUM_AVATAR_BYTES,
+ NULL));
+
+ write_presence (f, section_name, props);
+
WRITE_STR (TP_PROP_PROTOCOL_VCARD_FIELD, "VCardField");
WRITE_STR (TP_PROP_PROTOCOL_ENGLISH_NAME, "EnglishName");
WRITE_STR (TP_PROP_PROTOCOL_ICON, "Icon");
diff --git a/tests/test-handles.c b/tests/test-handles.c
index a0d60be49..ebc4c3914 100644
--- a/tests/test-handles.c
+++ b/tests/test-handles.c
@@ -12,7 +12,7 @@
static void
test_handles (guint handle_type)
{
- TpHandleRepoIface *repos[NUM_TP_HANDLE_TYPES];
+ TpHandleRepoIface *repos[TP_NUM_HANDLE_TYPES];
TpHandleRepoIface *tp_repo = NULL;
GError *error = NULL;
guint i;
@@ -21,7 +21,7 @@ test_handles (guint handle_type)
const gchar *jid = "handle.test@foobar";
const gchar *return_jid;
- for (i = 0; i < NUM_TP_HANDLE_TYPES; i++)
+ for (i = 0; i < TP_NUM_HANDLE_TYPES; i++)
{
repos[i] = NULL;
}
@@ -64,7 +64,7 @@ test_handles (guint handle_type)
return_jid = tp_handle_inspect (tp_repo, handle);
g_assert (!strcmp (return_jid, jid));
- for (i = 0; i < NUM_TP_HANDLE_TYPES; i++)
+ for (i = 0; i < TP_NUM_HANDLE_TYPES; i++)
{
if (repos[i])
g_object_unref ((GObject *) repos[i]);
diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index 37f732674..5865b14f5 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -2,7 +2,6 @@ TWISTED_TESTS = \
addressing.py \
avatar-requirements.py \
caps/advertise-contact-caps.py \
- caps/advertise-legacy.py \
caps/broken-reply.py \
caps/caps-cache.py \
caps/caps-persistent-cache.py \
@@ -21,6 +20,7 @@ TWISTED_TESTS = \
client-types.py \
cm/protocol.py \
connect/disco-error-from-bare-jid.py \
+ connect/disco-facebook.py \
connect/disconnect-timeout.py \
connect/disco-no-reply.py \
connect/network-error.py \
@@ -77,15 +77,12 @@ TWISTED_TESTS = \
pubsub.py \
roster/authorize.py \
roster/edit-before-roster.py \
- roster/ensure.py \
roster/groups-12791.py \
roster/groups.py \
roster/initial-aliases.py \
roster/push-from-contact.py \
roster/push-without-id.py \
roster/removed-from-rp-subscribe.py \
- roster/request-group-after-roster.py \
- roster/request-group-before-roster.py \
roster/test-google-roster.py \
roster/test-roster-item-deletion.py \
roster/test-roster.py \
@@ -175,7 +172,6 @@ TWISTED_VCARD_TESTS = \
$(NULL)
TWISTED_JINGLE_TESTS = \
- jingle/accept-extra-stream.py \
jingle/call-basics.py \
jingle/call-codecoffer.py \
jingle/call-content-adding-removal.py \
@@ -186,38 +182,10 @@ TWISTED_JINGLE_TESTS = \
jingle/call-muc-cancel.py \
jingle/call-muc.py \
jingle/call-muc-re-re-request.py \
- jingle/call-state.py \
jingle/decloak-peer.py \
- jingle/dtmf-no-audio.py \
- jingle/dtmf.py \
- jingle/google-relay.py \
- jingle/hold-audio.py \
- jingle/hold-av.py \
- jingle/incoming-basics.py \
- jingle/incoming-call-stream-error.py \
- jingle/incoming-gmail-modern-jingle.py \
- jingle/initial-audio-video.py \
- jingle/misuse.py \
- jingle/outgoing-basics.py \
- jingle/outgoing-ensure.py \
- jingle/outgoing-many-streams.py \
- jingle/payload-types.py \
jingle/preload-caps-crash.py \
jingle/session-id-collision.py \
- jingle/stream-errors-on-content-reject.py \
- jingle/stream-errors-on-terminate.py \
- jingle/stream-handler-error.py \
jingle/stun-server.py \
- jingle/test-content-adding-removal.py \
- jingle/test-content-complex.py \
- jingle/test-description-info.py \
- jingle/test-incoming-call-reject.py \
- jingle/test-incoming-iceudp.py \
- jingle/test-outgoing-call-rejected.py \
- jingle/test-outgoing-iceudp.py \
- jingle/test-wait-for-caps-incomplete.py \
- jingle/test-wait-for-caps.py \
- jingle/transport-info-parsing.py \
jingle/unknown-session.py \
$(NULL)
@@ -270,6 +238,7 @@ TWISTED_OTHER_FILES = \
mucutil.py \
ns.py \
olpc/util.py \
+ presence_helper.py \
presence/__init__.py \
presence/invisible_helper.py \
rostertest.py \
@@ -355,12 +324,6 @@ else
PLUGINS_ENABLED_PYBOOL = False
endif
-if ENABLE_CHANNEL_TYPE_CALL
-CHANNEL_TYPE_CALL_ENABLED_PYBOOL = True
-else
-CHANNEL_TYPE_CALL_ENABLED_PYBOOL = False
-endif
-
if ENABLE_GOOGLE_RELAY
GOOGLE_RELAY_ENABLED_PYBOOL = True
else
@@ -391,7 +354,6 @@ config.py: Makefile
echo "CLIENT_TYPE = '$(CLIENT_TYPE)'"; \
echo "DEBUGGING = $(DEBUGGING_PYBOOL)"; \
echo "PLUGINS_ENABLED = $(PLUGINS_ENABLED_PYBOOL)"; \
- echo "CHANNEL_TYPE_CALL_ENABLED = $(CHANNEL_TYPE_CALL_ENABLED_PYBOOL)"; \
echo "GOOGLE_RELAY_ENABLED = $(GOOGLE_RELAY_ENABLED_PYBOOL)"; \
echo "FILE_TRANSFER_ENABLED = $(FILE_TRANSFER_ENABLED_PYBOOL)"; \
echo "VOIP_ENABLED = $(VOIP_ENABLED_PYBOOL)"; \
@@ -464,7 +426,8 @@ tools/exec-with-log.sh: tools/exec-with-log.sh.in
# The wildcard % matches both config files!
tools/%.conf: tools/%.conf.in Makefile
- $(MKDIR_P) tools
+ $(MKDIR_P) tools/servicedir
+ $(MKDIR_P) tools/servicedir-uninstalled
$(AM_V_GEN)sed -e "s|[@]gabbletestsdir[@]|@gabbletestsdir@|g" \
-e "s|[@]abs_top_builddir[@]|@abs_top_builddir@|g" $< > $@
diff --git a/tests/twisted/addressing.py b/tests/twisted/addressing.py
index 9528e12cb..057617bf3 100644
--- a/tests/twisted/addressing.py
+++ b/tests/twisted/addressing.py
@@ -2,13 +2,11 @@
Test Gabble's different addressing interfaces.
"""
-import dbus
-from servicetest import unwrap, tp_path_prefix, assertEquals, ProxyWrapper, \
- assertContains, assertSameSets, assertDoesNotContain, pretty
+from servicetest import tp_path_prefix, assertEquals, ProxyWrapper, \
+ assertContains, assertSameSets
from gabbletest import exec_test, call_async
import constants as cs
import ns
-import time
def test_protocol(q, bus, conn, stream):
proto = ProxyWrapper(
diff --git a/tests/twisted/avatar-requirements.py b/tests/twisted/avatar-requirements.py
index 0272e95f0..25301b910 100644
--- a/tests/twisted/avatar-requirements.py
+++ b/tests/twisted/avatar-requirements.py
@@ -1,5 +1,5 @@
-from servicetest import call_async, EventPattern
-from gabbletest import exec_test, acknowledge_iq, make_result_iq
+from gabbletest import exec_test
+from servicetest import assertEquals
import constants as cs
def test_get_all(conn):
@@ -35,15 +35,13 @@ def test(q, bus, conn, stream):
test_get_all(conn)
# deprecated version
- types, minw, minh, maxw, maxh, maxb = conn.Avatars.GetAvatarRequirements()
- assert types[0] == 'image/png', types
- assert 'image/jpeg' in types, types
- assert 'image/gif' in types, types
- assert minw == 32, minw
- assert minh == 32, minh
- assert maxw == 96, maxw
- assert maxh == 96, maxh
- assert maxb == 8192, maxb
+ props = conn.Properties.GetAll(cs.CONN_IFACE_AVATARS)
+ assertEquals(['image/png', 'image/jpeg', 'image/gif'], props['SupportedAvatarMIMETypes'])
+ assertEquals(32, props['MinimumAvatarWidth'])
+ assertEquals(32, props['MinimumAvatarHeight'])
+ assertEquals(96, props['MaximumAvatarWidth'])
+ assertEquals(96, props['MaximumAvatarHeight'])
+ assertEquals(8192, props['MaximumAvatarBytes'])
if __name__ == '__main__':
exec_test(test, do_connect=False)
diff --git a/tests/twisted/caps/advertise-contact-caps.py b/tests/twisted/caps/advertise-contact-caps.py
index ab40277fd..23f4d478f 100644
--- a/tests/twisted/caps/advertise-contact-caps.py
+++ b/tests/twisted/caps/advertise-contact-caps.py
@@ -221,16 +221,6 @@ def run_mixed_test (q, bus, conn, stream):
conn.Connect()
conn.ContactCapabilities.UpdateCapabilities([
- (cs.CLIENT + '.SquareWheel', [
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.INITIAL_AUDIO: True},
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.INITIAL_VIDEO: True},
- ], [
- cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/gtalk-p2p',
- cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/ice-udp',
- cs.CHANNEL_IFACE_MEDIA_SIGNALLING + '/video/h264',
- ]),
(cs.CLIENT + '.FlyingCar', [
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CALL,
cs.CALL_INITIAL_AUDIO: True},
@@ -250,14 +240,6 @@ def run_mixed_test (q, bus, conn, stream):
if __name__ == '__main__':
exec_test(
partial(run_test,
- media_channel_type=cs.CHANNEL_TYPE_STREAMED_MEDIA,
- media_interface=cs.CHANNEL_IFACE_MEDIA_SIGNALLING,
- initial_audio=cs.INITIAL_AUDIO,
- initial_video=cs.INITIAL_VIDEO),
- do_connect=False)
-
- exec_test(
- partial(run_test,
media_channel_type=cs.CHANNEL_TYPE_CALL,
media_interface=cs.CHANNEL_TYPE_CALL,
initial_audio=cs.CALL_INITIAL_AUDIO,
diff --git a/tests/twisted/caps/advertise-legacy.py b/tests/twisted/caps/advertise-legacy.py
deleted file mode 100644
index 95b16245a..000000000
--- a/tests/twisted/caps/advertise-legacy.py
+++ /dev/null
@@ -1,110 +0,0 @@
-"""
-Test AdvertiseCapabilities.
-"""
-
-import dbus
-
-from twisted.words.xish import xpath, domish
-
-from servicetest import EventPattern
-from gabbletest import exec_test
-from caps_helper import caps_contain, receive_presence_and_ask_caps,\
- check_caps, JINGLE_CAPS
-import constants as cs
-import ns
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def run_test(q, bus, conn, stream):
- initial_presence = q.expect('stream-presence')
-
- # This method call looks wrong, but it's "the other side" of
- # test/twisted/capabilities/legacy-caps.py in MC 5.1 - MC doesn't know
- # how to map Client capabilities into the old Capabilities interface.
- #
- # Also, MC sometimes puts the same channel type in the list twice, so
- # make sure Gabble copes.
- add = [(cs.CHANNEL_TYPE_STREAMED_MEDIA, 2L**32-1),
- (cs.CHANNEL_TYPE_STREAM_TUBE, 2L**32-1),
- (cs.CHANNEL_TYPE_STREAM_TUBE, 2L**32-1)]
- remove = []
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
- (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream,
- False)
- check_caps(namespaces, JINGLE_CAPS)
-
- # Remove all our caps again
- add = []
- remove = [cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.CHANNEL_TYPE_STREAM_TUBE]
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
- (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream,
- False)
- check_caps(namespaces, [])
-
- # Add caps selectively (i.e. what a client that actually understood the
- # old Capabilities interface would do). With AUDIO and GTALK_P2P, we're
- # callable, but not via ICE-UDP, and not with video.
- #
- # (Jingle and raw UDP need no special client support, so are automatically
- # enabled whenever we can do audio or video.)
- add = [(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_GTALKP2P)]
- remove = []
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
- (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream,
- False)
- check_caps(namespaces,
- [ns.GOOGLE_P2P, ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE,
- ns.JINGLE_015, ns.GOOGLE_FEAT_VOICE, ns.JINGLE_RTP_AUDIO,
- ns.JINGLE_RTP, ns.JINGLE_015_AUDIO])
-
- # Remove all our caps again
- add = []
- remove = [cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.CHANNEL_TYPE_STREAM_TUBE]
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
- (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream,
- False)
- check_caps(namespaces, [])
-
- # With AUDIO but no transport, we are only callable via raw UDP, which
- # Google clients cannot do.
- add = [(cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.MEDIA_CAP_AUDIO)]
- remove = []
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
- (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream,
- False)
- check_caps(namespaces,
- [ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE,
- ns.JINGLE_015, ns.JINGLE_RTP_AUDIO,
- ns.JINGLE_RTP, ns.JINGLE_015_AUDIO])
-
- # Remove all our caps again
- add = []
- remove = [cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.CHANNEL_TYPE_STREAM_TUBE]
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
- (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream,
- False)
- check_caps(namespaces, [])
-
- # With VIDEO and ICE-UDP only, we are very futuristic indeed.
- # Google clients cannot interop with us.
- add = [(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.MEDIA_CAP_VIDEO | cs.MEDIA_CAP_ICEUDP)]
- remove = []
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
- (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream,
- False)
- check_caps(namespaces,
- [ns.JINGLE_TRANSPORT_ICEUDP, ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE,
- ns.JINGLE_015, ns.JINGLE_RTP_VIDEO,
- ns.JINGLE_RTP, ns.JINGLE_015_VIDEO])
-
-if __name__ == '__main__':
- exec_test(run_test)
diff --git a/tests/twisted/caps/caps-cache.py b/tests/twisted/caps/caps-cache.py
index 9c63e03b6..0102d5ceb 100644
--- a/tests/twisted/caps/caps-cache.py
+++ b/tests/twisted/caps/caps-cache.py
@@ -12,7 +12,8 @@ import constants as cs
import ns
from caps_helper import (
compute_caps_hash, fake_client_dataforms, presence_and_disco,
- send_presence, expect_disco, send_disco_reply)
+ send_presence, expect_disco, send_disco_reply,
+ assert_rccs_callable, get_contacts_capabilities_sync)
from config import VOIP_ENABLED
@@ -31,13 +32,16 @@ features = [
def expect_caps(q, conn, h):
# we can now do audio and video calls
- event = q.expect('dbus-signal', signal='CapabilitiesChanged')
+ cc, = q.expect_many(
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged',
+ predicate=lambda e: h in e.args[0]),
+ )
+ assert_rccs_callable(cc.args[0][h], require_video=True)
check_caps(conn, h)
def check_caps(conn, h):
- assertContains((h, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3,
- cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO),
- conn.Capabilities.GetCapabilities([h]))
+ caps = get_contacts_capabilities_sync(conn, [h])
+ assert_rccs_callable(caps[h], require_video=True)
def update_contact_caps(q, conn, stream, contact, caps, disco = True,
dataforms = {}, initial = True):
diff --git a/tests/twisted/caps/caps-persistent-cache.py b/tests/twisted/caps/caps-persistent-cache.py
index 2b1318396..b4725a8fa 100644
--- a/tests/twisted/caps/caps-persistent-cache.py
+++ b/tests/twisted/caps/caps-persistent-cache.py
@@ -5,7 +5,8 @@ from servicetest import (
assertEquals, assertContains, assertDoesNotContain, EventPattern,
)
from gabbletest import make_presence, exec_test
-from caps_helper import compute_caps_hash, send_disco_reply
+from caps_helper import (compute_caps_hash, send_disco_reply,
+ assert_rccs_callable)
import constants as cs
import ns
@@ -46,16 +47,13 @@ def handle_disco(q, stream, contact_jid, identity):
send_disco_reply(stream, event.stanza, [identity], features)
def capabilities_changed(q, contact_handle):
- streamed_media_caps = (contact_handle, cs.CHANNEL_TYPE_STREAMED_MEDIA,
- 0, 3, 0, cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO)
- e = q.expect('dbus-signal', signal='CapabilitiesChanged')
- assertContains(streamed_media_caps, e.args[0])
e = q.expect('dbus-signal', signal='ContactCapabilitiesChanged')
assertContains(contact_handle, e.args[0])
+ assert_rccs_callable(e.args[0][contact_handle], require_video=True)
assertContains(xiangqi_tube_cap, e.args[0][contact_handle])
def test1(q, bus, conn, stream):
- contact_handle = conn.RequestHandles(cs.HT_CONTACT, [contact_bare_jid])[0]
+ contact_handle = conn.get_contact_handle_sync(contact_bare_jid)
send_presence(q, stream, contact_jid, 'client/pc//thane')
handle_disco(q, stream, contact_jid, 'client/pc//thane')
capabilities_changed(q, contact_handle)
@@ -63,7 +61,7 @@ def test1(q, bus, conn, stream):
def test2(q, bus, conn, stream):
# The second time around, the capabilities are retrieved from the cache,
# so no disco request is sent.
- contact_handle = conn.RequestHandles(cs.HT_CONTACT, [contact_bare_jid])[0]
+ contact_handle = conn.get_contact_handle_sync(contact_bare_jid)
send_presence(q, stream, contact_jid, 'client/pc//thane')
capabilities_changed(q, contact_handle)
diff --git a/tests/twisted/caps/from-bare-jid.py b/tests/twisted/caps/from-bare-jid.py
index 0460fd61b..122aaf696 100644
--- a/tests/twisted/caps/from-bare-jid.py
+++ b/tests/twisted/caps/from-bare-jid.py
@@ -8,7 +8,8 @@ from servicetest import (
assertEquals, assertContains, assertDoesNotContain, EventPattern,
)
from gabbletest import make_presence, exec_test
-from caps_helper import compute_caps_hash, send_disco_reply
+from caps_helper import (compute_caps_hash, send_disco_reply,
+ assert_rccs_callable, assert_rccs_not_callable)
import constants as cs
import ns
@@ -22,7 +23,7 @@ def test(q, bus, conn, stream):
client = 'http://example.com/perverse-client'
contact_bare_jid = 'edgecase@example.com'
contact_with_resource = 'edgecase@example.com/hi'
- contact_handle = conn.RequestHandles(cs.HT_CONTACT, [contact_bare_jid])[0]
+ contact_handle = conn.get_contact_handle_sync(contact_bare_jid)
# Gabble gets a presence stanza from a bare JID, which is a tad surprising.
features = [
@@ -49,10 +50,10 @@ def test(q, bus, conn, stream):
# Gabble lets us know their caps have changed. (Gabble used to ignore the
# reply.)
- streamed_media_caps = (contact_handle, cs.CHANNEL_TYPE_STREAMED_MEDIA,
- 0, 3, 0, cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO)
- e = q.expect('dbus-signal', signal='CapabilitiesChanged')
- assertContains(streamed_media_caps, e.args[0])
+ cc, = q.expect_many(
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
+ )
+ assert_rccs_callable(cc.args[0][contact_handle])
# Gabble gets another presence stanza from the bare JID, with different
# caps.
@@ -84,12 +85,12 @@ def test(q, bus, conn, stream):
# a resource (and vice versa), so it should now say the contact is
# incapable. Gabble also looks up the resourceful JID's hash.
cc, disco3 = q.expect_many(
- EventPattern('dbus-signal', signal='CapabilitiesChanged'),
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
EventPattern('stream-iq', to=contact_with_resource,
query_ns='http://jabber.org/protocol/disco#info'),
)
- assertDoesNotContain(streamed_media_caps, cc.args[0])
+ assert_rccs_not_callable(cc.args[0][contact_handle])
query_node = xpath.queryForNodes('/iq/query', disco3.stanza)[0]
assertEquals(client + '#' + caps['ver'], query_node.attributes['node'])
@@ -103,8 +104,10 @@ def test(q, bus, conn, stream):
send_disco_reply(stream, disco3.stanza, [], features_)
# Gabble should announce that the contact has acquired some caps.
- e = q.expect('dbus-signal', signal='CapabilitiesChanged')
- assertContains(streamed_media_caps, e.args[0])
+ cc, = q.expect_many(
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
+ )
+ assert_rccs_callable(cc.args[0][contact_handle])
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/caps/hashed-caps.py b/tests/twisted/caps/hashed-caps.py
index 5c4562c7e..ce0ca5f57 100644
--- a/tests/twisted/caps/hashed-caps.py
+++ b/tests/twisted/caps/hashed-caps.py
@@ -5,13 +5,13 @@ Test the verification string introduced in version 1.5 of XEP-0115
This test changes the caps several times:
- Initial presence to be online
- Change presence to handle audio calls, using XEP-0115-v1.3. Check that
- 'CapabilitiesChanged' *is* fired
+ 'ContactCapabilitiesChanged' *is* fired
- Change presence *not* to handle audio calls, using XEP-0115-v1.5, but with a
- *bogus* hash. Check that 'CapabilitiesChanged' is *not* fired
+ *bogus* hash. Check that 'ContactCapabilitiesChanged' is *not* fired
- Change presence *not* to handle audio calls, using XEP-0115-v1.5, with a
- *good* hash. Check that 'CapabilitiesChanged' *is* fired
+ *good* hash. Check that 'ContactCapabilitiesChanged' *is* fired
- Change presence to handle audio calls, using XEP-0115-v1.5, with a XEP-0128
- dataform. Check that 'CapabilitiesChanged' is fired
+ dataform. Check that 'ContactCapabilitiesChanged' is fired
This is done for 2 contacts
Then, this test announce 2 contacts with the same hash.
@@ -27,12 +27,13 @@ from twisted.words.xish import xpath
from gabbletest import (
exec_test, make_result_iq, make_presence, sync_stream, elem,
)
-from servicetest import sync_dbus, EventPattern, assertLength
+from servicetest import sync_dbus, EventPattern, assertLength, assertEquals
import constants as cs
import ns
from caps_helper import (
compute_caps_hash, make_caps_disco_reply, send_disco_reply,
- fake_client_dataforms)
+ fake_client_dataforms, assert_rccs_callable, assert_rccs_not_callable,
+ get_contacts_capabilities_sync)
from config import VOIP_ENABLED
@@ -40,8 +41,6 @@ if not VOIP_ENABLED:
print "NOTE: built with --disable-voip"
raise SystemExit(77)
-caps_changed_flag = False
-
some_identities = [
'client/pc/fr/le gabble',
'client/pc/en/gabble',
@@ -53,15 +52,7 @@ jingle_av_features = [
ns.GOOGLE_P2P,
]
-def caps_changed_cb(dummy):
- # Workaround to bug 9980: do not raise an error but use a flag
- # https://bugs.freedesktop.org/show_bug.cgi?id=9980
- global caps_changed_flag
- caps_changed_flag = True
-
def test_hash(q, bus, conn, stream, contact, contact_handle, client):
- global caps_changed_flag
-
presence = make_presence(contact, status='hello')
stream.send(presence)
@@ -70,8 +61,8 @@ def test_hash(q, bus, conn, stream, contact, contact_handle, client):
(2, u'available', 'hello')}])
# no special capabilities
- basic_caps = [(contact_handle, cs.CHANNEL_TYPE_TEXT, 3, 0)]
- assert conn.Capabilities.GetCapabilities([contact_handle]) == basic_caps
+ for rcc in get_contacts_capabilities_sync(conn, [contact_handle])[contact_handle]:
+ assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))
# send updated presence with Jingle caps info
presence = make_presence(contact, status='hello',
@@ -91,12 +82,13 @@ def test_hash(q, bus, conn, stream, contact, contact_handle, client):
send_disco_reply(stream, event.stanza, [], jingle_av_features)
# we can now do audio calls
- event = q.expect('dbus-signal', signal='CapabilitiesChanged')
- caps_diff = event.args[0]
- media_diff = [c for c in caps_diff
- if c[1] == cs.CHANNEL_TYPE_STREAMED_MEDIA][0]
- assert media_diff[5] & cs.MEDIA_CAP_AUDIO, media_diff[5]
- caps_changed_flag = False
+ cc, = q.expect_many(
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
+ )
+
+ assert_rccs_callable(cc.args[0][contact_handle])
+ assertEquals(cc.args[0],
+ get_contacts_capabilities_sync(conn, [contact_handle]))
# Send presence without any capabilities. XEP-0115 §8.4 Caps Optimization
# says “receivers of presence notifications MUST NOT expect an annotation
@@ -105,10 +97,9 @@ def test_hash(q, bus, conn, stream, contact, contact_handle, client):
stream.send(make_presence(contact, status='very capable'))
q.expect('dbus-signal', signal='PresencesChanged',
args=[{contact_handle: (2, u'available', 'very capable')}])
- ye_olde_caps = conn.Capabilities.GetCapabilities([contact_handle])
- assertLength(1, [c for c in ye_olde_caps
- if c[1] == cs.CHANNEL_TYPE_STREAMED_MEDIA and
- c[3] & cs.MEDIA_CAP_AUDIO])
+ # still exactly the same capabilities
+ assertEquals(cc.args[0],
+ get_contacts_capabilities_sync(conn, [contact_handle]))
# send bogus presence
caps = {
@@ -131,10 +122,12 @@ def test_hash(q, bus, conn, stream, contact, contact_handle, client):
['http://jabber.org/protocol/bogus-feature'])
# don't receive any D-Bus signal
+ forbidden = [
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
+ ]
+ q.forbid_events(forbidden)
sync_dbus(bus, q, conn)
sync_stream(q, stream)
- assert caps_changed_flag == False
-
# send presence with empty caps
presence = make_presence(contact, status='hello',
@@ -152,18 +145,22 @@ def test_hash(q, bus, conn, stream, contact, contact_handle, client):
# still don't receive any D-Bus signal
sync_dbus(bus, q, conn)
- assert caps_changed_flag == False
# send good reply
+ q.unforbid_events(forbidden)
result = make_result_iq(stream, event.stanza)
query = result.firstChildElement()
stream.send(result)
# we can now do nothing
- event = q.expect('dbus-signal', signal='CapabilitiesChanged')
- assert caps_changed_flag == True
- caps_changed_flag = False
-
+ cc, = q.expect_many(
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
+ )
+ for rcc in cc.args[0][contact_handle]:
+ assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))
+ assert_rccs_not_callable(cc.args[0][contact_handle])
+ assertEquals(cc.args[0],
+ get_contacts_capabilities_sync(conn, [contact_handle]))
# send correct presence
ver = compute_caps_hash(some_identities, jingle_av_features, fake_client_dataforms)
@@ -183,22 +180,24 @@ def test_hash(q, bus, conn, stream, contact, contact_handle, client):
client + '#' + caps['ver']
# don't receive any D-Bus signal
+ q.forbid_events(forbidden)
sync_dbus(bus, q, conn)
- assert caps_changed_flag == False
+ q.unforbid_events(forbidden)
# send good reply
send_disco_reply(
stream, event.stanza, some_identities, jingle_av_features, fake_client_dataforms)
# we can now do audio calls
- event = q.expect('dbus-signal', signal='CapabilitiesChanged',
- )
- assert caps_changed_flag == True
- caps_changed_flag = False
+ cc, = q.expect_many(
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
+ )
+ assert_rccs_callable(cc.args[0][contact_handle])
+ assertEquals(cc.args[0],
+ get_contacts_capabilities_sync(conn, [contact_handle]))
def test_two_clients(q, bus, conn, stream, contact1, contact2,
contact_handle1, contact_handle2, client, broken_hash):
- global caps_changed_flag
presence = make_presence(contact1, status='hello')
stream.send(presence)
@@ -215,10 +214,9 @@ def test_two_clients(q, bus, conn, stream, contact1, contact2,
(2, u'available', 'hello')}])
# no special capabilities
- basic_caps = [(contact_handle1, cs.CHANNEL_TYPE_TEXT, 3, 0)]
- assert conn.Capabilities.GetCapabilities([contact_handle1]) == basic_caps
- basic_caps = [(contact_handle2, cs.CHANNEL_TYPE_TEXT, 3, 0)]
- assert conn.Capabilities.GetCapabilities([contact_handle2]) == basic_caps
+ for h in (contact_handle1, contact_handle2):
+ for rcc in get_contacts_capabilities_sync(conn, [h])[h]:
+ assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))
# send updated presence with Jingle caps info
ver = compute_caps_hash(some_identities, jingle_av_features, {})
@@ -240,8 +238,12 @@ def test_two_clients(q, bus, conn, stream, contact1, contact2,
client + '#' + ver
# don't receive any D-Bus signal
+ forbidden = [
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
+ ]
+ q.forbid_events(forbidden)
sync_dbus(bus, q, conn)
- assert caps_changed_flag == False
+ q.unforbid_events(forbidden)
result = make_caps_disco_reply(
stream, event.stanza, some_identities, jingle_av_features)
@@ -263,28 +265,33 @@ def test_two_clients(q, bus, conn, stream, contact1, contact2,
client + '#' + ver
# don't receive any D-Bus signal
+ q.forbid_events(forbidden)
sync_dbus(bus, q, conn)
- assert caps_changed_flag == False
+ q.unforbid_events(forbidden)
# send good reply
send_disco_reply(stream, event.stanza, some_identities, jingle_av_features)
- # we can now do audio calls with both contacts
- event = q.expect('dbus-signal', signal='CapabilitiesChanged',
- args=[[(contact_handle2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 0, 3, 0,
- cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO)]])
+ # we can now do audio calls
+ cc, = q.expect_many(
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged',
+ predicate=lambda e: contact_handle2 in e.args[0]),
+ )
+ assert_rccs_callable(cc.args[0][contact_handle2])
+
if not broken_hash:
# if the first contact failed to provide a good hash, it does not
# deserve its capabilities to be understood by Gabble!
- event = q.expect('dbus-signal', signal='CapabilitiesChanged',
- args=[[(contact_handle1, cs.CHANNEL_TYPE_STREAMED_MEDIA, 0, 3, 0,
- cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO)]])
-
- caps_changed_flag = False
-
- # don't receive any D-Bus signal
+ cc, = q.expect_many(
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged',
+ predicate=lambda e: contact_handle1 in e.args[0]),
+ )
+ assert_rccs_callable(cc.args[0][contact_handle1])
+
+ # don't receive any further signals
+ q.forbid_events(forbidden)
sync_dbus(bus, q, conn)
- assert caps_changed_flag == False
+ q.unforbid_events(forbidden)
def test_39464(q, bus, conn, stream):
"""
@@ -318,10 +325,6 @@ def test_39464(q, bus, conn, stream):
sync_stream(q, stream)
def test(q, bus, conn, stream):
- # be notified when the signal CapabilitiesChanged is fired
- conn_caps_iface = dbus.Interface(conn, cs.CONN_IFACE_CAPS)
- conn_caps_iface.connect_to_signal('CapabilitiesChanged', caps_changed_cb)
-
test_hash(q, bus, conn, stream, 'bob@foo.com/Foo', 2L, 'http://telepathy.freedesktop.org/fake-client')
test_hash(q, bus, conn, stream, 'bob2@foo.com/Foo', 3L, 'http://telepathy.freedesktop.org/fake-client2')
diff --git a/tests/twisted/caps/jingle-caps.py b/tests/twisted/caps/jingle-caps.py
index 42f69cf1d..4b142059b 100644
--- a/tests/twisted/caps/jingle-caps.py
+++ b/tests/twisted/caps/jingle-caps.py
@@ -13,8 +13,10 @@ from servicetest import (
)
import constants as cs
import ns
-from caps_helper import presence_and_disco, compute_caps_hash, send_presence
+from caps_helper import (presence_and_disco, compute_caps_hash, send_presence,
+ get_contacts_capabilities_sync)
from jingle.jingletest2 import JingleTest2, JingleProtocol031
+from call_helper import CallTest
from config import VOIP_ENABLED
@@ -46,17 +48,14 @@ def test_caps(q, conn, stream, contact, features, audio, video, google=False):
client, caps, features)
cflags = 0
- stream_expected_media_caps = []
call_expected_media_caps = []
if audio:
cflags |= cs.MEDIA_CAP_AUDIO
- stream_expected_media_caps.append (cs.INITIAL_AUDIO)
call_expected_media_caps.append (cs.CALL_INITIAL_AUDIO)
call_expected_media_caps.append (cs.CALL_INITIAL_AUDIO_NAME)
if video:
cflags |= cs.MEDIA_CAP_VIDEO
- stream_expected_media_caps.append (cs.INITIAL_VIDEO)
call_expected_media_caps.append (cs.CALL_INITIAL_VIDEO)
call_expected_media_caps.append (cs.CALL_INITIAL_VIDEO_NAME)
@@ -64,32 +63,17 @@ def test_caps(q, conn, stream, contact, features, audio, video, google=False):
# client, they'll have the ImmutableStreams cap.
if cflags < (cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO) or google:
cflags |= cs.MEDIA_CAP_IMMUTABLE_STREAMS
- stream_expected_media_caps.append(cs.IMMUTABLE_STREAMS)
else:
call_expected_media_caps.append(cs.CALL_MUTABLE_CONTENTS)
- _, event = q.expect_many(
- EventPattern('dbus-signal', signal='CapabilitiesChanged',
- args = [[ ( h,
- cs.CHANNEL_TYPE_STREAMED_MEDIA,
- 0, # old generic
- 3, # new generic (can create and receive these)
- 0, # old specific
- cflags ) ]] # new specific
- ),
+ event, = q.expect_many(
EventPattern('dbus-signal', signal='ContactCapabilitiesChanged')
)
- assertContains((h, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, cflags),
- conn.Capabilities.GetCapabilities([h]))
-
- # Check Contact capabilities for streamed media
+ # Check Contact capabilities
assertEquals(len(event.args), 1)
assertEquals (event.args[0],
- conn.ContactCapabilities.GetContactCapabilities([h]))
-
- check_contact_caps (event.args[0][h],
- cs.CHANNEL_TYPE_STREAMED_MEDIA, stream_expected_media_caps)
+ get_contacts_capabilities_sync(conn, [h]))
check_contact_caps (event.args[0][h],
cs.CHANNEL_TYPE_CALL, call_expected_media_caps)
@@ -142,6 +126,11 @@ def test(q, bus, conn, stream):
def test_prefer_phones(q, bus, conn, stream, expect_disco):
cat = 'cat@windowsill'
+ # This needs to be done once per connection
+ jp = JingleProtocol031()
+ JingleTest2(jp, conn, q, stream, 'test@localhost',
+ cat).prepare()
+
def sign_in_a_cat(jid, identities, show=None):
caps['ver'] = compute_caps_hash(identities, features, {})
@@ -151,32 +140,19 @@ def test_prefer_phones(q, bus, conn, stream, expect_disco):
sync_stream(q, stream)
def make_call(expected_recipient):
- jp = JingleProtocol031()
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', 'dummy')
-
- conn.Requests.CreateChannel({
- cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_ID: cat,
- cs.INITIAL_AUDIO: True,
- })
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- session = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session.Ready()
+ class MyTest(CallTest):
+ PEER_JID = expected_recipient
- e = q.expect('dbus-signal', signal='NewStreamHandler')
+ def check_session_initiate_iq(self, e):
+ assertEquals(expected_recipient, e.to)
- stream_handler = make_channel_proxy(conn, e.args[0],
- 'Media.StreamHandler')
- stream_handler.NewNativeCandidate("fake",
- jt.get_remote_transports_dbus())
- stream_handler.Ready(jt.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
+ def prepare(self):
+ # Don't do the preparation step: we did that already
+ pass
- e = q.expect('stream-iq',
- predicate=jp.action_predicate('session-initiate'))
- assertEquals(expected_recipient, e.to)
+ test = MyTest(jp, q, bus, conn, stream, incoming=False, params={})
+ test.run()
features = [ ns.JINGLE_RTP, ns.JINGLE_RTP_AUDIO, ns.JINGLE_RTP_VIDEO
] + all_transports
@@ -214,7 +190,7 @@ def test_google_caps(q, bus, conn, stream):
'ver': '1.1',
'ext': ' '.join(ext_set) }
- handle = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ handle = conn.get_contact_handle_sync(jid)
send_presence(q, conn, stream, jid, gcaps, initial=True)
diff --git a/tests/twisted/caps/offline.py b/tests/twisted/caps/offline.py
index 1313c6d09..dea958b72 100644
--- a/tests/twisted/caps/offline.py
+++ b/tests/twisted/caps/offline.py
@@ -4,6 +4,7 @@ Test for fd.o#32874 -- Offline contacts do not have capabilities.
from gabbletest import exec_test
from servicetest import assertEquals, assertSameSets, assertLength
+from caps_helper import get_contacts_capabilities_sync
import constants as cs
import ns
@@ -26,10 +27,10 @@ def test(q, bus, conn, stream):
q.expect('dbus-signal', signal='StatusChanged',
args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]),
- bob_handle = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ bob_handle = conn.get_contact_handle_sync(jid)
# new ContactCapabilities
- ccaps_map = conn.ContactCapabilities.GetContactCapabilities([bob_handle])
+ ccaps_map = get_contacts_capabilities_sync(conn, [bob_handle])
assertLength(1, ccaps_map)
assertLength(1, ccaps_map[bob_handle])
@@ -40,13 +41,5 @@ def test(q, bus, conn, stream):
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT}, fixed)
assertSameSets([cs.TARGET_HANDLE], allowed)
- # old Capabilities
- all_caps = conn.Capabilities.GetCapabilities([bob_handle])
- assertLength(1, all_caps)
-
- caps = all_caps[0]
-
- assertEquals((bob_handle, cs.CHANNEL_TYPE_TEXT, 3, 0), caps)
-
if __name__ == '__main__':
exec_test(test, do_connect=False)
diff --git a/tests/twisted/caps/receive-jingle.py b/tests/twisted/caps/receive-jingle.py
index 7ea84f535..c35d0dbb8 100644
--- a/tests/twisted/caps/receive-jingle.py
+++ b/tests/twisted/caps/receive-jingle.py
@@ -6,6 +6,8 @@ import dbus
from servicetest import EventPattern, assertEquals, sync_dbus
from gabbletest import exec_test, make_result_iq, make_presence, sync_stream
+from caps_helper import (assert_rccs_callable, assert_rccs_not_callable,
+ check_rccs_callable, get_contacts_capabilities_sync)
import constants as cs
from config import VOIP_ENABLED
@@ -14,26 +16,30 @@ if not VOIP_ENABLED:
print "NOTE: built with --disable-voip"
raise SystemExit(77)
-icaps_attr = cs.CONN_IFACE_CAPS + "/caps"
-basic_caps = [(2, cs.CHANNEL_TYPE_TEXT, 3, 0)]
-
def test(q, bus, conn, stream):
+ bob = conn.get_contact_handle_sync('bob@foo.com')
+
presence = make_presence('bob@foo.com/Foo', status='hello')
stream.send(presence)
q.expect('dbus-signal', signal='PresencesChanged',
- args=[{2L: (2, u'available', 'hello')}])
+ args=[{bob: (cs.PRESENCE_AVAILABLE, u'available', 'hello')}])
- # FIXME: throughout this test, Bob's handle is assumed to be 2.
+ basic_caps = [(bob, cs.CHANNEL_TYPE_TEXT, 3, 0)]
- # no special capabilities
- assert conn.Capabilities.GetCapabilities([2]) == basic_caps
+ # only Text
+ for rcc in get_contacts_capabilities_sync(conn, [bob])[bob]:
+ assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))
# holding the handle here: see below
- assert conn.Contacts.GetContactAttributes(
- [2], [cs.CONN_IFACE_CAPS], True) == \
- { 2L: { icaps_attr: basic_caps,
- cs.CONN + '/contact-id': 'bob@foo.com'}}
+ assertEquals(
+ { bob: {
+ cs.ATTR_CONTACT_CAPABILITIES:
+ get_contacts_capabilities_sync(conn, [bob])[bob],
+ cs.CONN + '/contact-id': 'bob@foo.com',
+ },
+ },
+ conn.Contacts.GetContactAttributes([bob], [cs.CONN_IFACE_CONTACT_CAPS], True))
# send updated presence with Jingle audio/video caps info. we turn on both
# audio and video at the same time to test that all of the capabilities are
@@ -76,16 +82,22 @@ def test(q, bus, conn, stream):
stream.send(result)
# we can now do audio and video calls
- event = q.expect('dbus-signal', signal='CapabilitiesChanged',
- args=[[(2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 0, 3,
- 0, cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO)]])
-
- caps = conn.Contacts.GetContactAttributes([2], [cs.CONN_IFACE_CAPS], False)
- assert caps.keys() == [2L]
- assert icaps_attr in caps[2L]
- assert len(caps[2L][icaps_attr]) == 2
- assert basic_caps[0] in caps[2L][icaps_attr]
- assert (2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, 3) in caps[2L][icaps_attr]
+ cc, = q.expect_many(
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged',
+ predicate=lambda e: check_rccs_callable(e.args[0][bob])),
+ )
+ assert_rccs_callable(cc.args[0][bob], require_video=True,
+ mutable_contents=True)
+
+ assertEquals(
+ { bob: {
+ cs.ATTR_CONTACT_CAPABILITIES:
+ cc.args[0][bob],
+ cs.CONN + '/contact-id': 'bob@foo.com',
+ },
+ },
+ conn.Contacts.GetContactAttributes([bob],
+ [cs.CONN_IFACE_CONTACT_CAPS], True))
# send updated presence without video support
presence = make_presence('bob@foo.com/Foo', status='hello',
@@ -97,19 +109,22 @@ def test(q, bus, conn, stream):
# we can now do only audio calls (and as a result have the ImmutableStreams
# cap)
- event = q.expect('dbus-signal', signal='CapabilitiesChanged',
- args=[[(2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, 3,
- cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_VIDEO,
- cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_IMMUTABLE_STREAMS)]])
-
- caps = conn.Contacts.GetContactAttributes([2], [cs.CONN_IFACE_CAPS], False)
- assert caps.keys() == [2L]
- assert icaps_attr in caps[2L]
- assert len(caps[2L][icaps_attr]) == 2
- assert basic_caps[0] in caps[2L][icaps_attr]
- assert (2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3,
- cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_IMMUTABLE_STREAMS) \
- in caps[2L][icaps_attr]
+ cc, = q.expect_many(
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
+ )
+ assert_rccs_callable(cc.args[0][bob])
+ assert_rccs_not_callable(cc.args[0][bob], require_audio=False,
+ require_video=True, mutable_contents=False)
+
+ assertEquals(
+ { bob: {
+ cs.ATTR_CONTACT_CAPABILITIES:
+ cc.args[0][bob],
+ cs.CONN + '/contact-id': 'bob@foo.com',
+ },
+ },
+ conn.Contacts.GetContactAttributes([bob],
+ [cs.CONN_IFACE_CONTACT_CAPS], True))
# go offline
presence = make_presence('bob@foo.com/Foo', type='unavailable')
@@ -117,35 +132,31 @@ def test(q, bus, conn, stream):
# can't do audio calls any more
q.expect_many(
- EventPattern('dbus-signal', signal='CapabilitiesChanged',
- args=[[(2, cs.CHANNEL_TYPE_STREAMED_MEDIA, 3, 0,
- cs.MEDIA_CAP_AUDIO | cs.MEDIA_CAP_IMMUTABLE_STREAMS,
- 0)]],
- ),
EventPattern('dbus-signal', signal='PresencesChanged',
- args=[{2: (cs.PRESENCE_OFFLINE, 'offline', '')}]),
+ args=[{bob: (cs.PRESENCE_OFFLINE, 'offline', '')}]),
+ EventPattern('dbus-signal', signal='ContactCapabilitiesChanged'),
)
# Contact went offline. Previously, this test asserted that the handle
# became invalid, but that's not guaranteed to happen immediately; so we
# now hold the handle (above), to guarantee that it does *not* become
# invalid.
- assert conn.Contacts.GetContactAttributes(
- [2], [cs.CONN_IFACE_CAPS], False) == \
- { 2L: { icaps_attr: basic_caps,
- cs.CONN + '/contact-id': 'bob@foo.com'}}
+ rccs = get_contacts_capabilities_sync(conn, [bob])[bob]
+ for rcc in rccs:
+ assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))
+
+ assertEquals(
+ { bob: {
+ cs.ATTR_CONTACT_CAPABILITIES: rccs,
+ cs.CONN + '/contact-id': 'bob@foo.com',
+ },
+ },
+ conn.Contacts.GetContactAttributes([bob],
+ [cs.CONN_IFACE_CONTACT_CAPS], True))
# What about a handle that's not valid?
assertEquals({}, conn.Contacts.GetContactAttributes(
- [31337], [cs.CONN_IFACE_CAPS], False))
-
- # regression test for fd.o #15198: getting caps of invalid handle crashed
- try:
- conn.Capabilities.GetCapabilities([31337])
- except dbus.DBusException, e:
- pass
- else:
- assert False, "Should have had an error!"
+ [31337], [cs.CONN_IFACE_CONTACT_CAPS], False))
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/caps/trust-thyself.py b/tests/twisted/caps/trust-thyself.py
index 34a145b62..fda08ec3e 100644
--- a/tests/twisted/caps/trust-thyself.py
+++ b/tests/twisted/caps/trust-thyself.py
@@ -49,12 +49,25 @@ def test(q, bus, conn, stream):
stream.send(p)
sync_stream(q, stream)
- # Advertise some different capabilities, to change our own caps hash.
- add = [(cs.CHANNEL_TYPE_STREAMED_MEDIA, 2L**32-1),
- (cs.CHANNEL_TYPE_STREAM_TUBE, 2L**32-1),
- (cs.CHANNEL_TYPE_STREAM_TUBE, 2L**32-1)]
- remove = []
- caps = conn.Capabilities.AdvertiseCapabilities(add, remove)
+ conn.ContactCapabilities.UpdateCapabilities([
+ (cs.CLIENT + '.AbiWord', [
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
+ cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
+ cs.STREAM_TUBE_SERVICE: 'x-abiword' },
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
+ cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
+ cs.STREAM_TUBE_SERVICE: 'x-abiword' },
+ ], []),
+ (cs.CLIENT + '.KCall', [
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CALL },
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CALL, cs.CALL_INITIAL_AUDIO: True},
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CALL, cs.CALL_INITIAL_VIDEO: True},
+ ], [
+ cs.CHANNEL_TYPE_CALL + '/gtalk-p2p',
+ cs.CHANNEL_TYPE_CALL + '/ice-udp',
+ cs.CHANNEL_TYPE_CALL + '/video/h264',
+ ]),
+ ])
self_presence = q.expect('stream-presence')
c_ = xpath.queryForNodes('/presence/c', self_presence.stanza)[0]
diff --git a/tests/twisted/caps/tube-caps.py b/tests/twisted/caps/tube-caps.py
index 3d3f698dd..1ceb6f8b5 100644
--- a/tests/twisted/caps/tube-caps.py
+++ b/tests/twisted/caps/tube-caps.py
@@ -47,7 +47,7 @@ import constants as cs
from caps_helper import compute_caps_hash, text_fixed_properties,\
text_allowed_properties, stream_tube_fixed_properties, stream_tube_allowed_properties,\
dbus_tube_fixed_properties, dbus_tube_allowed_properties, receive_presence_and_ask_caps,\
- caps_contain, ft_fixed_properties, ft_allowed_properties
+ caps_contain, ft_fixed_properties, ft_allowed_properties, get_contacts_capabilities_sync
import ns
specialized_tube_allowed_properties = dbus.Array([cs.TARGET_HANDLE,
@@ -130,11 +130,11 @@ def receive_caps(q, conn, stream, contact, contact_handle, features,
# Make sure Gabble's got the caps
sync_stream(q, stream)
- caps = conn.ContactCapabilities.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assertSameElements(expected_caps, caps)
# test again, to check GetContactCapabilities does not have side effect
- caps = conn.ContactCapabilities.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assertSameElements(expected_caps, caps)
# check the Contacts interface give the same caps
@@ -144,11 +144,11 @@ def receive_caps(q, conn, stream, contact, contact_handle, features,
assertSameElements(caps[contact_handle], caps_via_contacts_iface)
def test_tube_caps_from_contact(q, bus, conn, stream, contact):
- contact_handle = conn.RequestHandles(cs.HT_CONTACT, [contact])[0]
+ contact_handle = conn.get_contact_handle_sync(contact)
# Check that we don't crash if we haven't seen any caps/presence for this
# contact yet.
- caps = conn.ContactCapabilities.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
basic_caps = dbus.Dictionary({contact_handle:
[(text_fixed_properties, text_allowed_properties)]})
@@ -227,7 +227,7 @@ def test_tube_caps_from_contact(q, bus, conn, stream, contact):
def advertise_caps(q, conn, stream, filters, expected_features, unexpected_features,
expected_caps):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
ret_caps = conn.ContactCapabilities.UpdateCapabilities(
[(cs.CLIENT + '.Foo', filters, [])])
@@ -245,7 +245,7 @@ def advertise_caps(q, conn, stream, filters, expected_features, unexpected_featu
assertDoesNotContain(var, namespaces)
# Check our own caps
- caps = conn.ContactCapabilities.GetContactCapabilities([self_handle])
+ caps = get_contacts_capabilities_sync(conn, [self_handle])
assertSameElements(expected_caps, caps)
# check the Contacts interface give the same caps
@@ -255,7 +255,7 @@ def advertise_caps(q, conn, stream, filters, expected_features, unexpected_featu
assertSameElements(caps[self_handle], caps_via_contacts_iface)
def test_tube_caps_to_contact(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
basic_caps = dbus.Dictionary({self_handle:
[(text_fixed_properties, text_allowed_properties),
@@ -292,7 +292,7 @@ def test_tube_caps_to_contact(q, bus, conn, stream):
(ft_fixed_properties, ft_allowed_properties)]})
# Check our own caps
- caps = conn.ContactCapabilities.GetContactCapabilities([self_handle])
+ caps = get_contacts_capabilities_sync(conn, [self_handle])
assertEquals(basic_caps, caps)
# check the Contacts interface give the same caps
@@ -306,7 +306,7 @@ def test_tube_caps_to_contact(q, bus, conn, stream):
[(cs.CLIENT + '.Foo', {}, [])])
# Check our own caps
- caps = conn.ContactCapabilities.GetContactCapabilities([self_handle])
+ caps = get_contacts_capabilities_sync(conn, [self_handle])
assertLength(1, caps)
assertEquals(basic_caps, caps)
@@ -323,7 +323,7 @@ def test_tube_caps_to_contact(q, bus, conn, stream):
[(cs.CLIENT + '.Foo', [outgoing_daap_fixed_properties], [])])
# Check our own caps
- caps = conn.ContactCapabilities.GetContactCapabilities([self_handle])
+ caps = get_contacts_capabilities_sync(conn, [self_handle])
assertLength(1, caps)
assertEquals(basic_caps, caps)
diff --git a/tests/twisted/caps_helper.py b/tests/twisted/caps_helper.py
index 11b05d9d8..b5579a2e0 100644
--- a/tests/twisted/caps_helper.py
+++ b/tests/twisted/caps_helper.py
@@ -315,8 +315,15 @@ def presence_and_disco(q, conn, stream, contact, disco,
return h
+def get_contacts_capabilities_sync(conn, contacts):
+ h2asv = conn.Contacts.GetContactAttributes(contacts, [cs.CONN_IFACE_CONTACT_CAPS], False)
+ ret = {}
+ for h in contacts:
+ ret[h] = h2asv[h][cs.ATTR_CONTACT_CAPABILITIES]
+ return ret
+
def send_presence(q, conn, stream, contact, caps, initial=True, show=None):
- h = conn.RequestHandles(cs.HT_CONTACT, [contact])[0]
+ h = conn.get_contact_handle_sync(contact)
if initial:
stream.send(make_presence(contact, status='hello'))
@@ -326,8 +333,8 @@ def send_presence(q, conn, stream, contact, caps, initial=True, show=None):
(2, u'available', 'hello')}])
# no special capabilities
- assertEquals([(h, cs.CHANNEL_TYPE_TEXT, 3, 0)],
- conn.Capabilities.GetCapabilities([h]))
+ for rcc in get_contacts_capabilities_sync(conn, [h])[h]:
+ assertEquals(cs.CHANNEL_TYPE_TEXT, rcc[0].get(cs.CHANNEL_TYPE))
# send updated presence with caps info
stream.send(make_presence(contact, show=show, status='hello', caps=caps))
@@ -345,6 +352,73 @@ def send_disco_reply(stream, stanza, identities, features, dataforms={}):
stream.send(
make_caps_disco_reply(stream, stanza, identities, features, dataforms))
+def assert_rccs_callable(rccs, **kwargs):
+ assert check_rccs_callable(rccs, **kwargs), rccs
+
+def assert_rccs_not_callable(rccs, **kwargs):
+ assert not check_rccs_callable(rccs, **kwargs), rccs
+
+def check_rccs_callable(rccs,
+ require_audio=True,
+ require_video=False,
+ mutable_contents=None):
+ """rccs: a list of RequestableChannelClass tuples"""
+
+ audio_callable = False
+ video_callable = False
+ av_callable = False
+
+ for rcc in rccs:
+ fixed, allowed = rcc
+
+ if fixed.get(cs.CHANNEL_TYPE) != cs.CHANNEL_TYPE_CALL:
+ continue
+
+ if fixed.get(cs.TARGET_HANDLE_TYPE) != cs.HT_CONTACT:
+ continue
+
+ if len(fixed) > (int(cs.CHANNEL_TYPE in fixed) +
+ int(cs.TARGET_HANDLE_TYPE in fixed) +
+ int(cs.CALL_INITIAL_AUDIO in fixed) +
+ int(cs.CALL_INITIAL_VIDEO in fixed)):
+ continue
+
+ assert fixed.get(cs.CALL_INITIAL_AUDIO) in (True, None)
+ assert fixed.get(cs.CALL_INITIAL_VIDEO) in (True, None)
+
+ if mutable_contents is not None:
+ if mutable_contents:
+ assertContains(cs.CALL_MUTABLE_CONTENTS, allowed)
+ else:
+ assertDoesNotContain(cs.CALL_MUTABLE_CONTENTS, allowed)
+
+ if (fixed.get(cs.CALL_INITIAL_AUDIO) == True or
+ cs.CALL_INITIAL_AUDIO in allowed):
+ audio_callable = True
+ assertContains(cs.CALL_INITIAL_AUDIO_NAME, allowed)
+
+ if (fixed.get(cs.CALL_INITIAL_VIDEO) == True or
+ cs.CALL_INITIAL_VIDEO in allowed):
+ video_callable = True
+ assertContains(cs.CALL_INITIAL_VIDEO_NAME, allowed)
+
+ if ((fixed.get(cs.CALL_INITIAL_AUDIO) == True or
+ cs.CALL_INITIAL_AUDIO in allowed) and
+ (fixed.get(cs.CALL_INITIAL_VIDEO) == True or
+ cs.CALL_INITIAL_VIDEO in allowed)):
+ av_callable = True
+
+ if require_audio and not audio_callable:
+ return False
+
+ if require_video and not video_callable:
+ return False
+
+ if require_audio and require_video and not av_callable:
+ return False
+
+ return True
+
if __name__ == '__main__':
# example from XEP-0115
assertEquals('QgayPKawpkPSDYmwT/WM94uAlu0=',
diff --git a/tests/twisted/client-types.py b/tests/twisted/client-types.py
index 2eaeebedb..7becd11a4 100644
--- a/tests/twisted/client-types.py
+++ b/tests/twisted/client-types.py
@@ -1,10 +1,10 @@
"""
Test Conn.I.ClientTypes
"""
-import random
from functools import partial
-from servicetest import EventPattern, assertEquals, assertLength, assertContains, assertSameSets
+from servicetest import (EventPattern, assertEquals, assertLength,
+ assertContains, assertSameSets, call_async)
from gabbletest import exec_test, make_presence, sync_stream
import constants as cs
import ns
@@ -50,7 +50,7 @@ def build_stuff(identities):
def contact_online(q, conn, stream, contact, identities,
disco=True, dataforms={}, initial=True, show=None):
(caps, client, types) = build_stuff(identities)
- handle = conn.RequestHandles(cs.HT_CONTACT, [contact])[0]
+ handle = conn.get_contact_handle_sync(contact)
# make contact come online
presence_and_disco (q, conn, stream, contact,
@@ -62,6 +62,10 @@ def contact_online(q, conn, stream, contact, identities,
event = q.expect('dbus-signal', signal='ClientTypesUpdated')
assertEquals([handle, types], event.args)
+def get_client_types(conn, handle):
+ h2asv = conn.Contacts.GetContactAttributes([handle], [cs.CONN_IFACE_CLIENT_TYPES], False)
+ return h2asv[handle][cs.ATTR_CLIENT_TYPES]
+
def test(q, bus, conn, stream):
# check all these types appear as they should
contact_online(q, conn, stream, 'bot@bot.com/lol', BOT)
@@ -76,7 +80,7 @@ def test(q, bus, conn, stream):
meredith_one = 'meredith@foo.com/One'
meredith_two = 'meredith@foo.com/Two'
meredith_three = 'meredith@foo.com/Three'
- meredith_handle = conn.RequestHandles(cs.HT_CONTACT, [meredith_one])[0]
+ meredith_handle = conn.get_contact_handle_sync(meredith_one)
# Meredith signs in from one resource
contact_online(q, conn, stream, meredith_one, PC, show='chat')
@@ -92,12 +96,16 @@ def test(q, bus, conn, stream):
# ClientTypes should be: ['pc']
# check we're still a PC
- types = conn.GetClientTypes([meredith_handle],
- dbus_interface=cs.CONN_IFACE_CLIENT_TYPES)
+ types = get_client_types(conn, meredith_handle)
+
+ assertLength(1, types)
+ assertEquals('pc', types[0])
+
+ types = conn.RequestClientTypes(meredith_handle,
+ dbus_interface=cs.CONN_IFACE_CLIENT_TYPES)
assertLength(1, types)
- assertLength(1, types[meredith_handle])
- assertEquals('pc', types[meredith_handle][0])
+ assertEquals('pc', types[0])
# Two now becomes more available
stream.send(make_presence(meredith_two, show='chat'))
@@ -106,9 +114,8 @@ def test(q, bus, conn, stream):
# * Two: chat: phone
# ClientTypes should be: ['pc']
- types = conn.GetClientTypes([meredith_handle],
- dbus_interface=cs.CONN_IFACE_CLIENT_TYPES)
- assertEquals('pc', types[meredith_handle][0])
+ types = get_client_types(conn, meredith_handle)
+ assertEquals('pc', types[0])
# One now becomes less available
stream.send(make_presence(meredith_one, show='away'))
@@ -158,9 +165,8 @@ def test(q, bus, conn, stream):
args=[{meredith_handle: (cs.PRESENCE_AWAY, 'away', '')}])
# check it still thinks we're a PC
- types = conn.GetClientTypes([meredith_handle],
- dbus_interface=cs.CONN_IFACE_CLIENT_TYPES)
- assertEquals('pc', types[meredith_handle][0])
+ types = get_client_types(conn, meredith_handle)
+ assertEquals('pc', types[0])
# Three, with multiple identities, signs in
identities = [PHONE[0], CONSOLE[0], HANDHELD[0], BOT[0]]
@@ -201,21 +207,19 @@ def test(q, bus, conn, stream):
def test2(q, bus, conn, stream):
marco_pidgin = 'marco@fancy.italian.restaurant/Pidgin'
marco_phone = 'marco@fancy.italian.restaurant/N900'
- handle = conn.RequestHandles(cs.HT_CONTACT, [marco_pidgin])[0]
+ handle = conn.get_contact_handle_sync(marco_pidgin)
# pidgin comes online
contact_online(q, conn, stream, marco_pidgin, PC)
- types = conn.GetClientTypes([handle],
- dbus_interface=cs.CONN_IFACE_CLIENT_TYPES)
- assertSameSets(['pc'], types[handle])
+ types = get_client_types(conn, handle)
+ assertSameSets(['pc'], types)
# phone comes online
contact_online(q, conn, stream, marco_phone, PHONE, initial=False)
- types = conn.GetClientTypes([handle],
- dbus_interface=cs.CONN_IFACE_CLIENT_TYPES)
- assertSameSets(['pc'], types[handle])
+ types = get_client_types(conn, handle)
+ assertSameSets(['pc'], types)
sync_stream(q, stream)
@@ -249,7 +253,7 @@ def two_contacts_with_the_same_hash(q, bus, conn, stream, bare_jids):
contact1 += '/lol'
contact2 += '/whut'
- h1, h2 = conn.RequestHandles(cs.HT_CONTACT, [contact1, contact2])
+ h1, h2 = conn.get_contact_handles_sync([contact1, contact2])
ver = compute_caps_hash(BANANAPHONE, features, {})
caps = {
# Uniquify slightly with a stringified boolean ;-)
diff --git a/tests/twisted/cm/protocol.py b/tests/twisted/cm/protocol.py
index e9c0b1c3b..2c34036c8 100644
--- a/tests/twisted/cm/protocol.py
+++ b/tests/twisted/cm/protocol.py
@@ -3,27 +3,19 @@ Test Gabble's o.T.Protocol implementation
"""
import dbus
-from servicetest import unwrap, tp_path_prefix, assertEquals
+from servicetest import unwrap, tp_path_prefix, assertEquals, assertContains
from gabbletest import exec_test, call_async
import constants as cs
-import time
def test(q, bus, conn, stream):
cm = bus.get_object(cs.CM + '.gabble',
tp_path_prefix + '/ConnectionManager/gabble')
- cm_iface = dbus.Interface(cm, cs.CM)
cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)
protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
assertEquals(set(['jabber']), set(protocols.keys()))
- protocol_names = unwrap(cm_iface.ListProtocols())
- assertEquals(set(['jabber']), set(protocol_names))
-
- cm_params = cm_iface.GetParameters('jabber')
jabber_props = protocols['jabber']
- jabber_params = jabber_props[cs.PROTOCOL + '.Parameters']
- assertEquals(cm_params, jabber_params)
proto = bus.get_object(cm.bus_name, cm.object_path + '/jabber')
proto_iface = dbus.Interface(proto, cs.PROTOCOL)
@@ -39,7 +31,7 @@ def test(q, bus, conn, stream):
assertEquals('foo@mit.edu',
unwrap(proto_iface.NormalizeContact('foo@MIT.Edu/Telepathy')))
- # org.freedesktop.Telepathy.Protocol.Interface.Presence
+ # Protocol.Interface.Presence
expected_status = {'available': (cs.PRESENCE_AVAILABLE, True, True),
'dnd' : (cs.PRESENCE_BUSY, True, True),
'unknown' : (cs.PRESENCE_UNKNOWN, False, False),
@@ -66,6 +58,17 @@ def test(q, bus, conn, stream):
acc_name = unwrap(proto_iface.IdentifyAccount(test_params))
assertEquals(test_params['account'], acc_name)
+ assertContains(cs.PROTOCOL_IFACE_AVATARS, proto_props['Interfaces'])
+ avatar_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL_IFACE_AVATARS))
+ assertEquals(8192, avatar_props['MaximumAvatarBytes'])
+ assertEquals(96, avatar_props['MaximumAvatarHeight'])
+ assertEquals(96, avatar_props['MaximumAvatarWidth'])
+ assertEquals(32, avatar_props['MinimumAvatarHeight'])
+ assertEquals(32, avatar_props['MinimumAvatarWidth'])
+ assertEquals(64, avatar_props['RecommendedAvatarHeight'])
+ assertEquals(64, avatar_props['RecommendedAvatarWidth'])
+ assertEquals(['image/png', 'image/jpeg', 'image/gif'], avatar_props['SupportedAvatarMIMETypes'])
+
conn.Connect()
q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTING, cs.CSR_REQUESTED])
q.expect('stream-authenticated')
diff --git a/tests/twisted/connect/disco-facebook.py b/tests/twisted/connect/disco-facebook.py
new file mode 100644
index 000000000..39cd9e631
--- /dev/null
+++ b/tests/twisted/connect/disco-facebook.py
@@ -0,0 +1,51 @@
+"""
+Test that Gabble is tolerant of non-RFC-compliance from Facebook.
+https://bugs.freedesktop.org/show_bug.cgi?id=68829
+"""
+
+from gabbletest import exec_test, XmppXmlStream
+import constants as cs
+import ns
+
+from twisted.words.xish import xpath
+
+def test(q, bus, conn, stream):
+ conn.Connect()
+
+ # everything is fine and actually very boring
+ q.expect('dbus-signal', signal='StatusChanged',
+ args=[cs.CONN_STATUS_CONNECTING, cs.CSR_REQUESTED]),
+ q.expect('dbus-signal', signal='StatusChanged',
+ args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
+
+class XmppXmlStreamFacebook201309(XmppXmlStream):
+ """As of 2013-09, a new version of Facebook's XMPP server (used
+ consistently for beta.chat.facebook.com, and gradually being rolled out
+ for chat.facebook.com users) omits the 'from' attribute in its disco
+ reply. The disco reply is otherwise correct.
+ """
+
+ def _cb_disco_iq(self, iq):
+ nodes = xpath.queryForNodes(
+ "/iq/query[@xmlns='" + ns.DISCO_INFO + "']", iq)
+ query = nodes[0]
+
+ for feature in self.disco_features:
+ query.addChild(elem('feature', var=feature))
+
+ iq['type'] = 'result'
+
+ # The Facebook server's IQ responses have neither 'from' nor 'to'
+ try:
+ del iq['from']
+ except KeyError:
+ pass
+ try:
+ del iq['to']
+ except KeyError:
+ pass
+
+ self.send(iq)
+
+if __name__ == '__main__':
+ exec_test(test, protocol=XmppXmlStreamFacebook201309, do_connect=False)
diff --git a/tests/twisted/connect/test-twice.py b/tests/twisted/connect/test-twice.py
index 437ecec61..9ab1b09f7 100644
--- a/tests/twisted/connect/test-twice.py
+++ b/tests/twisted/connect/test-twice.py
@@ -9,8 +9,6 @@ import dbus
import constants as cs
from gabbletest import exec_test
-from rostertest import expect_contact_list_signals, check_contact_list_signals
-from servicetest import assertLength
def test(q, bus, conns, streams):
@@ -30,16 +28,8 @@ def test(q, bus, conns, streams):
args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED],
path=conn1.object.object_path)
- pairs = expect_contact_list_signals(q, bus, conn1,
- ['publish', 'subscribe', 'stored'])
-
- check_contact_list_signals(q, bus, conn1, pairs.pop(0), cs.HT_LIST,
- 'publish', [])
- check_contact_list_signals(q, bus, conn1, pairs.pop(0), cs.HT_LIST,
- 'subscribe', [])
- check_contact_list_signals(q, bus, conn1, pairs.pop(0), cs.HT_LIST,
- 'stored', [])
- assertLength(0, pairs) # i.e. we popped and checked all of them
+ q.expect('dbus-signal', signal='ContactListStateChanged',
+ args=[cs.CONTACT_LIST_STATE_SUCCESS], path=conn1.object.object_path)
# Connection 2
conn2.Connect()
@@ -54,16 +44,8 @@ def test(q, bus, conns, streams):
args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED],
path=conn2.object.object_path)
- pairs = expect_contact_list_signals(q, bus, conn2,
- ['publish', 'subscribe', 'stored'])
-
- check_contact_list_signals(q, bus, conn2, pairs.pop(0), cs.HT_LIST,
- 'publish', [])
- check_contact_list_signals(q, bus, conn2, pairs.pop(0), cs.HT_LIST,
- 'subscribe', [])
- check_contact_list_signals(q, bus, conn2, pairs.pop(0), cs.HT_LIST,
- 'stored', [])
- assertLength(0, pairs) # i.e. we popped and checked all of them
+ q.expect('dbus-signal', signal='ContactListStateChanged',
+ args=[cs.CONTACT_LIST_STATE_SUCCESS], path=conn2.object.object_path)
if __name__ == '__main__':
exec_test(test, num_instances=2, do_connect=False)
diff --git a/tests/twisted/console.py b/tests/twisted/console.py
index 5eddaf024..3d99c261c 100644
--- a/tests/twisted/console.py
+++ b/tests/twisted/console.py
@@ -4,15 +4,14 @@ A smoketest for the XMPP console API.
from servicetest import (
ProxyWrapper, EventPattern,
- call_async, assertEquals, assertContains, assertNotEquals, sync_dbus,
+ call_async, assertEquals, assertContains, sync_dbus,
)
from gabbletest import exec_test, acknowledge_iq, elem, elem_iq
from config import PLUGINS_ENABLED
-from twisted.words.xish import domish
import ns
import constants as cs
-CONSOLE_PLUGIN_IFACE = "org.freedesktop.Telepathy.Gabble.Plugin.Console"
+CONSOLE_PLUGIN_IFACE = cs.PREFIX + ".Gabble.Plugin.Console"
STACY = 'stacy@pilgrim.lit'
if not PLUGINS_ENABLED:
diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py
index d541c75fe..d792b70bb 100644
--- a/tests/twisted/constants.py
+++ b/tests/twisted/constants.py
@@ -1,10 +1,34 @@
+# Copyright (C) 2009 Nokia Corporation
+# Copyright (C) 2009-2013 Collabora Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
"""
Some handy constants for other tests to share and enjoy.
"""
-from dbus import PROPERTIES_IFACE
+from dbus import PROPERTIES_IFACE, INTROSPECTABLE_IFACE
+
+PREFIX = "org.freedesktop.Telepathy"
+PATH_PREFIX = '/' + PREFIX.replace('.', '/')
+
+tp_name_prefix = PREFIX
+tp_path_prefix = PATH_PREFIX
-CM = "org.freedesktop.Telepathy.ConnectionManager"
+CM = PREFIX + ".ConnectionManager"
HT_NONE = 0
HT_CONTACT = 1
@@ -12,7 +36,7 @@ HT_ROOM = 2
HT_LIST = 3
HT_GROUP = 4
-CHANNEL = "org.freedesktop.Telepathy.Channel"
+CHANNEL = PREFIX + ".Channel"
CHANNEL_IFACE_CALL_STATE = CHANNEL + ".Interface.CallState"
CHANNEL_IFACE_CHAT_STATE = CHANNEL + '.Interface.ChatState'
@@ -38,15 +62,15 @@ CHANNEL_TYPE_TEXT = CHANNEL + ".Type.Text"
CHANNEL_TYPE_TUBES = CHANNEL + ".Type.Tubes"
CHANNEL_TYPE_STREAM_TUBE = CHANNEL + ".Type.StreamTube"
CHANNEL_TYPE_DBUS_TUBE = CHANNEL + ".Type.DBusTube"
-CHANNEL_TYPE_STREAMED_MEDIA = CHANNEL + ".Type.StreamedMedia"
CHANNEL_TYPE_TEXT = CHANNEL + ".Type.Text"
CHANNEL_TYPE_FILE_TRANSFER = CHANNEL + ".Type.FileTransfer"
+CHANNEL_TYPE_ROOM_LIST = CHANNEL + ".Type.RoomList"
CHANNEL_TYPE_SERVER_AUTHENTICATION = \
CHANNEL + ".Type.ServerAuthentication"
CHANNEL_TYPE_SERVER_TLS_CONNECTION = \
CHANNEL + ".Type.ServerTLSConnection"
-TP_AWKWARD_PROPERTIES = "org.freedesktop.Telepathy.Properties"
+TP_AWKWARD_PROPERTIES = PREFIX + ".Properties"
PROPERTY_FLAG_READ = 1
PROPERTY_FLAG_WRITE = 2
PROPERTY_FLAGS_RW = PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE
@@ -60,30 +84,31 @@ INITIATOR_HANDLE = CHANNEL + '.InitiatorHandle'
INITIATOR_ID = CHANNEL + '.InitiatorID'
INTERFACES = CHANNEL + '.Interfaces'
-INITIAL_AUDIO = CHANNEL_TYPE_STREAMED_MEDIA + '.InitialAudio'
-INITIAL_VIDEO = CHANNEL_TYPE_STREAMED_MEDIA + '.InitialVideo'
-IMMUTABLE_STREAMS = CHANNEL_TYPE_STREAMED_MEDIA + '.ImmutableStreams'
-
+CALL_CONTENTS = CHANNEL_TYPE_CALL + '.Contents'
+CALL_CALL_STATE_DETAILS = CHANNEL_TYPE_CALL + '.CallStateDetails'
+CALL_CALL_STATE = CHANNEL_TYPE_CALL + '.CallState'
+CALL_CALL_FLAGS = CHANNEL_TYPE_CALL + '.CallFlags'
+CALL_CALL_STATE_REASON = CHANNEL_TYPE_CALL + '.CallStateReason'
+CALL_HARDWARE_STREAMING = CHANNEL_TYPE_CALL + '.HardwareStreaming'
+CALL_CALL_MEMBERS = CHANNEL_TYPE_CALL + '.CallMembers'
+CALL_MEMBER_IDENTIFIERS = CHANNEL_TYPE_CALL + '.MemberIdentifiers'
+CALL_INITIAL_TRANSPORT = CHANNEL_TYPE_CALL + '.InitialTransport'
CALL_INITIAL_AUDIO = CHANNEL_TYPE_CALL + '.InitialAudio'
CALL_INITIAL_AUDIO_NAME = CHANNEL_TYPE_CALL + '.InitialAudioName'
CALL_INITIAL_VIDEO = CHANNEL_TYPE_CALL + '.InitialVideo'
CALL_INITIAL_VIDEO_NAME = CHANNEL_TYPE_CALL + '.InitialVideoName'
CALL_MUTABLE_CONTENTS = CHANNEL_TYPE_CALL + '.MutableContents'
-CALL_CONTENT = 'org.freedesktop.Telepathy.Call1.Content'
-CALL_CONTENT_IFACE_MEDIA = \
- 'org.freedesktop.Telepathy.Call1.Content.Interface.Media'
-CALL_CONTENT_IFACE_DTMF = \
- 'org.freedesktop.Telepathy.Call1.Content.Interface.DTMF'
+CALL_CONTENT = PREFIX + '.Call1.Content'
+CALL_CONTENT_IFACE_MEDIA = CALL_CONTENT + '.Interface.Media'
+CALL_CONTENT_IFACE_DTMF = CALL_CONTENT + '.Interface.DTMF'
-CALL_CONTENT_MEDIADESCRIPTION = \
- 'org.freedesktop.Telepathy.Call1.Content.MediaDescription'
+CALL_CONTENT_MEDIA_DESCRIPTION = CALL_CONTENT + '.MediaDescription'
-CALL_STREAM = 'org.freedesktop.Telepathy.Call1.Stream'
-CALL_STREAM_IFACE_MEDIA = \
- 'org.freedesktop.Telepathy.Call1.Stream.Interface.Media'
+CALL_STREAM = PREFIX + '.Call1.Stream'
+CALL_STREAM_IFACE_MEDIA = CALL_STREAM + '.Interface.Media'
-CALL_STREAM_ENDPOINT = 'org.freedesktop.Telepathy.Call1.Stream.Endpoint'
+CALL_STREAM_ENDPOINT = CALL_STREAM + '.Endpoint'
CALL_MEDIA_TYPE_AUDIO = 0
CALL_MEDIA_TYPE_VIDEO = 1
@@ -100,11 +125,7 @@ CALL_STREAM_TRANSPORT_WLM_2009 = 4
CALL_STREAM_TRANSPORT_SHM = 5
CALL_STREAM_TRANSPORT_MULTICAST = 6
-#for streamed media
-CALL_STATE_RINGING = 1
-CALL_STATE_HELD = 4
-
-CALL_STATE_UNKNOWN = 0,
+CALL_STATE_UNKNOWN = 0
CALL_STATE_PENDING_INITIATOR = 1
CALL_STATE_INITIALISING = 2
CALL_STATE_INITIALISED = 3
@@ -174,7 +195,7 @@ CONTACT_LIST_STATE_WAITING = 1
CONTACT_LIST_STATE_FAILURE = 2
CONTACT_LIST_STATE_SUCCESS = 3
-CONN = "org.freedesktop.Telepathy.Connection"
+CONN = PREFIX + ".Connection"
CONN_IFACE_AVATARS = CONN + '.Interface.Avatars'
CONN_IFACE_ALIASING = CONN + '.Interface.Aliasing'
CONN_IFACE_CAPS = CONN + '.Interface.Capabilities'
@@ -193,12 +214,23 @@ CONN_IFACE_CLIENT_TYPES = CONN + '.Interface.ClientTypes'
CONN_IFACE_POWER_SAVING = CONN + '.Interface.PowerSaving'
CONN_IFACE_CONTACT_BLOCKING = CONN + '.Interface.ContactBlocking'
CONN_IFACE_ADDRESSING = CONN + '.Interface.Addressing1'
+CONN_IFACE_SERVICE_POINT = CONN + '.Interface.ServicePoint'
+ATTR_ALIAS = CONN_IFACE_ALIASING + '/alias'
+ATTR_AVATAR_TOKEN = CONN_IFACE_AVATARS + '/token'
+ATTR_CLIENT_TYPES = CONN_IFACE_CLIENT_TYPES + '/client-types'
ATTR_CONTACT_CAPABILITIES = CONN_IFACE_CONTACT_CAPS + '/capabilities'
+ATTR_CONTACT_ID = CONN + '/contact-id'
+ATTR_CONTACT_INFO = CONN_IFACE_CONTACT_INFO + '/info'
+ATTR_GROUPS = CONN_IFACE_CONTACT_GROUPS + '/groups'
+ATTR_LOCATION = CONN_IFACE_LOCATION + '/location'
+ATTR_PRESENCE = CONN_IFACE_SIMPLE_PRESENCE + '/presence'
+ATTR_PUBLISH = CONN_IFACE_CONTACT_LIST + '/publish'
+ATTR_SUBSCRIBE = CONN_IFACE_CONTACT_LIST + '/subscribe'
-STREAM_HANDLER = 'org.freedesktop.Telepathy.Media.StreamHandler'
+STREAM_HANDLER = PREFIX + '.Media.StreamHandler'
-ERROR = 'org.freedesktop.Telepathy.Error'
+ERROR = PREFIX + '.Error'
INVALID_ARGUMENT = ERROR + '.InvalidArgument'
NOT_IMPLEMENTED = ERROR + '.NotImplemented'
NOT_AVAILABLE = ERROR + '.NotAvailable'
@@ -209,6 +241,7 @@ CONNECTION_REFUSED = ERROR + '.ConnectionRefused'
CONNECTION_FAILED = ERROR + '.ConnectionFailed'
CONNECTION_LOST = ERROR + '.ConnectionLost'
CANCELLED = ERROR + '.Cancelled'
+NOT_YOURS = ERROR + '.NotYours'
DISCONNECTED = ERROR + '.Disconnected'
REGISTRATION_EXISTS = ERROR + '.RegistrationExists'
AUTHENTICATION_FAILED = ERROR + '.AuthenticationFailed'
@@ -220,10 +253,12 @@ INVALID_HANDLE = ERROR + '.InvalidHandle'
CERT_UNTRUSTED = ERROR + '.Cert.Untrusted'
SERVICE_BUSY = ERROR + '.ServiceBusy'
SERVICE_CONFUSED = ERROR + '.ServiceConfused'
+SOFTWARE_UPGRADE_REQUIRED = ERROR + '.SoftwareUpgradeRequired'
BANNED = ERROR + '.Channel.Banned'
-UNKNOWN_METHOD = 'org.freedesktop.DBus.Error.UnknownMethod'
+DBUS_ERROR_UNKNOWN_METHOD = 'org.freedesktop.DBus.Error.UnknownMethod'
+DBUS_ERROR_NO_REPLY = 'org.freedesktop.DBus.Error.NoReply'
TUBE_PARAMETERS = CHANNEL_IFACE_TUBE + '.Parameters'
TUBE_STATE = CHANNEL_IFACE_TUBE + '.State'
@@ -407,8 +442,9 @@ MEDIA_CAP_GTALKP2P = 8
MEDIA_CAP_ICEUDP = 16
MEDIA_CAP_IMMUTABLE_STREAMS = 32
-CLIENT = 'org.freedesktop.Telepathy.Client'
+CLIENT = PREFIX + '.Client'
+PRESENCE_UNSET = 0
PRESENCE_OFFLINE = 1
PRESENCE_AVAILABLE = 2
PRESENCE_AWAY = 3
@@ -477,9 +513,10 @@ class SendError(object):
TOO_LONG = 4
NOT_IMPLEMENTED = 5
-PROTOCOL = 'org.freedesktop.Telepathy.Protocol'
+PROTOCOL = PREFIX + '.Protocol'
PROTOCOL_IFACE_PRESENCES = PROTOCOL + '.Interface.Presence'
PROTOCOL_IFACE_ADDRESSING = PROTOCOL + '.Interface.Addressing'
+PROTOCOL_IFACE_AVATARS = PROTOCOL + '.Interface.Avatars'
PARAM_REQUIRED = 1
PARAM_REGISTER = 2
@@ -487,7 +524,7 @@ PARAM_HAS_DEFAULT = 4
PARAM_SECRET = 8
PARAM_DBUS_PROPERTY = 16
-AUTHENTICATION = 'org.freedesktop.Telepathy.Authentication'
+AUTHENTICATION = PREFIX + '.Authentication'
AUTH_TLS_CERT = AUTHENTICATION + ".TLSCertificate"
TLS_CERT_STATE_PENDING = 0
@@ -539,3 +576,53 @@ ROOM_SERVER = CHANNEL_IFACE_ROOM + '.Server'
SUBJECT = CHANNEL_IFACE_ROOM + '.Subject'
SUBJECT_PRESENT = 1
SUBJECT_CAN_SET = 2
+
+DEBUG_IFACE = PREFIX + '.Debug'
+DEBUG_PATH = PATH_PREFIX + '/debug'
+
+SERVICE_POINT_TYPE_NONE = 0
+SERVICE_POINT_TYPE_EMERGENCY = 1
+SERVICE_POINT_TYPE_COUNSELING = 2
+
+CLIENT = PREFIX + '.Client'
+CLIENT_PATH = PATH_PREFIX + '/Client'
+OBSERVER = PREFIX + '.Client.Observer'
+APPROVER = PREFIX + '.Client.Approver'
+HANDLER = PREFIX + '.Client.Handler'
+CLIENT_IFACE_REQUESTS = CLIENT + '.Interface.Requests'
+
+ACCOUNT = PREFIX + '.Account'
+ACCOUNT_IFACE_AVATAR = ACCOUNT + '.Interface.Avatar'
+ACCOUNT_IFACE_ADDRESSING = ACCOUNT + '.Interface.Addressing'
+ACCOUNT_IFACE_HIDDEN = ACCOUNT + '.Interface.Hidden.DRAFT1'
+ACCOUNT_IFACE_NOKIA_CONDITIONS = 'com.nokia.Account.Interface.Conditions'
+ACCOUNT_PATH_PREFIX = PATH_PREFIX + '/Account/'
+
+AM = PREFIX + '.AccountManager'
+AM_IFACE_HIDDEN = AM + '.Interface.Hidden.DRAFT1'
+AM_PATH = PATH_PREFIX + '/AccountManager'
+
+CR = PREFIX + '.ChannelRequest'
+CDO = PREFIX + '.ChannelDispatchOperation'
+
+CD = PREFIX + '.ChannelDispatcher'
+CD_IFACE_OP_LIST = PREFIX + '.ChannelDispatcher.Interface.OperationList'
+CD_PATH = PATH_PREFIX + '/ChannelDispatcher'
+CD_REDISPATCH = CD + '.Interface.Redispatch.DRAFT'
+
+MC = PREFIX + '.MissionControl5'
+MC_PATH = PATH_PREFIX + '/MissionControl5'
+
+DTMF_CURRENTLY_SENDING_TONES = CHANNEL_IFACE_DTMF + '.CurrentlySendingTones'
+DTMF_INITIAL_TONES = CHANNEL_IFACE_DTMF + '.InitialTones'
+DTMF_DEFERRED_TONES = CHANNEL_IFACE_DTMF + '.DeferredTones'
+
+TESTDOT = PREFIX + ".Test."
+TESTSLASH = PATH_PREFIX + "/Test/"
+
+TEST_DBUS_ACCOUNT_SERVICE = TESTDOT + "DBusAccountService"
+TEST_DBUS_ACCOUNT_SERVICE_PATH = TESTSLASH + "DBusAccountService"
+TEST_DBUS_ACCOUNT_SERVICE_IFACE = TEST_DBUS_ACCOUNT_SERVICE
+
+TEST_DBUS_ACCOUNT_PLUGIN_PATH = TESTSLASH + "DBusAccountPlugin"
+TEST_DBUS_ACCOUNT_PLUGIN_IFACE = TESTDOT + "DBusAccountPlugin"
diff --git a/tests/twisted/dataforms.py b/tests/twisted/dataforms.py
index 6004c1516..87cb625b8 100644
--- a/tests/twisted/dataforms.py
+++ b/tests/twisted/dataforms.py
@@ -2,10 +2,8 @@
Test dataforms
"""
-from servicetest import sync_dbus, assertEquals
-from gabbletest import exec_test, sync_stream
-import ns
-import constants as cs
+from servicetest import assertEquals
+from gabbletest import exec_test
from caps_helper import receive_presence_and_ask_caps
from config import VOIP_ENABLED
diff --git a/tests/twisted/file-transfer/file_transfer_helper.py b/tests/twisted/file-transfer/file_transfer_helper.py
index 79b3acf92..2ae607f53 100644
--- a/tests/twisted/file-transfer/file_transfer_helper.py
+++ b/tests/twisted/file-transfer/file_transfer_helper.py
@@ -88,13 +88,13 @@ class FileTransferTest(object):
announce_socks5_proxy(self.q, self.stream, disco_event.stanza)
- self.self_handle = self.conn.GetSelfHandle()
- self.self_handle_name = self.conn.InspectHandles(cs.HT_CONTACT, [self.self_handle])[0]
+ self.self_handle = self.conn.Properties.Get(cs.CONN, "SelfHandle")
+ self.self_handle_name = self.conn.inspect_contact_sync(self.self_handle)
def announce_contact(self, name=CONTACT_NAME, metadata=True):
self.contact_name = name
self.contact_full_jid = '%s/Telepathy' % name
- self.handle = self.conn.RequestHandles(cs.HT_CONTACT, [name])[0]
+ self.handle = self.conn.get_contact_handle_sync(name)
presence = domish.Element(('jabber:client', 'presence'))
presence['from'] = self.contact_full_jid
@@ -216,7 +216,7 @@ class ReceiveFileTest(FileTransferTest):
path, props = channels[0]
# check channel properties
- # org.freedesktop.Telepathy.Channel D-Bus properties
+ # Channel D-Bus properties
assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_FILE_TRANSFER
assertSameSets(
[ cs.CHANNEL_IFACE_FILE_TRANSFER_METADATA,
@@ -229,7 +229,7 @@ class ReceiveFileTest(FileTransferTest):
assert props[cs.INITIATOR_HANDLE] == self.handle
assert props[cs.INITIATOR_ID] == self.contact_name
- # org.freedesktop.Telepathy.Channel.Type.FileTransfer D-Bus properties
+ # Channel.Type.FileTransfer D-Bus properties
assert props[cs.FT_STATE] == cs.FT_STATE_PENDING
assert props[cs.FT_CONTENT_TYPE] == self.file.content_type
assert props[cs.FT_FILENAME] == self.file.name
@@ -334,7 +334,6 @@ class ReceiveFileTest(FileTransferTest):
def _read_file_from_socket(self, s):
# Read the file from Gabble's socket
data = ''
- read = 0
to_receive = self.file.size - self.file.offset
e = self.q.expect('dbus-signal', signal='TransferredBytesChanged')
@@ -409,7 +408,7 @@ class SendFileTest(FileTransferTest):
self.ft_path, props = self.conn.Requests.CreateChannel(request)
- # org.freedesktop.Telepathy.Channel D-Bus properties
+ # Channel D-Bus properties
assertEquals(cs.CHANNEL_TYPE_FILE_TRANSFER, props[cs.CHANNEL_TYPE])
assertSameSets(
[ cs.CHANNEL_IFACE_FILE_TRANSFER_METADATA,
@@ -422,7 +421,7 @@ class SendFileTest(FileTransferTest):
assertEquals(self.self_handle, props[cs.INITIATOR_HANDLE])
assertEquals(self.self_handle_name, props[cs.INITIATOR_ID])
- # org.freedesktop.Telepathy.Channel.Type.FileTransfer D-Bus properties
+ # Channel.Type.FileTransfer D-Bus properties
assertEquals(cs.FT_STATE_PENDING, props[cs.FT_STATE])
assertEquals(self.file.content_type, props[cs.FT_CONTENT_TYPE])
assertEquals(self.file.name, props[cs.FT_FILENAME])
diff --git a/tests/twisted/file-transfer/ft-client-caps.py b/tests/twisted/file-transfer/ft-client-caps.py
index 336d7a070..f8c65c940 100644
--- a/tests/twisted/file-transfer/ft-client-caps.py
+++ b/tests/twisted/file-transfer/ft-client-caps.py
@@ -36,18 +36,16 @@ make a FT service advertised as a cap.
import dbus
-from twisted.words.xish import xpath
-
from servicetest import assertEquals, assertLength, assertContains,\
assertDoesNotContain, sync_dbus
-from gabbletest import exec_test, make_result_iq, sync_stream, make_presence
+from gabbletest import exec_test, sync_stream
import constants as cs
from caps_helper import compute_caps_hash, text_fixed_properties,\
text_allowed_properties, stream_tube_fixed_properties, stream_tube_allowed_properties,\
dbus_tube_fixed_properties, dbus_tube_allowed_properties, receive_presence_and_ask_caps,\
- caps_contain, ft_fixed_properties, ft_allowed_properties, ft_allowed_properties_with_metadata, \
- presence_and_disco
+ ft_fixed_properties, ft_allowed_properties, ft_allowed_properties_with_metadata, \
+ presence_and_disco, get_contacts_capabilities_sync
import ns
from config import FILE_TRANSFER_ENABLED
@@ -105,11 +103,11 @@ def receive_caps(q, conn, stream, contact, contact_handle, features,
# Make sure Gabble's got the caps
sync_stream(q, stream)
- caps = conn.ContactCapabilities.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assertSameElements(expected_caps, caps[contact_handle])
# test again, to check GetContactCapabilities does not have side effect
- caps = conn.ContactCapabilities.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assertSameElements(expected_caps, caps[contact_handle])
# check the Contacts interface give the same caps
@@ -119,11 +117,11 @@ def receive_caps(q, conn, stream, contact, contact_handle, features,
assertSameElements(caps[contact_handle], caps_via_contacts_iface)
def test_ft_caps_from_contact(q, bus, conn, stream, contact):
- contact_handle = conn.RequestHandles(cs.HT_CONTACT, [contact])[0]
+ contact_handle = conn.get_contact_handle_sync(contact)
# Check that we don't crash if we haven't seen any caps/presence for this
# contact yet.
- caps = conn.ContactCapabilities.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
basic_caps = [(text_fixed_properties, text_allowed_properties)]
@@ -179,7 +177,7 @@ def advertise_caps(q, bus, conn, stream, filters, expected_features, unexpected_
# make sure nothing from a previous update is still running
sync_dbus(bus, q, conn)
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
ret_caps = conn.ContactCapabilities.UpdateCapabilities(
[(cs.CLIENT + '.Foo', filters, [])])
@@ -197,7 +195,7 @@ def advertise_caps(q, bus, conn, stream, filters, expected_features, unexpected_
assertDoesNotContain(var, namespaces)
# Check our own caps
- caps = conn.ContactCapabilities.GetContactCapabilities([self_handle])
+ caps = get_contacts_capabilities_sync(conn, [self_handle])
assertSameElements(expected_caps, caps[self_handle])
# check the Contacts interface give the same caps
@@ -207,7 +205,7 @@ def advertise_caps(q, bus, conn, stream, filters, expected_features, unexpected_
assertSameElements(caps[self_handle], caps_via_contacts_iface)
def test_ft_caps_to_contact(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
basic_caps = [
(text_fixed_properties, text_allowed_properties),
@@ -233,7 +231,7 @@ def test_ft_caps_to_contact(q, bus, conn, stream):
#
# Check our own caps; we should have no FT caps
#
- caps = conn.ContactCapabilities.GetContactCapabilities([self_handle])
+ caps = get_contacts_capabilities_sync(conn, [self_handle])
assertEquals(basic_caps, caps[self_handle])
# check the Contacts interface give the same caps
@@ -249,7 +247,7 @@ def test_ft_caps_to_contact(q, bus, conn, stream):
[(cs.CLIENT + '.Foo', {}, [])])
# Check our own caps
- caps = conn.ContactCapabilities.GetContactCapabilities([self_handle])
+ caps = get_contacts_capabilities_sync(conn, [self_handle])
assertLength(1, caps)
assertEquals(basic_caps, caps[self_handle])
@@ -268,7 +266,7 @@ def test_ft_caps_to_contact(q, bus, conn, stream):
[(cs.CLIENT + '.Foo', [no_service_fixed_properties], [])])
# Check our own caps
- caps = conn.ContactCapabilities.GetContactCapabilities([self_handle])
+ caps = get_contacts_capabilities_sync(conn, [self_handle])
assertLength(1, caps)
assertEquals(simple_ft_caps, caps[self_handle])
@@ -287,7 +285,7 @@ def test_ft_caps_to_contact(q, bus, conn, stream):
[(cs.CLIENT + '.Foo', [outgoing_daap_fixed_properties], [])])
# Check our own caps
- caps = conn.ContactCapabilities.GetContactCapabilities([self_handle])
+ caps = get_contacts_capabilities_sync(conn, [self_handle])
assertLength(1, caps)
assertEquals(simple_ft_caps, caps[self_handle])
diff --git a/tests/twisted/file-transfer/metadata.py b/tests/twisted/file-transfer/metadata.py
index 8667a9caa..337e90c1a 100644
--- a/tests/twisted/file-transfer/metadata.py
+++ b/tests/twisted/file-transfer/metadata.py
@@ -3,7 +3,7 @@
import dbus
from file_transfer_helper import exec_file_transfer_test, ReceiveFileTest, SendFileTest
-from servicetest import assertEquals, call_async
+from servicetest import call_async
import constants as cs
diff --git a/tests/twisted/file-transfer/test-caps-file-transfer.py b/tests/twisted/file-transfer/test-caps-file-transfer.py
index 743906af0..c7d6c9b30 100644
--- a/tests/twisted/file-transfer/test-caps-file-transfer.py
+++ b/tests/twisted/file-transfer/test-caps-file-transfer.py
@@ -2,14 +2,12 @@ import dbus
from twisted.words.xish import xpath
-from servicetest import assertEquals
from gabbletest import exec_test, make_result_iq, sync_stream, make_presence
import constants as cs
-from caps_helper import compute_caps_hash, text_fixed_properties,\
- text_allowed_properties, stream_tube_fixed_properties,\
- stream_tube_allowed_properties, dbus_tube_fixed_properties,\
- dbus_tube_allowed_properties, ft_fixed_properties, ft_allowed_properties
+from caps_helper import (compute_caps_hash, text_fixed_properties,
+ text_allowed_properties, ft_fixed_properties, ft_allowed_properties,
+ get_contacts_capabilities_sync)
import ns
@@ -50,10 +48,10 @@ def test_ft_caps_from_contact(q, bus, conn, stream, contact, contact_handle, cli
# no special capabilities
basic_caps = dbus.Dictionary({contact_handle:
[(text_fixed_properties, text_allowed_properties)]})
- caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assert caps == basic_caps, caps
# test again, to check GetContactCapabilities does not have side effect
- caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assert caps == basic_caps, caps
# check the Contacts interface give the same caps
caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
@@ -92,10 +90,10 @@ def test_ft_caps_from_contact(q, bus, conn, stream, contact, contact_handle, cli
assert len(event.args) == 1
assert event.args[0] == generic_tubes_caps
- caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assert caps == generic_tubes_caps, caps
# test again, to check GetContactCapabilities does not have side effect
- caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assert caps == generic_tubes_caps, caps
# check the Contacts interface give the same caps
caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
diff --git a/tests/twisted/file-transfer/test-ibb-too-early.py b/tests/twisted/file-transfer/test-ibb-too-early.py
index a5a8d97b8..51b0e46d9 100644
--- a/tests/twisted/file-transfer/test-ibb-too-early.py
+++ b/tests/twisted/file-transfer/test-ibb-too-early.py
@@ -25,7 +25,7 @@ class IbbTooEarlyTest (ReceiveFileTest):
# Instead of us accepting the other side starts sending the iq open
# skip the open step explicitely
self.bytestream.checked = True
- event = self.bytestream.open_bytestream(
+ self.bytestream.open_bytestream(
expected_after = [ EventPattern ('stream-iq', iq_type = 'error') ] )
return True
diff --git a/tests/twisted/file-transfer/test-send-file-declined.py b/tests/twisted/file-transfer/test-send-file-declined.py
index f2e79ab9c..89b865df1 100644
--- a/tests/twisted/file-transfer/test-send-file-declined.py
+++ b/tests/twisted/file-transfer/test-send-file-declined.py
@@ -24,8 +24,8 @@ class SendFileDeclinedTest(SendFileTest):
error = reply.addElement((None, 'error'))
error['code'] = '403'
error['type'] = 'cancel'
- forbidden = error.addElement((ns.STANZA, 'forbidden'))
- text = error.addElement((ns.STANZA, 'text'), content='Offer Declined')
+ error.addElement((ns.STANZA, 'forbidden'))
+ error.addElement((ns.STANZA, 'text'), content='Offer Declined')
self.stream.send(reply)
e = self.q.expect('dbus-signal', signal='FileTransferStateChanged')
diff --git a/tests/twisted/file-transfer/test-send-file-send-before-accept.py b/tests/twisted/file-transfer/test-send-file-send-before-accept.py
index bb1389477..491e86fdc 100644
--- a/tests/twisted/file-transfer/test-send-file-send-before-accept.py
+++ b/tests/twisted/file-transfer/test-send-file-send-before-accept.py
@@ -1,11 +1,7 @@
-import dbus
import constants as cs
from servicetest import EventPattern
from file_transfer_helper import SendFileTest, exec_file_transfer_test
-from twisted.words.xish import domish
-import ns
-
from config import FILE_TRANSFER_ENABLED
if not FILE_TRANSFER_ENABLED:
diff --git a/tests/twisted/file-transfer/test-send-file-to-unknown-contact.py b/tests/twisted/file-transfer/test-send-file-to-unknown-contact.py
index 17d0799ed..dc1d691c2 100644
--- a/tests/twisted/file-transfer/test-send-file-to-unknown-contact.py
+++ b/tests/twisted/file-transfer/test-send-file-to-unknown-contact.py
@@ -17,7 +17,7 @@ class SendFileTransferToUnknownContactTest(SendFileTest):
def my_request_ft_channel(self):
self.contact_name = 'jean@localhost'
- self.handle = self.conn.RequestHandles(cs.HT_CONTACT, [self.contact_name])[0]
+ self.handle = self.conn.get_contact_handle_sync(self.contact_name)
try:
self.request_ft_channel()
diff --git a/tests/twisted/gabbletest.py b/tests/twisted/gabbletest.py
index e6b8baa0e..fe2ce6637 100644
--- a/tests/twisted/gabbletest.py
+++ b/tests/twisted/gabbletest.py
@@ -57,11 +57,6 @@ def send_error_reply(stream, iq, error_stanza=None):
stream.send(result)
-def request_muc_handle(q, conn, stream, muc_jid):
- servicetest.call_async(q, conn, 'RequestHandles', 2, [muc_jid])
- event = q.expect('dbus-return', method='RequestHandles')
- return event.value[0][0]
-
def make_muc_presence(affiliation, role, muc_jid, alias, jid=None, photo=None):
presence = domish.Element((None, 'presence'))
presence['from'] = '%s/%s' % (muc_jid, alias)
@@ -682,7 +677,7 @@ def exec_test_deferred(fun, params, protocol=None, timeout=None,
# Connection has already been disconnected and destroyed
continue
try:
- if conn.GetStatus() == cs.CONN_STATUS_CONNECTED:
+ if conn.Properties.Get(cs.CONN, 'Status') == cs.CONN_STATUS_CONNECTED:
# Connection is connected, properly disconnect it
disconnect_conn(queue, conn, streams[i])
else:
diff --git a/tests/twisted/gateways.py b/tests/twisted/gateways.py
index d4073dd25..3934971b2 100644
--- a/tests/twisted/gateways.py
+++ b/tests/twisted/gateways.py
@@ -5,18 +5,13 @@ Test the gateways plugin
import dbus
from twisted.words.xish import domish, xpath
-from servicetest import (
- sync_dbus, call_async, EventPattern, assertEquals, assertContains,
- )
-from gabbletest import (
- exec_test, send_error_reply, acknowledge_iq, sync_stream,
- make_presence,
- )
+from servicetest import call_async, EventPattern, assertEquals
+from gabbletest import exec_test, send_error_reply, acknowledge_iq, make_presence
import constants as cs
import ns
from config import PLUGINS_ENABLED
-PLUGIN_IFACE = "org.freedesktop.Telepathy.Gabble.Plugin.Gateways"
+PLUGIN_IFACE = cs.PREFIX + ".Gabble.Plugin.Gateways"
if not PLUGINS_ENABLED:
print "NOTE: built without --enable-plugins, not testing plugins"
diff --git a/tests/twisted/jingle-share/file_transfer_helper.py b/tests/twisted/jingle-share/file_transfer_helper.py
index 19a45ca57..f917df2f6 100644
--- a/tests/twisted/jingle-share/file_transfer_helper.py
+++ b/tests/twisted/jingle-share/file_transfer_helper.py
@@ -2,23 +2,20 @@ import dbus
import socket
import hashlib
import time
-import datetime
from servicetest import EventPattern, assertEquals, assertLength, assertSameSets
-from gabbletest import exec_test, sync_stream, make_result_iq, elem_iq, elem
+from gabbletest import exec_test, elem_iq, elem
import ns
from caps_helper import text_fixed_properties, text_allowed_properties, \
stream_tube_fixed_properties, stream_tube_allowed_properties, \
dbus_tube_fixed_properties, dbus_tube_allowed_properties, \
ft_fixed_properties, ft_allowed_properties, compute_caps_hash, \
- extract_disco_parts
+ extract_disco_parts, get_contacts_capabilities_sync
from twisted.words.xish import domish, xpath
import constants as cs
-import sys
-
class File(object):
DEFAULT_DATA = "What a nice file"
@@ -77,12 +74,12 @@ class FileTransferTest(object):
args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED],
path=self.conn.object.object_path)
- self.self_handle = self.conn.GetSelfHandle()
- self.self_handle_name = self.conn.InspectHandles(cs.HT_CONTACT, [self.self_handle])[0]
+ self.self_handle = self.conn.Properties.Get(cs.CONN, "SelfHandle")
+ self.self_handle_name = self.conn.inspect_contact_sync(self.self_handle)
def set_target(self, jid):
self.target = jid
- self.handle = self.conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ self.handle = self.conn.get_contact_handle_sync(jid)
def set_ft_caps(self):
caps_iface = dbus.Interface(self.conn, cs.CONN_IFACE_CONTACT_CAPS)
@@ -95,15 +92,13 @@ class FileTransferTest(object):
args=[{self.self_handle:generic_ft_caps}])
def wait_for_ft_caps(self):
- conn_caps_iface = dbus.Interface(self.conn, cs.CONN_IFACE_CONTACT_CAPS)
-
- caps = conn_caps_iface.GetContactCapabilities([self.handle])
+ caps = get_contacts_capabilities_sync(self.conn, [self.handle])
if caps != dbus.Dictionary({self.handle:generic_ft_caps}):
self.q.expect('dbus-signal',
signal='ContactCapabilitiesChanged',
path=self.conn.object.object_path,
args=[{self.handle:generic_ft_caps}])
- caps = conn_caps_iface.GetContactCapabilities([self.handle])
+ caps = get_contacts_capabilities_sync(self.conn, [self.handle])
assert caps == dbus.Dictionary({self.handle:generic_ft_caps}), caps
def create_ft_channel(self):
diff --git a/tests/twisted/jingle-share/jingleshareutils.py b/tests/twisted/jingle-share/jingleshareutils.py
index 6ade4f50d..21030dc4d 100644
--- a/tests/twisted/jingle-share/jingleshareutils.py
+++ b/tests/twisted/jingle-share/jingleshareutils.py
@@ -2,13 +2,13 @@ import dbus
from twisted.words.xish import xpath
-from servicetest import (assertEquals, EventPattern)
-from gabbletest import exec_test, make_result_iq, sync_stream, make_presence
+from servicetest import (assertEquals)
+from gabbletest import make_result_iq, sync_stream, make_presence
import constants as cs
from caps_helper import compute_caps_hash, \
text_fixed_properties, text_allowed_properties, \
- ft_fixed_properties, ft_allowed_properties
+ ft_fixed_properties, ft_allowed_properties, get_contacts_capabilities_sync
import ns
@@ -47,10 +47,10 @@ def test_ft_caps_from_contact(q, bus, conn, stream, contact, contact_handle, cli
# no special capabilities
basic_caps = dbus.Dictionary({contact_handle:
[(text_fixed_properties, text_allowed_properties)]})
- caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assert caps == basic_caps, caps
# test again, to check GetContactCapabilities does not have side effect
- caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assert caps == basic_caps, caps
# check the Contacts interface give the same caps
caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
@@ -89,10 +89,10 @@ def test_ft_caps_from_contact(q, bus, conn, stream, contact, contact_handle, cli
assert len(event.args) == 1
assert event.args[0] == generic_ft_caps
- caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assert caps == generic_ft_caps, caps
# test again, to check GetContactCapabilities does not have side effect
- caps = conn_caps_iface.GetContactCapabilities([contact_handle])
+ caps = get_contacts_capabilities_sync(conn, [contact_handle])
assert caps == generic_ft_caps, caps
# check the Contacts interface give the same caps
caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
diff --git a/tests/twisted/jingle-share/test-caps-file-transfer.py b/tests/twisted/jingle-share/test-caps-file-transfer.py
index 0bf869a1a..f3be084ed 100644
--- a/tests/twisted/jingle-share/test-caps-file-transfer.py
+++ b/tests/twisted/jingle-share/test-caps-file-transfer.py
@@ -2,15 +2,16 @@ import dbus
from twisted.words.xish import xpath
-from servicetest import (assertEquals, EventPattern)
-from gabbletest import exec_test, make_result_iq, sync_stream, make_presence
+from servicetest import EventPattern
+from gabbletest import exec_test
import constants as cs
-from caps_helper import compute_caps_hash, \
+from caps_helper import \
text_fixed_properties, text_allowed_properties, \
stream_tube_fixed_properties, stream_tube_allowed_properties, \
dbus_tube_fixed_properties, dbus_tube_allowed_properties, \
- ft_fixed_properties, ft_allowed_properties_with_metadata
+ ft_fixed_properties, ft_allowed_properties_with_metadata,\
+ get_contacts_capabilities_sync
import ns
from jingleshareutils import test_ft_caps_from_contact
@@ -43,7 +44,6 @@ generic_caps = [(text_fixed_properties, text_allowed_properties),
(dbus_tube_fixed_properties, dbus_tube_allowed_properties)]
def check_contact_caps(conn, handle, with_ft):
- conn_caps_iface = dbus.Interface(conn, cs.CONN_IFACE_CONTACT_CAPS)
conn_contacts_iface = dbus.Interface(conn, cs.CONN_IFACE_CONTACTS)
if with_ft:
@@ -51,7 +51,7 @@ def check_contact_caps(conn, handle, with_ft):
else:
expected_caps = dbus.Dictionary({handle: generic_caps})
- caps = conn_caps_iface.GetContactCapabilities([handle])
+ caps = get_contacts_capabilities_sync(conn, [handle])
assert caps == expected_caps, caps
# check the Contacts interface give the same caps
caps_via_contacts_iface = conn_contacts_iface.GetContactAttributes(
@@ -65,11 +65,11 @@ def test2(q, bus, connections, streams):
conn1, conn2 = connections
stream1, stream2 = streams
conn1_handle = conn1.Properties.Get(cs.CONN, 'SelfHandle')
- conn1_jid = conn1.InspectHandles(cs.HT_CONTACT, [conn1_handle])[0]
+ conn1_jid = conn1.inspect_contact_sync(conn1_handle)
conn2_handle = conn2.Properties.Get(cs.CONN, 'SelfHandle')
- conn2_jid = conn2.InspectHandles(cs.HT_CONTACT, [conn2_handle])[0]
- handle1 = conn2.RequestHandles(cs.HT_CONTACT, [conn1_jid])[0]
- handle2 = conn1.RequestHandles(cs.HT_CONTACT, [conn2_jid])[0]
+ conn2_jid = conn2.inspect_contact_sync(conn2_handle)
+ handle1 = conn2.get_contact_handle_sync(conn1_jid)
+ handle2 = conn1.get_contact_handle_sync(conn2_jid)
q.expect_many(EventPattern('dbus-signal',
signal='ContactCapabilitiesChanged',
diff --git a/tests/twisted/jingle-share/test-multift.py b/tests/twisted/jingle-share/test-multift.py
index d318e427d..e84276789 100644
--- a/tests/twisted/jingle-share/test-multift.py
+++ b/tests/twisted/jingle-share/test-multift.py
@@ -25,8 +25,8 @@ def test(q, bus, conn, stream):
test_ft_caps_from_contact(q, bus, conn, stream, contact,
2L, client)
- self_handle = conn.GetSelfHandle()
- jid = conn.InspectHandles(cs.HT_CONTACT, [self_handle])[0]
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
+ jid = conn.inspect_contact_sync(self_handle)
iq = IQ(stream, "set")
iq['to'] = jid
@@ -59,17 +59,46 @@ def test(q, bus, conn, stream):
url['name'] = 'preview-path'
stream.send(iq)
- event = q.expect('dbus-signal', signal="NewChannels")
- channels = event.args[0]
- # Make sure we get the right amout of channels
- assert len(channels) == len(files)
+ patterns = []
+ found = {}
+
+ def get_predicate(name, found, i):
+ # This needs to be a function so that name, found, i
+ # are part of a closure.
+
+ # /!\ This predicate has side-effects: it writes to 'found'
+ def predicate(e):
+ path, props = e.args[0][0]
+ if props[cs.CHANNEL_TYPE] != cs.CHANNEL_TYPE_FILE_TRANSFER:
+ return False
+
+ if props[cs.FT_FILENAME] == name:
+ found[i] = (path, props)
+ return True
+ return predicate
+
+ for i, f in enumerate(files):
+ type, name, size, image = f
+ if type == "folder":
+ name = "%s.tar" % name
+
+ return False
+
+ patterns.append(EventPattern('dbus-signal',
+ signal='NewChannels',
+ predicate=get_predicate(name, found, i)))
# Make sure every file transfer has a channel associated with it
- found = [False for i in files]
file_collection = None
- for channel in channels:
- path, props = channel
+ q.expect_many(*patterns)
+ assertLength(len(files), found)
+
+ channels = []
+ for i in found:
+ assert found[i] is not None
+ path, props = found[i]
+ channels.append((path, props))
# Get the FileCollection and make sure it exists
if file_collection is None:
@@ -80,17 +109,11 @@ def test(q, bus, conn, stream):
# FileCollection must be the same for every channel
assert props[cs.FT_FILE_COLLECTION] == file_collection, props
- for i, f in enumerate(files):
- type, name, size, image = f
- if type == "folder":
- name = "%s.tar" % name
- if size is None:
- size = 0
+ type, name, size, image = files[i]
+ if size is None:
+ size = 0
- if props[cs.FT_FILENAME].encode('utf=8') == name:
- assert found[i] == False
- found[i] = True
- assert props[cs.FT_SIZE] == size, props
+ assertEquals(size, props[cs.FT_SIZE])
assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_FILE_TRANSFER, props
assertSameSets(
@@ -118,8 +141,6 @@ def test(q, bus, conn, stream):
assert props[cs.FT_TRANSFERRED_BYTES] == 0, props
assert props[cs.FT_INITIAL_OFFSET] == 0, props
- assert False not in found
-
event = q.expect('stream-iq', to=contact,
iq_type='set', query_name='session')
session_node = event.query
diff --git a/tests/twisted/jingle/accept-extra-stream.py b/tests/twisted/jingle/accept-extra-stream.py
deleted file mode 100644
index 95e46377c..000000000
--- a/tests/twisted/jingle/accept-extra-stream.py
+++ /dev/null
@@ -1,198 +0,0 @@
-"""
-Test that we can accept streams added after the call has been accepted.
-"""
-
-from servicetest import (
- make_channel_proxy, EventPattern, sync_dbus, call_async,
- assertEquals,
- )
-from gabbletest import exec_test, make_result_iq, sync_stream
-import constants as cs
-
-from jingletest2 import JingleProtocol031, JingleTest2
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(q, bus, conn, stream):
- worker(q, bus, conn, stream, remote_jid='foo@bar.com/Foo')
-
-def test_bare_jid(q, bus, conn, stream):
- worker(q, bus, conn, stream, remote_jid='foo@sip.bar.com')
-
-def worker(q, bus, conn, stream, remote_jid):
- jp = JingleProtocol031()
- jt2 = JingleTest2(jp, conn, q, stream, 'test@localhost', remote_jid)
- jt2.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, [jt2.peer])[0]
-
- # Remote end calls us
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'session-initiate', [
- jp.Content('audiostream', 'initiator', 'both',
- jp.Description('audio', [
- jp.PayloadType(name, str(rate), str(id), parameters) for
- (name, id, rate, parameters) in jt2.audio_codecs ]),
- jp.TransportGoogleP2P()) ]) ])
- stream.send(jp.xml(node))
-
- nc = q.expect('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args)
- path, ct, ht, h, sh = nc.args
- assert ct == cs.CHANNEL_TYPE_STREAMED_MEDIA, ct
- assert ht == cs.HT_CONTACT, ht
- assert h == remote_handle, h
-
- group = make_channel_proxy(conn, path, 'Channel.Interface.Group')
- sm = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')
- ms = make_channel_proxy(conn, path, 'Channel.Interface.MediaSignalling')
-
- streams = sm.ListStreams()
- assert len(streams) == 1, streams
- audio_stream_id, h, media_type, state, direction, pending = streams[0]
- assert h == remote_handle, (h, remote_handle)
- assert media_type == cs.MEDIA_STREAM_TYPE_AUDIO, media_type
- assert state == cs.MEDIA_STREAM_STATE_DISCONNECTED, state
- # FIXME: This turns out to be Bidirectional; wjt thinks this sounds wrong
- # since the stream is (we hope) pending local send.
- #assert direction == cs.MEDIA_STREAM_DIRECTION_RECEIVE, direction
- assert pending == cs.MEDIA_STREAM_PENDING_LOCAL_SEND, pending
-
- session_handlers = ms.GetSessionHandlers()
- assert len(session_handlers) == 1, session_handlers
- session_handler = make_channel_proxy(conn, session_handlers[0][0],
- 'Media.SessionHandler')
- session_handler.Ready()
-
- nsh = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_handler_path, stream_id, media_type, direction = nsh.args
- assert stream_id == audio_stream_id, (stream_id, audio_stream_id)
- assert media_type == cs.MEDIA_STREAM_TYPE_AUDIO, media_type
- # FIXME: As above
- #assert direction == cs.MEDIA_STREAM_DIRECTION_RECEIVE, direction
-
- stream_handler = make_channel_proxy(conn, stream_handler_path,
- 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", jt2.get_remote_transports_dbus())
- stream_handler.Ready(jt2.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
- stream_handler.SupportedCodecs(jt2.get_audio_codecs_dbus())
-
- # peer gets the transport
- e = q.expect('stream-iq', predicate=jp.action_predicate('transport-info'))
- assertEquals(jt2.peer, e.query['initiator'])
-
- stream.send(make_result_iq(stream, e.stanza))
-
- # Make sure all the above's happened.
- sync_stream(q, stream)
- sync_dbus(bus, q, conn)
-
- # At last, accept the call
- group.AddMembers([self_handle], 'accepted')
-
- # Call is accepted, we become a member, and the stream that was pending
- # local send is now sending.
- memb, acc, _, _, _, = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [self_handle], [], [], [],
- self_handle,
- cs.GC_REASON_NONE]),
- EventPattern('stream-iq',
- predicate=lambda e: (e.query.name == 'jingle' and
- e.query['action'] == 'session-accept')),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[True]),
- EventPattern('dbus-signal', signal='SetStreamPlaying', args=[True]),
- EventPattern('dbus-signal', signal='StreamDirectionChanged',
- args=[audio_stream_id, cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL, 0]),
- )
-
- # Respond to session-accept
- # FIXME: wjt thinks Gabble should accept the content-add without this.
- stream.send(jp.xml(jp.ResultIq('test@localhost', acc.stanza, [])))
-
- # Foo would like to gaze upon our beautiful complexion
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'content-add', [
- jp.Content('videostream', 'initiator', 'both',
- jp.Description('video', [
- jp.PayloadType(name, str(rate), str(id), parameters) for
- (name, id, rate, parameters) in jt2.video_codecs ]),
- jp.TransportGoogleP2P()) ]) ])
- stream.send(jp.xml(node))
-
- added, nsh = q.expect_many(
- EventPattern('dbus-signal', signal='StreamAdded'),
- EventPattern('dbus-signal', signal='NewStreamHandler'),
- )
-
- video_stream_id, h, type = added.args
- assert h == remote_handle, (h, remote_handle)
- assert type == cs.MEDIA_STREAM_TYPE_VIDEO, type
-
- stream_handler_path, stream_id, media_type, direction = nsh.args
- assert stream_id == video_stream_id, (stream_id, video_stream_id)
- assert media_type == cs.MEDIA_STREAM_TYPE_VIDEO, type
- # FIXME: As above
- #assert direction == cs.MEDIA_STREAM_DIRECTION_RECEIVE, direction
-
- video_handler = make_channel_proxy(conn, stream_handler_path,
- 'Media.StreamHandler')
-
- video_handler.NewNativeCandidate("fake", jt2.get_remote_transports_dbus())
- video_handler.Ready(jt2.get_video_codecs_dbus())
- video_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
- video_handler.SupportedCodecs(jt2.get_video_codecs_dbus())
-
- ti, _, _, _ = q.expect_many(
- # Peer gets the transport
- EventPattern('stream-iq',
- predicate=jp.action_predicate('transport-info')),
- # Gabble tells the peer we accepted
- EventPattern('stream-iq',
- predicate=jp.action_predicate('content-accept')),
- EventPattern('dbus-signal', signal='SetStreamPlaying', args=[True]),
- # It's not entirely clear that this *needs* to fire here...
- EventPattern('dbus-signal', signal='SetStreamSending', args=[False]),
- )
- assertEquals(jt2.peer, ti.query['initiator'])
-
- stream.send(make_result_iq(stream, e.stanza))
-
- # Okay, so now the stream's playing but not sending, and we should be still
- # pending local send:
- streams = sm.ListStreams()
- assert len(streams) == 2, streams
- video_streams = [s for s in streams if s[2] == cs.MEDIA_STREAM_TYPE_VIDEO]
- assert len(video_streams) == 1, streams
- stream_id, h, _, state, direction, pending = video_streams[0]
- assert stream_id == video_stream_id, (stream_id, video_stream_id)
- assert h == remote_handle, (h, remote_handle)
- assert state == cs.MEDIA_STREAM_STATE_CONNECTED, state
- assert direction == cs.MEDIA_STREAM_DIRECTION_RECEIVE, direction
- assert pending == cs.MEDIA_STREAM_PENDING_LOCAL_SEND, pending
-
- # Let's accept the stream; the direction should change, and we should be
- # told to start sending.
- call_async(q, sm, 'RequestStreamDirection', video_stream_id,
- cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL)
-
- # The stream's direction should change, and we should be told to start
- # playing.
- q.expect_many(
- EventPattern('dbus-signal', signal='StreamDirectionChanged',
- args=[video_stream_id, cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL, 0]),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[True]),
- )
-
- # That'll do, pig. That'll do.
-
-if __name__ == '__main__':
- exec_test(test)
- exec_test(test_bare_jid)
diff --git a/tests/twisted/jingle/call-basics.py b/tests/twisted/jingle/call-basics.py
index a044f83bc..68d8182bb 100644
--- a/tests/twisted/jingle/call-basics.py
+++ b/tests/twisted/jingle/call-basics.py
@@ -4,10 +4,6 @@ Test basic outgoing and incoming call handling
import config
-if not config.CHANNEL_TYPE_CALL_ENABLED:
- print "NOTE: built with --disable-channel-type-call"
- raise SystemExit(77)
-
import dbus
from dbus.exceptions import DBusException
diff --git a/tests/twisted/jingle/call-codecoffer.py b/tests/twisted/jingle/call-codecoffer.py
index 0ccf94122..18ccaecc3 100644
--- a/tests/twisted/jingle/call-codecoffer.py
+++ b/tests/twisted/jingle/call-codecoffer.py
@@ -13,11 +13,7 @@ import constants as cs
from jingletest2 import JingleTest2, test_dialects, JingleProtocol031
-from config import CHANNEL_TYPE_CALL_ENABLED, VOIP_ENABLED
-
-if not CHANNEL_TYPE_CALL_ENABLED:
- print "NOTE: built with --disable-channel-type-call"
- raise SystemExit(77)
+from config import VOIP_ENABLED
if not VOIP_ENABLED:
print "NOTE: built with --disable-voip"
@@ -30,10 +26,10 @@ def check_offer (bus, conn, content):
assertNotEquals ("/", path)
offer = bus.get_object (conn.bus_name, path)
- md_property = offer.Get (cs.CALL_CONTENT_MEDIADESCRIPTION,
+ md_property = offer.Get (cs.CALL_CONTENT_MEDIA_DESCRIPTION,
"Codecs", dbus_interface=dbus.PROPERTIES_IFACE)
- assertEquals (md[cs.CALL_CONTENT_MEDIADESCRIPTION + ".Codecs"], md_property)
+ assertEquals (md[cs.CALL_CONTENT_MEDIA_DESCRIPTION + ".Codecs"], md_property)
def accept_offer (q, bus, conn, self_handle, remote_handle,
content, md_props, offer_path = None,
@@ -43,19 +39,19 @@ def accept_offer (q, bus, conn, self_handle, remote_handle,
offer = bus.get_object (conn.bus_name, path)
- offer.Accept (md_props, dbus_interface=cs.CALL_CONTENT_MEDIADESCRIPTION)
+ offer.Accept (md_props, dbus_interface=cs.CALL_CONTENT_MEDIA_DESCRIPTION)
current_mds = content.Get (cs.CALL_CONTENT_IFACE_MEDIA,
"RemoteMediaDescriptions", dbus_interface=dbus.PROPERTIES_IFACE)
- assertEquals (md_props[cs.CALL_CONTENT_MEDIADESCRIPTION + '.Codecs'],
- current_mds[remote_handle][cs.CALL_CONTENT_MEDIADESCRIPTION + '.Codecs'])
+ assertEquals (md_props[cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.Codecs'],
+ current_mds[remote_handle][cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.Codecs'])
if codecs_changed:
o = q.expect ('dbus-signal', signal='RemoteMediaDescriptionsChanged')
- assertEquals (md_props[cs.CALL_CONTENT_MEDIADESCRIPTION + '.Codecs'],
- o.args[0][remote_handle][cs.CALL_CONTENT_MEDIADESCRIPTION + '.Codecs'])
+ assertEquals (md_props[cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.Codecs'],
+ o.args[0][remote_handle][cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.Codecs'])
def reject_offer (q, bus, conn,
content, codecs, offer_path = None):
@@ -64,7 +60,7 @@ def reject_offer (q, bus, conn,
offer = bus.get_object (conn.bus_name, path)
- offer.Reject ((0, 0, "", ""), dbus_interface=cs.CALL_CONTENT_MEDIADESCRIPTION)
+ offer.Reject ((0, 0, "", ""), dbus_interface=cs.CALL_CONTENT_MEDIA_DESCRIPTION)
def update_codecs(jt2):
contents = jt2.generate_contents()
@@ -80,8 +76,8 @@ def prepare_test(jp, q, bus, conn, stream):
jt2.prepare()
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(1, ["foo@bar.com/Foo"])[0]
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
+ remote_handle = conn.get_contact_handle_sync("foo@bar.com/Foo")
# Advertise that we can do new style calls
conn.ContactCapabilities.UpdateCapabilities([
@@ -102,7 +98,7 @@ def prepare_test(jp, q, bus, conn, stream):
def try_to_access_old_offer(conn, path):
try:
offer = bus.get_object (conn.bus_name, path)
- ret = offer.GetAll (cs.CALL_CONTENT_MEDIADESCRIPTION,
+ ret = offer.GetAll (cs.CALL_CONTENT_MEDIA_DESCRIPTION,
dbus_interface=dbus.PROPERTIES_IFACE)
except Exception, e:
pass
@@ -186,7 +182,7 @@ def test_outgoing(jp, q, bus, conn, stream):
chan = bus.get_object(conn.bus_name, ret[0].args[0][0][0])
# there is no remote codec information, so this should be empty
- assertEquals(ret[1].args[1][cs.CALL_CONTENT_MEDIADESCRIPTION + ".Codecs"], [])
+ assertEquals(ret[1].args[1][cs.CALL_CONTENT_MEDIA_DESCRIPTION + ".Codecs"], [])
# get a list of audio codecs we can support
md = jt2.get_call_audio_md_dbus(remote_handle)
@@ -212,13 +208,13 @@ def test_outgoing(jp, q, bus, conn, stream):
# make an offer they can't refuse
offer = bus.get_object(conn.bus_name, ret[1].args[0])
- props = offer.GetAll(cs.CALL_CONTENT_MEDIADESCRIPTION,
+ props = offer.GetAll(cs.CALL_CONTENT_MEDIA_DESCRIPTION,
dbus_interface=dbus.PROPERTIES_IFACE)
# this also needs to be empty
assertEquals(props["Codecs"], [])
- offer.Accept(md, dbus_interface=cs.CALL_CONTENT_MEDIADESCRIPTION)
+ offer.Accept(md, dbus_interface=cs.CALL_CONTENT_MEDIA_DESCRIPTION)
o = q.expect('dbus-signal', signal='RemoteMediaDescriptionsChanged')
@@ -264,17 +260,17 @@ def test_outgoing(jp, q, bus, conn, stream):
ret = q.expect('dbus-signal', signal='NewMediaDescriptionOffer')
# make sure the codec offer has the updated codecs
- assertEquals(ret.args[1][cs.CALL_CONTENT_MEDIADESCRIPTION + ".Codecs"],
- md[cs.CALL_CONTENT_MEDIADESCRIPTION + ".Codecs"][:-1])
+ assertEquals(ret.args[1][cs.CALL_CONTENT_MEDIA_DESCRIPTION + ".Codecs"],
+ md[cs.CALL_CONTENT_MEDIA_DESCRIPTION + ".Codecs"][:-1])
# accept new offer
offer = bus.get_object(conn.bus_name, ret.args[0])
- md[cs.CALL_CONTENT_MEDIADESCRIPTION + ".Codecs"].pop()
- offer.Accept(md, dbus_interface=cs.CALL_CONTENT_MEDIADESCRIPTION)
+ md[cs.CALL_CONTENT_MEDIA_DESCRIPTION + ".Codecs"].pop()
+ offer.Accept(md, dbus_interface=cs.CALL_CONTENT_MEDIA_DESCRIPTION)
# now we should both have the smaller set of codecs, easy
o = q.expect ('dbus-signal', signal='RemoteMediaDescriptionsChanged')
- assertEquals (md[cs.CALL_CONTENT_MEDIADESCRIPTION + ".Codecs"], o.args[0][remote_handle][cs.CALL_CONTENT_MEDIADESCRIPTION + ".Codecs"])
+ assertEquals (md[cs.CALL_CONTENT_MEDIA_DESCRIPTION + ".Codecs"], o.args[0][remote_handle][cs.CALL_CONTENT_MEDIA_DESCRIPTION + ".Codecs"])
chan.Close(dbus_interface=cs.CHANNEL)
signal = q.expect('dbus-signal', signal='ChannelClosed')
diff --git a/tests/twisted/jingle/call-google-relay.py b/tests/twisted/jingle/call-google-relay.py
index 85168f5d9..c9acbb0ef 100644
--- a/tests/twisted/jingle/call-google-relay.py
+++ b/tests/twisted/jingle/call-google-relay.py
@@ -259,7 +259,7 @@ class CallGoogleRelayTest(CallTest):
except dbus.DBusException, e:
# This should fail because the object's gone away, not because
# Gabble's crashed.
- assert cs.UNKNOWN_METHOD == e.get_dbus_name(), \
+ assert cs.DBUS_ERROR_UNKNOWN_METHOD == e.get_dbus_name(), \
"maybe Gabble crashed? %s" % e
else:
# Gabble will probably also crash in a moment, because the http
diff --git a/tests/twisted/jingle/call-hold-av.py b/tests/twisted/jingle/call-hold-av.py
index 441a453cf..82f0b0987 100644
--- a/tests/twisted/jingle/call-hold-av.py
+++ b/tests/twisted/jingle/call-hold-av.py
@@ -62,7 +62,7 @@ class CallHoldAVTest(CallTest):
[path, _] = content.Get(cs.CALL_CONTENT_IFACE_MEDIA,
"MediaDescriptionOffer", dbus_interface=dbus.PROPERTIES_IFACE)
offer = bus.get_object (conn.bus_name, path)
- offer.Accept (md, dbus_interface=cs.CALL_CONTENT_MEDIADESCRIPTION)
+ offer.Accept (md, dbus_interface=cs.CALL_CONTENT_MEDIA_DESCRIPTION)
assertEquals(cs.CALL_STREAM_FLOW_STATE_STOPPED,
cstream.Get(cs.CALL_STREAM_IFACE_MEDIA, 'SendingState',
@@ -104,7 +104,7 @@ class CallHoldAVTest(CallTest):
[path, _] = content.Get(cs.CALL_CONTENT_IFACE_MEDIA,
"MediaDescriptionOffer", dbus_interface=dbus.PROPERTIES_IFACE)
offer = bus.get_object (conn.bus_name, path)
- offer.Accept (md, dbus_interface=cs.CALL_CONTENT_MEDIADESCRIPTION)
+ offer.Accept (md, dbus_interface=cs.CALL_CONTENT_MEDIA_DESCRIPTION)
assertEquals(cs.CALL_STREAM_FLOW_STATE_STOPPED,
cstream.Get(cs.CALL_STREAM_IFACE_MEDIA, 'SendingState',
diff --git a/tests/twisted/jingle/call-muc.py b/tests/twisted/jingle/call-muc.py
index 715a3e248..f82c07eee 100644
--- a/tests/twisted/jingle/call-muc.py
+++ b/tests/twisted/jingle/call-muc.py
@@ -35,7 +35,7 @@ def run_incoming_test(q, bus, conn, stream, bob_leaves_room = False):
jt.prepare()
forbidden = [ no_muji_presences (muc) ]
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
_, _, test_handle, bob_handle = \
join_muc_and_check(q, bus, conn, stream, muc)
@@ -173,7 +173,7 @@ def run_outgoing_test(q, bus, conn, stream, close_channel=False):
jt = JingleTest2(jp, conn, q, stream, 'test@localhost', muc + '/bob')
jt.prepare()
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
# Not allowed to have muji related presences before we accept the channel
forbidden = [ no_muji_presences (muc) ]
@@ -231,7 +231,7 @@ def run_outgoing_test(q, bus, conn, stream, close_channel=False):
e = q.expect('dbus-signal', signal = 'NewMediaDescriptionOffer')
offer = bus.get_object (conn.bus_name, e.args[0])
- offer.Accept(md, dbus_interface=cs.CALL_CONTENT_MEDIADESCRIPTION)
+ offer.Accept(md, dbus_interface=cs.CALL_CONTENT_MEDIA_DESCRIPTION)
jt.incoming_call(audio = "Audio")
diff --git a/tests/twisted/jingle/call-state.py b/tests/twisted/jingle/call-state.py
deleted file mode 100644
index b4d749b83..000000000
--- a/tests/twisted/jingle/call-state.py
+++ /dev/null
@@ -1,288 +0,0 @@
-"""
-Test exposing incoming <hold/>, <ringing/> and <active/> notifications via the
-CallState interface.
-"""
-
-from twisted.words.xish import xpath
-
-from gabbletest import make_result_iq
-from servicetest import (
- wrap_channel, make_channel_proxy, EventPattern, sync_dbus)
-import ns
-import constants as cs
-
-from jingletest2 import JingleTest2, test_all_dialects
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(jp, q, bus, conn, stream):
- remote_jid = 'foo@bar.com/Foo'
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', remote_jid)
-
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- handle = conn.RequestHandles(cs.HT_CONTACT, [remote_jid])[0]
-
- path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.HT_CONTACT,
- handle, True)
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia',
- ['MediaSignalling', 'Group', 'CallState'])
- chan_props = chan.Properties.GetAll(cs.CHANNEL)
- assert cs.CHANNEL_IFACE_CALL_STATE in chan_props['Interfaces'], \
- chan_props['Interfaces']
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: 0 } or \
- call_states == {}, call_states
-
- chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- audio_path = e.args[0]
- stream_handler = make_channel_proxy(conn, audio_path, 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler.Ready(jt.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('session-initiate'))
- stream.send(make_result_iq(stream, e.stanza))
-
- jt.parse_session_initiate(e.query)
-
- if jp.is_modern_jingle():
- # The other person's client starts ringing, and tells us so!
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.jid, 'session-info', [
- ('ringing', ns.JINGLE_RTP_INFO_1, {}, []) ]) ])
- stream.send(jp.xml(node))
-
- # If this is an old Jingle dialect, Gabble should treat the
- # session-initiate ack as ringing notification; if it's modern Jingle, we
- # just sent a ringing notification.
- q.expect('dbus-signal', signal='CallStateChanged',
- args=[handle, cs.CALL_STATE_RINGING])
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: cs.CALL_STATE_RINGING }, call_states
-
- if jp.is_modern_jingle():
- # We're waiting in a queue, so the other person's client tells us we're on
- # hold. Gabble should ack the IQ, and set the call state to Ringing | Held.
- # Also, Gabble certainly shouldn't tell s-e to start sending. (Although it
- # might tell it not to; we don't mind.)
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.jid, 'session-info', [
- ('hold', ns.JINGLE_RTP_INFO_1, {}, []) ]) ])
- stream.send(jp.xml(node))
-
- forbidden = [
- EventPattern('dbus-signal', signal='SetStreamSending', args=[True],
- path=audio_path),
- ]
- q.forbid_events(forbidden)
-
- q.expect_many(
- EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
- EventPattern('dbus-signal', signal='CallStateChanged',
- args=[handle, cs.CALL_STATE_RINGING | cs.CALL_STATE_HELD]),
- )
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: cs.CALL_STATE_RINGING | cs.CALL_STATE_HELD }, call_states
-
- # We're at the head of a queue, so the other person's client tells us we're
- # no longer on hold. The call centre phone's still ringing, though. s-e
- # still shouldn't start sending.
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.jid, 'session-info', [
- ('unhold', ns.JINGLE_RTP_INFO_1, {}, []) ]) ])
- stream.send(jp.xml(node))
-
- q.expect_many(
- EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
- EventPattern('dbus-signal', signal='CallStateChanged',
- args=[handle, cs.CALL_STATE_RINGING]),
- )
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: cs.CALL_STATE_RINGING }, call_states
-
- sync_dbus(bus, q, conn)
- q.unforbid_events(forbidden)
-
- jt.accept()
-
- if jp.is_modern_jingle():
- # The other person's client decides it's not ringing any more
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.jid, 'session-info', [
- ('active', ns.JINGLE_RTP_INFO_1, {}, []) ]) ])
- stream.send(jp.xml(node))
-
- # Gabble tells s-e to start sending, and removes the Ringing flag, either
- # because we got <active/> or because of the session-accept in ye olde
- # Jingle.
- q.expect_many(
- EventPattern('dbus-signal', signal='SetStreamSending', args=[True],
- path=audio_path),
- EventPattern('dbus-signal', signal='CallStateChanged',
- args=[ handle, 0 ]),
- )
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: 0 } or call_states == {}, call_states
-
- # The rest of the test concerns things we only support in the glorious
- # modern Jingle future.
- if not jp.is_modern_jingle():
- return
-
- # The other person puts us on hold. Gabble should ack the session-info IQ,
- # tell s-e to stop sending on the held stream, and set the call state.
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.jid, 'session-info', [
- ('hold', ns.JINGLE_RTP_INFO_1, {}, []) ]) ])
- stream.send(jp.xml(node))
-
- q.expect_many(
- EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[False],
- path=audio_path),
- EventPattern('dbus-signal', signal='CallStateChanged',
- args=[handle, cs.CALL_STATE_HELD]),
- )
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: cs.CALL_STATE_HELD }, call_states
-
- # The peer pings us with an empty session-info; Gabble should just ack it.
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.jid, 'session-info', [])])
- stream.send(jp.xml(node))
-
- q.expect('stream-iq', iq_type='result', iq_id=node[2]['id'])
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: cs.CALL_STATE_HELD }, call_states
-
- # The peer sends us some unknown-namespaced misc in a session-info; Gabble
- # should nak it with <unsupported-info/>
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.jid, 'session-info', [
- ('boiling', 'com.example.Kettle', {}, []) ]) ])
- stream.send(jp.xml(node))
-
- e = q.expect('stream-iq', iq_type='error', iq_id=node[2]['id'])
- xpath.queryForNodes("/jingle/error/unsupported-info", e.query)
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: cs.CALL_STATE_HELD }, call_states
-
- # The other person unholds us; Gabble should ack the session-info IQ, tell
- # s-e to start sending on the now-active stream, and set the call state.
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.jid, 'session-info', [
- ('active', ns.JINGLE_RTP_INFO_1, {}, []) ]) ])
- stream.send(jp.xml(node))
-
- q.expect_many(
- EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[True],
- path=audio_path),
- EventPattern('dbus-signal', signal='CallStateChanged',
- args=[handle, 0]),
- )
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: 0 } or call_states == {}, call_states
-
- # Okay, let's get a second stream involved!
-
- chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_VIDEO])
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- video_path = e.args[0]
- stream_handler2 = make_channel_proxy(conn, video_path, 'Media.StreamHandler')
-
- stream_handler2.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler2.Ready(jt.get_video_codecs_dbus())
- stream_handler2.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('content-add'))
- stream.send(make_result_iq(stream, e.stanza))
-
- jt.content_accept(e.query, 'video')
-
- q.expect('dbus-signal', signal='SetStreamSending', args=[True],
- path=video_path)
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: 0 } or call_states == {}, call_states
-
- # The other person puts us on hold. Gabble should ack the session-info IQ,
- # tell s-e to stop sending on both streams, and set the call state.
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.jid, 'session-info', [
- ('hold', ns.JINGLE_RTP_INFO_1, {}, []) ]) ])
- stream.send(jp.xml(node))
-
- q.expect_many(
- EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[False],
- path=audio_path),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[False],
- path=video_path),
- EventPattern('dbus-signal', signal='CallStateChanged',
- args=[handle, cs.CALL_STATE_HELD]),
- )
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: cs.CALL_STATE_HELD }, call_states
-
- # Now the other person sets the audio stream to mute. We can't represent
- # mute yet, but Gabble shouldn't take this to mean the call is active, as
- # one stream being muted doesn't change the fact that the call's on hold.
- # FIXME: hardcoded stream id
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.jid, 'session-info', [
- ('mute', ns.JINGLE_RTP_INFO_1,
- {'name': 'Audio', 'creator': 'initiator'}, []) ]) ])
- stream.send(jp.xml(node))
-
- forbidden = [
- EventPattern('dbus-signal', signal='SetStreamSending', args=[True],
- path=audio_path),
- EventPattern('dbus-signal', signal='CallStateChanged',
- args=[ handle, 0 ]),
- ]
- q.forbid_events(forbidden)
-
- q.expect('stream-iq', iq_type='result', iq_id=node[2]['id'])
-
- call_states = chan.CallState.GetCallStates()
- assert call_states == { handle: cs.CALL_STATE_HELD }, call_states
-
- sync_dbus(bus, q, conn)
- q.unforbid_events(forbidden)
-
- # That'll do, pig.
-
- chan.Group.RemoveMembers([self_handle], 'closed')
- e = q.expect('dbus-signal', signal='Close') #XXX - match against the path
-
-if __name__ == '__main__':
- test_all_dialects(test)
diff --git a/tests/twisted/jingle/call_helper.py b/tests/twisted/jingle/call_helper.py
index 402f1c931..781750a13 100644
--- a/tests/twisted/jingle/call_helper.py
+++ b/tests/twisted/jingle/call_helper.py
@@ -4,10 +4,6 @@ Base classes for Call tests
import config
-if not config.CHANNEL_TYPE_CALL_ENABLED:
- print "NOTE: built with --disable-channel-type-call"
- raise SystemExit(77)
-
import dbus
from dbus.exceptions import DBusException
@@ -60,9 +56,8 @@ class CallTest(object):
self.PEER_JID)
self.can_change_direction = (jp.dialect not in ['gtalk-v0.3',
'gtalk-v0.4'])
- self.self_handle = conn.GetSelfHandle()
- self.peer_handle = conn.RequestHandles(1, ["foo@bar.com/Foo"])[0]
-
+ self.self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
+ self.peer_handle = conn.get_contact_handle_sync(self.PEER_JID)
def check_channel_state(self, state, wait = False):
"""Optionnally wait for channel state to be reached and check that the
@@ -112,13 +107,13 @@ class CallTest(object):
assertNotEquals("/", path)
offer = self.bus.get_object(self.conn.bus_name, path)
- codecmap_property = offer.Get(cs.CALL_CONTENT_MEDIADESCRIPTION,
+ codecmap_property = offer.Get(cs.CALL_CONTENT_MEDIA_DESCRIPTION,
"Codecs", dbus_interface=dbus.PROPERTIES_IFACE)
- assertEquals(remote_md[cs.CALL_CONTENT_MEDIADESCRIPTION + '.Codecs'],
+ assertEquals(remote_md[cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.Codecs'],
codecmap_property)
- offer.Accept(md, dbus_interface=cs.CALL_CONTENT_MEDIADESCRIPTION)
+ offer.Accept(md, dbus_interface=cs.CALL_CONTENT_MEDIA_DESCRIPTION)
current_md = content.Get(cs.CALL_CONTENT_IFACE_MEDIA,
"LocalMediaDescriptions", dbus_interface=dbus.PROPERTIES_IFACE)
@@ -135,7 +130,7 @@ class CallTest(object):
incoming = self.incoming
content = wrap_content(self.bus.get_object(self.conn.bus_name,
- content_path), ['DTMF', 'Media'])
+ content_path))
content_props = content.GetAll(cs.CALL_CONTENT,
dbus_interface=dbus.PROPERTIES_IFACE)
@@ -321,8 +316,7 @@ class CallTest(object):
chan_path = signal.args[0][0][0]
self.chan = wrap_channel(
- self.bus.get_object(self.conn.bus_name, chan_path),
- 'Call', ['Hold'])
+ self.bus.get_object(self.conn.bus_name, chan_path), 'Call')
properties = self.chan.GetAll(cs.CHANNEL_TYPE_CALL,
dbus_interface=dbus.PROPERTIES_IFACE)
@@ -460,8 +454,9 @@ class CallTest(object):
ret = self.q.expect_many(*expected)
# Check the first LocalCandidatesAdded signal (third in the array)
assertEquals(candidates, ret[2].args[0])
-
if not self.incoming:
+ self.check_session_initiate_iq(ret[-1])
+
if expect_after_si is not None:
sync_stream(self.q, self.stream)
self.q.unforbid_events(expect_after_si)
@@ -607,6 +602,10 @@ class CallTest(object):
self.check_channel_state(cs.CALL_STATE_INITIALISED)
+ def check_session_initiate_iq(self, e):
+ """e is the session-initiate stream-iq event."""
+ pass
+
def connect(self, expect_after_si=None):
"""Negotiate all the codecs, bringing the channel to INITIALISED
state"""
diff --git a/tests/twisted/jingle/callutils.py b/tests/twisted/jingle/callutils.py
index 8688c9b71..b4db0b0f7 100644
--- a/tests/twisted/jingle/callutils.py
+++ b/tests/twisted/jingle/callutils.py
@@ -37,7 +37,7 @@ def check_and_accept_offer (q, bus, conn, content, md, in_remote_handle = 0,
[path, remote_md] = content.Get(cs.CALL_CONTENT_IFACE_MEDIA,
"MediaDescriptionOffer", dbus_interface=dbus.PROPERTIES_IFACE)
- remote_handle = remote_md[cs.CALL_CONTENT_MEDIADESCRIPTION + '.RemoteContact']
+ remote_handle = remote_md[cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.RemoteContact']
if in_remote_handle != 0:
assertEquals(remote_handle, in_remote_handle)
@@ -48,12 +48,12 @@ def check_and_accept_offer (q, bus, conn, content, md, in_remote_handle = 0,
assertNotEquals ("/", path)
offer = bus.get_object (conn.bus_name, path)
- codecmap_property = offer.Get (cs.CALL_CONTENT_MEDIADESCRIPTION,
+ codecmap_property = offer.Get (cs.CALL_CONTENT_MEDIA_DESCRIPTION,
"Codecs", dbus_interface=dbus.PROPERTIES_IFACE)
- assertEquals (remote_md[cs.CALL_CONTENT_MEDIADESCRIPTION + '.Codecs'], codecmap_property)
+ assertEquals (remote_md[cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.Codecs'], codecmap_property)
- offer.Accept (md, dbus_interface=cs.CALL_CONTENT_MEDIADESCRIPTION)
+ offer.Accept (md, dbus_interface=cs.CALL_CONTENT_MEDIA_DESCRIPTION)
current_md = content.Get(cs.CALL_CONTENT_IFACE_MEDIA,
"LocalMediaDescriptions", dbus_interface=dbus.PROPERTIES_IFACE)
diff --git a/tests/twisted/jingle/decloak-peer.py b/tests/twisted/jingle/decloak-peer.py
index fa8f1ee50..237472b66 100644
--- a/tests/twisted/jingle/decloak-peer.py
+++ b/tests/twisted/jingle/decloak-peer.py
@@ -36,16 +36,13 @@ def run_test(q, bus, conn, stream, jt, decloak_allowed):
presence at all.
"""
- request = dbus.Dictionary({ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_ID: jt.peer,
- }, signature='sv')
- path, props = conn.CreateChannel(request, dbus_interface=cs.CONN_IFACE_REQUESTS)
- media_iface = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')
- handle = props[cs.TARGET_HANDLE]
-
- call_async(q, media_iface, 'RequestStreams', handle,
- [cs.MEDIA_STREAM_TYPE_AUDIO])
+ call_async(q, conn.Requests, 'CreateChannel',
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CALL,
+ cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
+ cs.TARGET_ID: jt.peer,
+ cs.CALL_INITIAL_AUDIO: True,
+ cs.CALL_INITIAL_VIDEO: False,
+ })
e = q.expect('stream-presence',
to=jt.peer_bare_jid, presence_type=None)
@@ -57,10 +54,13 @@ def run_test(q, bus, conn, stream, jt, decloak_allowed):
jt.send_presence_and_caps()
# RequestStreams should now happily complete
- q.expect('dbus-return', method='RequestStreams')
+ q.expect('dbus-return', method='CreateChannel')
else:
- q.expect('dbus-error', method='RequestStreams',
+ q.expect('dbus-error', method='CreateChannel',
name=cs.OFFLINE)
if __name__ == '__main__':
+ print "FIXME: needs to be ported to Call1"
+ raise SystemExit(77)
+
exec_test(test, timeout=10)
diff --git a/tests/twisted/jingle/dtmf-no-audio.py b/tests/twisted/jingle/dtmf-no-audio.py
deleted file mode 100644
index fd5f568cf..000000000
--- a/tests/twisted/jingle/dtmf-no-audio.py
+++ /dev/null
@@ -1,81 +0,0 @@
-"""
-Test inability to send DTMF events on a video-only call.
-"""
-
-from twisted.words.xish import xpath
-
-from gabbletest import make_result_iq
-from servicetest import (call_async,
- wrap_channel, make_channel_proxy, EventPattern, sync_dbus)
-import constants as cs
-
-from jingletest2 import JingleTest2, test_all_dialects
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(jp, q, bus, conn, stream):
- if not jp.can_do_video_only():
- return
-
- remote_jid = 'foo@bar.com/Foo'
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', remote_jid)
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- handle = conn.RequestHandles(cs.HT_CONTACT, [remote_jid])[0]
-
- chan_path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.HT_CONTACT, handle, True)
- chan = wrap_channel(bus.get_object(conn.bus_name, chan_path),
- 'StreamedMedia', ['MediaSignalling', 'Group', 'CallState', 'DTMF'])
- chan_props = chan.Properties.GetAll(cs.CHANNEL)
- assert cs.CHANNEL_IFACE_DTMF in chan_props['Interfaces'], \
- chan_props['Interfaces']
-
- chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_VIDEO])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- video_path = e.args[0]
- stream_handler = make_channel_proxy(conn, video_path, 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler.Ready(jt.get_video_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('session-initiate'))
- stream.send(make_result_iq(stream, e.stanza))
-
- jt.parse_session_initiate(e.query)
-
- jt.accept()
-
- # Gabble tells s-e to start sending
- q.expect('dbus-signal', signal='SetStreamSending', args=[True],
- path=video_path)
-
- # We don't actually have an audio stream, so this is a non-starter.
- call_async(q, chan.DTMF, 'StartTone', 666, 3)
- q.expect('dbus-error', method='StartTone', name=cs.NOT_AVAILABLE)
- call_async(q, chan.DTMF, 'MultipleTones', '**666##')
- q.expect('dbus-error', method='MultipleTones', name=cs.NOT_AVAILABLE)
-
- # We can still stop all the tones that are playing (a no-op).
- call_async(q, chan.DTMF, 'StopTone', 666)
- q.expect('dbus-return', method='StopTone')
-
- chan.Group.RemoveMembers([self_handle], 'closed')
- e = q.expect('dbus-signal', signal='Closed', path=chan_path)
-
-if __name__ == '__main__':
- test_all_dialects(test)
diff --git a/tests/twisted/jingle/dtmf.py b/tests/twisted/jingle/dtmf.py
deleted file mode 100644
index 4116e9d10..000000000
--- a/tests/twisted/jingle/dtmf.py
+++ /dev/null
@@ -1,186 +0,0 @@
-"""
-Test DTMF events.
-"""
-
-from twisted.words.xish import xpath
-
-from gabbletest import make_result_iq
-from servicetest import (call_async,
- wrap_channel, make_channel_proxy, EventPattern, sync_dbus, assertEquals)
-import constants as cs
-
-from jingletest2 import JingleTest2, test_all_dialects
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(jp, q, bus, conn, stream):
- # this test uses multiple streams
- if not jp.is_modern_jingle():
- return
-
- remote_jid = 'foo@bar.com/Foo'
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', remote_jid)
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- handle = conn.RequestHandles(cs.HT_CONTACT, [remote_jid])[0]
-
- chan_path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.HT_CONTACT, handle, True)
- chan = wrap_channel(bus.get_object(conn.bus_name, chan_path),
- 'StreamedMedia', ['MediaSignalling', 'Group', 'CallState', 'DTMF'])
- chan_props = chan.Properties.GetAll(cs.CHANNEL)
- assert cs.CHANNEL_IFACE_DTMF in chan_props['Interfaces'], \
- chan_props['Interfaces']
-
- assertEquals('',
- chan.Properties.Get(cs.CHANNEL_IFACE_DTMF, 'InitialTones'))
- assertEquals('',
- chan.Properties.Get(cs.CHANNEL_IFACE_DTMF, 'DeferredTones'))
-
- chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- audio_path = e.args[0]
- stream_handler = make_channel_proxy(conn, audio_path, 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler.Ready(jt.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('session-initiate'))
- stream.send(make_result_iq(stream, e.stanza))
-
- jt.parse_session_initiate(e.query)
-
- jt.accept()
-
- # Gabble tells s-e to start sending
- q.expect('dbus-signal', signal='SetStreamSending', args=[True],
- path=audio_path)
-
- chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- audio2_path = e.args[0]
-
- # The Stream_ID is specified to be ignored; we use 666 here.
- call_async(q, chan.DTMF, 'StartTone', 666, 3)
- q.expect_many(
- EventPattern('dbus-signal', signal='StartTelephonyEvent',
- path=audio2_path),
- EventPattern('dbus-signal', signal='StartTelephonyEvent',
- path=audio_path),
- EventPattern('dbus-signal', signal='SendingTones', args=['3'],
- path=chan_path),
- EventPattern('dbus-return', method='StartTone'),
- )
-
- call_async(q, chan.DTMF, 'StopTone', 666)
- q.expect_many(
- EventPattern('dbus-signal', signal='StopTelephonyEvent',
- path=audio_path),
- EventPattern('dbus-signal', signal='StopTelephonyEvent',
- path=audio2_path),
- EventPattern('dbus-signal', signal='StoppedTones', args=[True],
- path=chan_path),
- EventPattern('dbus-return', method='StopTone'),
- )
-
- call_async(q, chan.DTMF, 'MultipleTones', '123w*#')
- q.expect_many(
- EventPattern('dbus-signal', signal='StartTelephonyEvent',
- path=audio_path, args=[1]),
- EventPattern('dbus-signal', signal='StartTelephonyEvent',
- path=audio2_path, args=[1]),
- EventPattern('dbus-signal', signal='SendingTones', args=['123w*#'],
- path=chan_path),
- EventPattern('dbus-return', method='MultipleTones'),
- )
- q.expect_many(
- EventPattern('dbus-signal', signal='StopTelephonyEvent',
- path=audio_path),
- EventPattern('dbus-signal', signal='StopTelephonyEvent',
- path=audio2_path),
- )
- q.expect_many(
- EventPattern('dbus-signal', signal='StartTelephonyEvent',
- path=audio_path, args=[2]),
- EventPattern('dbus-signal', signal='StartTelephonyEvent',
- path=audio2_path, args=[2]),
- )
- q.expect_many(
- EventPattern('dbus-signal', signal='StopTelephonyEvent',
- path=audio_path),
- EventPattern('dbus-signal', signal='StopTelephonyEvent',
- path=audio2_path),
- )
- q.expect_many(
- EventPattern('dbus-signal', signal='StartTelephonyEvent',
- path=audio_path, args=[3]),
- EventPattern('dbus-signal', signal='StartTelephonyEvent',
- path=audio2_path, args=[3]),
- )
- q.expect_many(
- EventPattern('dbus-signal', signal='StopTelephonyEvent',
- path=audio_path),
- EventPattern('dbus-signal', signal='StopTelephonyEvent',
- path=audio2_path),
- EventPattern('dbus-signal', signal='StoppedTones', args=[False],
- path=chan_path),
- EventPattern('dbus-signal', signal='TonesDeferred',
- args=['*#']),
- )
-
- assertEquals('*#',
- chan.Properties.Get(cs.CHANNEL_IFACE_DTMF, 'DeferredTones'))
-
- forbidden = [EventPattern('dbus-signal', signal='StartTelephonyEvent',
- args=[9])]
- q.forbid_events(forbidden)
-
- # This is technically a race condition, but this dialstring is almost
- # certainly long enough that the Python script will win the race, i.e.
- # cancel before Gabble processes the whole dialstring.
- call_async(q, chan.DTMF, 'MultipleTones',
- '1,1' * 100)
- q.expect('dbus-return', method='MultipleTones')
-
- call_async(q, chan.DTMF, 'MultipleTones', '9')
- q.expect('dbus-error', method='MultipleTones',
- name=cs.SERVICE_BUSY)
- call_async(q, chan.DTMF, 'StartTone', 666, 9)
- q.expect('dbus-error', method='StartTone', name=cs.SERVICE_BUSY)
- call_async(q, chan.DTMF, 'StopTone', 666)
- q.expect_many(
- EventPattern('dbus-signal', signal='StopTelephonyEvent',
- path=audio_path),
- EventPattern('dbus-signal', signal='StopTelephonyEvent',
- path=audio2_path),
- EventPattern('dbus-signal', signal='StoppedTones', args=[True],
- path=chan_path),
- EventPattern('dbus-return', method='StopTone'),
- )
-
- # emitting any sound resets TonesDeferred
- assertEquals('',
- chan.Properties.Get(cs.CHANNEL_IFACE_DTMF, 'DeferredTones'))
-
- q.unforbid_events(forbidden)
-
- chan.Group.RemoveMembers([self_handle], 'closed')
- e = q.expect('dbus-signal', signal='Closed', path=chan_path)
-
-if __name__ == '__main__':
- test_all_dialects(test)
diff --git a/tests/twisted/jingle/google-relay.py b/tests/twisted/jingle/google-relay.py
deleted file mode 100644
index 18940fa16..000000000
--- a/tests/twisted/jingle/google-relay.py
+++ /dev/null
@@ -1,424 +0,0 @@
-"""
-Test getting relay from Google jingleinfo
-"""
-
-import config
-
-if not config.GOOGLE_RELAY_ENABLED:
- print "NOTE: built with --disable-google-relay"
- raise SystemExit(77)
-
-from functools import partial
-
-from gabbletest import exec_test, make_result_iq, sync_stream, \
- GoogleXmlStream, disconnect_conn
-from servicetest import make_channel_proxy, \
- EventPattern, call_async, sync_dbus, assertEquals, assertLength
-import jingletest2
-import gabbletest
-import constants as cs
-import dbus
-import ns
-import config
-from twisted.words.protocols.jabber.client import IQ
-
-from twisted.web import http
-
-from httptest import listen_http
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-# A real request/response looks like this:
-#
-# GET /create_session HTTP/1.1
-# Connection: Keep-Alive
-# Content-Length: 0
-# Host: relay.l.google.com
-# User-Agent: farsight-libjingle
-# X-Google-Relay-Auth: censored
-# X-Talk-Google-Relay-Auth: censored
-#
-# HTTP/1.1 200 OK
-# Content-Type: text/plain
-# Date: Tue, 03 Mar 2009 18:33:28 GMT
-# Server: MediaProxy
-# Cache-Control: private, x-gzip-ok=""
-# Transfer-Encoding: chunked
-#
-# c3
-# relay.ip=74.125.47.126
-# relay.udp_port=19295
-# relay.tcp_port=19294
-# relay.ssltcp_port=443
-# stun.ip=74.125.47.126
-# stun.port=19302
-# username=censored
-# password=censored
-# magic_cookie=censored
-#
-# 0
-response_template = """c3
-relay.ip=127.0.0.1
-relay.udp_port=11111
-relay.tcp_port=22222
-relay.ssltcp_port=443
-stun.ip=1.2.3.4
-stun.port=12345
-username=UUUUUUUU%d
-password=PPPPPPPP%d
-magic_cookie=MMMMMMMM
-"""
-
-def handle_request(req, n):
- req.setResponseCode(http.OK)
- req.setHeader("Content-Type", "text/plain")
- req.write(response_template % (n, n))
- req.finish()
-
-TOO_SLOW_CLOSE = 1
-TOO_SLOW_REMOVE_SELF = 2
-TOO_SLOW_DISCONNECT = 3
-TOO_SLOW_DISCONNECT_IMMEDIATELY = 4
-
-def test(q, bus, conn, stream, incoming=True, too_slow=None, use_call=False):
- jp = jingletest2.JingleProtocol031()
- jt = jingletest2.JingleTest2(jp, conn, q, stream, 'test@localhost',
- 'foo@bar.com/Foo')
-
- if use_call:
- # wjt only updated just about enough of this test for Call to check for
- # one specific crash, not to verify that it all works...
- assert incoming
- assert too_slow in [TOO_SLOW_CLOSE, TOO_SLOW_DISCONNECT]
-
- # Tell Gabble we want to use Call.
- conn.ContactCapabilities.UpdateCapabilities([
- (cs.CLIENT + ".CallHandler", [
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CALL,
- cs.CALL_INITIAL_AUDIO: True},
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CALL,
- cs.CALL_INITIAL_VIDEO: True},
- ], [
- cs.CHANNEL_TYPE_CALL + '/gtalk-p2p',
- cs.CHANNEL_TYPE_CALL + '/ice-udp',
- cs.CHANNEL_TYPE_CALL + '/video/h264',
- ]),
- ])
-
- # See: http://code.google.com/apis/talk/jep_extensions/jingleinfo.html
- ji_event = q.expect('stream-iq', query_ns=ns.GOOGLE_JINGLE_INFO,
- to='test@localhost')
-
- # Regression test for a bug where Gabble would crash if it disconnected
- # before receiving a reply to the google:jingleinfo query.
- if too_slow == TOO_SLOW_DISCONNECT_IMMEDIATELY:
- disconnect_conn(q, conn, stream, [])
- return
-
- listen_port = listen_http(q, 0)
-
- jingleinfo = make_result_iq(stream, ji_event.stanza)
- stun = jingleinfo.firstChildElement().addElement('stun')
- server = stun.addElement('server')
- server['host'] = 'resolves-to-1.2.3.4'
- server['udp'] = '12345'
-
- expected_stun_server = '1.2.3.4'
- expected_stun_port = 12345
-
- # This bit is undocumented... but it has the same format as what we get
- # from Google Talk servers:
- # <iq to="censored" from="censored" id="73930208084" type="result">
- # <query xmlns="google:jingleinfo">
- # <stun>
- # <server host="stun.l.google.com" udp="19302"/>
- # <server host="stun4.l.google.com" udp="19302"/>
- # <server host="stun3.l.google.com" udp="19302"/>
- # <server host="stun1.l.google.com" udp="19302"/>
- # <server host="stun2.l.google.com" udp="19302"/>
- # </stun>
- # <relay>
- # <token>censored</token>
- # <server host="relay.google.com" udp="19295" tcp="19294"
- # tcpssl="443"/>
- # </relay>
- # </query>
- # </iq>
- relay = jingleinfo.firstChildElement().addElement('relay')
- relay.addElement('token', content='jingle all the way')
- server = relay.addElement('server')
- server['host'] = '127.0.0.1'
- server['udp'] = '11111'
- server['tcp'] = '22222'
- server['tcpssl'] = '443'
- # The special regression-test build of Gabble parses this attribute,
- # because we can't listen on port 80
- server['gabble-test-http-port'] = str(listen_port.getHost().port)
- stream.send(jingleinfo)
- jingleinfo = None
-
- # Spoof some jingle info. This is a regression test for
- # <https://bugs.freedesktop.org/show_bug.cgi?id=34048>. We assert that
- # Gabble has ignored this stuff later.
- iq = IQ(stream, 'set')
- iq['from'] = "evil@evil.net"
- query = iq.addElement((ns.GOOGLE_JINGLE_INFO, "query"))
-
- stun = query.addElement('stun')
- server = stun.addElement('server')
- server['host'] = '6.6.6.6'
- server['udp'] = '6666'
-
- relay = query.addElement('relay')
- relay.addElement('token', content='mwohahahahaha')
- server = relay.addElement('server')
- server['host'] = '127.0.0.1'
- server['udp'] = '666'
- server['tcp'] = '999'
- server['tcpssl'] = '666'
-
- stream.send(iq)
-
- jt.send_presence_and_caps()
-
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, ["foo@bar.com/Foo"])[0]
- self_handle = conn.GetSelfHandle()
- req_pattern = EventPattern('http-request', method='GET', path='/create_session')
-
- if incoming:
- # Remote end calls us
- jt.incoming_call()
-
- if use_call:
- def looks_like_a_call_to_me(event):
- channels, = event.args
- path, props = channels[0]
- return props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_CALL
- new_channels = q.expect('dbus-signal', signal='NewChannels',
- predicate=looks_like_a_call_to_me)
-
- path = new_channels.args[0][0][0]
- media_chan = bus.get_object(conn.bus_name, path)
- else:
- # FIXME: these signals are not observable by real clients, since they
- # happen before NewChannels.
- # The caller is in members
- # We're pending because of remote_handle
- mc, _, e = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [remote_handle], [], [], [], 0, 0]),
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [], [], [self_handle], [], remote_handle,
- cs.GC_REASON_INVITED]),
- EventPattern('dbus-signal', signal='NewSessionHandler'))
-
- media_chan = make_channel_proxy(conn, mc.path,
- 'Channel.Interface.Group')
- media_iface = make_channel_proxy(conn, mc.path,
- 'Channel.Type.StreamedMedia')
- else:
- call_async(q, conn.Requests, 'CreateChannel',
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_HANDLE: remote_handle,
- })
- ret, old_sig, new_sig = q.expect_many(
- EventPattern('dbus-return', method='CreateChannel'),
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e:
- cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewChannels',
- predicate=lambda e:
- cs.CHANNEL_TYPE_CONTACT_LIST not in
- e.args[0][0][1].values()),
- )
- path = ret.value[0]
- media_chan = make_channel_proxy(conn, path, 'Channel.Interface.Group')
- media_iface = make_channel_proxy(conn, path,
- 'Channel.Type.StreamedMedia')
- call_async(q, media_iface, 'RequestStreams',
- remote_handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
- e = q.expect('dbus-signal', signal='NewSessionHandler')
-
- req1 = q.expect('http-request', method='GET', path='/create_session')
- req2 = q.expect('http-request', method='GET', path='/create_session')
-
- if too_slow is not None:
- test_too_slow(q, bus, conn, stream, req1, req2, media_chan, too_slow)
- return
-
- if incoming:
- assertLength(0, media_iface.ListStreams())
- # Accept the call.
- media_chan.AddMembers([self_handle], '')
-
- # In response to the streams call, we now have two HTTP requests
- # (for RTP and RTCP)
- handle_request(req1.request, 0)
- handle_request(req2.request, 1)
-
- if incoming:
- # We accepted the call, and it should get a new, bidirectional stream
- # now that the relay info request has finished. This tests against a
- # regression of bug #24023.
- q.expect('dbus-signal', signal='StreamAdded',
- args=[1, remote_handle, cs.MEDIA_STREAM_TYPE_AUDIO])
- q.expect('dbus-signal', signal='StreamDirectionChanged',
- args=[1, cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL, 0])
- else:
- # Now that we have the relay info, RequestStreams can return
- q.expect('dbus-return', method='RequestStreams')
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- # Exercise channel properties
- channel_props = media_chan.GetAll(
- cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE)
- assert channel_props['TargetHandle'] == remote_handle
- assert channel_props['TargetHandleType'] == cs.HT_CONTACT
- assert channel_props['TargetID'] == 'foo@bar.com'
- assert channel_props['Requested'] == (not incoming)
-
- # The new API for STUN servers etc.
- sh_props = stream_handler.GetAll(
- cs.STREAM_HANDLER, dbus_interface=dbus.PROPERTIES_IFACE)
-
- assert sh_props['NATTraversal'] == 'gtalk-p2p'
- assert sh_props['CreatedLocally'] == (not incoming)
-
- # If Gabble has erroneously paid attention to the contact evil@evil.net who
- # sent us a google:jingleinfo stanza, this assertion will fail.
- assertEquals([(expected_stun_server, expected_stun_port)],
- sh_props['STUNServers'])
-
- credentials_used = {}
- credentials = {}
-
- for relay in sh_props['RelayInfo']:
- assert relay['ip'] == '127.0.0.1', sh_props['RelayInfo']
- assert relay['type'] in ('udp', 'tcp', 'tls')
- assert relay['component'] in (1, 2)
-
- if relay['type'] == 'udp':
- assert relay['port'] == 11111, sh_props['RelayInfo']
- elif relay['type'] == 'tcp':
- assert relay['port'] == 22222, sh_props['RelayInfo']
- elif relay['type'] == 'tls':
- assert relay['port'] == 443, sh_props['RelayInfo']
-
- assert relay['username'][:8] == 'UUUUUUUU', sh_props['RelayInfo']
- assert relay['password'][:8] == 'PPPPPPPP', sh_props['RelayInfo']
- assert relay['password'][8:] == relay['username'][8:], \
- sh_props['RelayInfo']
- assert (relay['password'][8:], relay['type']) not in credentials_used
- credentials_used[(relay['password'][8:], relay['type'])] = 1
- credentials[(relay['component'], relay['type'])] = relay['password'][8:]
-
- assert (1, 'udp') in credentials
- assert (1, 'tcp') in credentials
- assert (1, 'tls') in credentials
- assert (2, 'udp') in credentials
- assert (2, 'tcp') in credentials
- assert (2, 'tls') in credentials
-
- assert ('0', 'udp') in credentials_used
- assert ('0', 'tcp') in credentials_used
- assert ('0', 'tls') in credentials_used
- assert ('1', 'udp') in credentials_used
- assert ('1', 'tcp') in credentials_used
- assert ('1', 'tls') in credentials_used
-
- # consistency check, since we currently reimplement Get separately
- for k in sh_props:
- assert sh_props[k] == stream_handler.Get(
- 'org.freedesktop.Telepathy.Media.StreamHandler', k,
- dbus_interface=dbus.PROPERTIES_IFACE), k
-
- media_chan.RemoveMembers([self_handle], '')
-
- if incoming:
- q.expect_many(
- EventPattern('stream-iq',
- predicate=lambda e: e.query is not None and
- e.query.name == 'jingle' and
- e.query['action'] == 'session-terminate'),
- EventPattern('dbus-signal', signal='Closed'),
- )
- else:
- # We haven't sent a session-initiate, so we shouldn't expect to send a
- # session-terminate.
- q.expect('dbus-signal', signal='Closed')
-
- # Tests completed, close the connection
-
-def test_too_slow(q, bus, conn, stream, req1, req2, media_chan, too_slow):
- """
- Regression test for a bug where if the channel was closed before the HTTP
- responses arrived, the responses finally arriving crashed Gabble.
- """
-
- # User gets bored, and ends the call.
- e = EventPattern('dbus-signal', signal='Closed',
- path=media_chan.object_path)
-
- if too_slow == TOO_SLOW_CLOSE:
- call_async(q, media_chan, 'Close', dbus_interface=cs.CHANNEL)
- elif too_slow == TOO_SLOW_REMOVE_SELF:
- media_chan.RemoveMembers([conn.GetSelfHandle()], "",
- dbus_interface=cs.CHANNEL_IFACE_GROUP)
- elif too_slow == TOO_SLOW_DISCONNECT:
- disconnect_conn(q, conn, stream, [e])
-
- try:
- media_chan.GetMembers()
- except dbus.DBusException, e:
- # This should fail because the object's gone away, not because
- # Gabble's crashed.
- assert cs.UNKNOWN_METHOD == e.get_dbus_name(), \
- "maybe Gabble crashed? %s" % e
- else:
- # Gabble will probably also crash in a moment, because the http
- # request callbacks will be called after the channel's meant to
- # have died, which will cause the channel to try to call methods on
- # the (finalized) connection.
- assert False, "the channel should be dead by now"
-
- return
-
- q.expect_many(e)
-
- # Now Google answers!
- handle_request(req1.request, 2)
- handle_request(req2.request, 3)
-
- # Make a misc method call to check that Gabble's still alive.
- sync_dbus(bus, q, conn)
-
-def exec_relay_test(incoming, too_slow=None, use_call=False):
- exec_test(
- partial(test, incoming=incoming, too_slow=too_slow, use_call=use_call),
- protocol=GoogleXmlStream)
-
-if __name__ == '__main__':
- exec_relay_test(True)
- exec_relay_test(False)
- exec_relay_test(True, TOO_SLOW_CLOSE)
- exec_relay_test(False, TOO_SLOW_CLOSE)
- exec_relay_test(True, TOO_SLOW_REMOVE_SELF)
- exec_relay_test(False, TOO_SLOW_REMOVE_SELF)
- exec_relay_test(True, TOO_SLOW_DISCONNECT)
- exec_relay_test(False, TOO_SLOW_DISCONNECT)
- exec_relay_test(True, TOO_SLOW_DISCONNECT_IMMEDIATELY)
-
- if config.CHANNEL_TYPE_CALL_ENABLED:
- exec_relay_test(True, TOO_SLOW_CLOSE, use_call=True)
- exec_relay_test(True, TOO_SLOW_DISCONNECT, use_call=True)
-
diff --git a/tests/twisted/jingle/hold-audio.py b/tests/twisted/jingle/hold-audio.py
deleted file mode 100644
index d7656889a..000000000
--- a/tests/twisted/jingle/hold-audio.py
+++ /dev/null
@@ -1,425 +0,0 @@
-"""
-Test the Hold API.
-"""
-
-from gabbletest import make_result_iq, sync_stream
-from servicetest import (
- assertEquals, sync_dbus,
- make_channel_proxy, call_async, EventPattern, wrap_channel,
- )
-import constants as cs
-
-from jingletest2 import JingleTest2, test_all_dialects
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(jp, q, bus, conn, stream):
- remote_jid = 'foo@bar.com/Foo'
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', remote_jid)
-
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- handle = conn.RequestHandles(cs.HT_CONTACT, [remote_jid])[0]
- path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.HT_CONTACT,
- handle, True)
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia',
- ['Hold'])
-
- # These are 0- (for old dialects) or 1- (for new dialects) element lists
- # that can be splatted into expect_many with *
- hold_event = jp.rtp_info_event_list("hold")
- unhold_event = jp.rtp_info_event_list("unhold")
-
- # Before we have any streams, GetHoldState returns Unheld and unhold is a
- # no-op.
- assertEquals((cs.HS_UNHELD, cs.HSR_NONE), chan.Hold.GetHoldState())
- chan.Hold.RequestHold(False)
-
- # Before we have any streams, RequestHold(True) should work; because there
- # are no streams, it should take effect at once. It certainly shouldn't
- # send anything to the peer.
- q.forbid_events(hold_event)
- q.forbid_events(unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED])
- q.expect('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_REQUESTED])
- assertEquals((cs.HS_HELD, cs.HSR_REQUESTED), chan.Hold.GetHoldState())
-
- # If we unhold, it should succeed immediately again, because there are no
- # resources to reclaim.
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED])
- q.expect('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_UNHELD, cs.HSR_REQUESTED])
- assertEquals((cs.HS_UNHELD, cs.HSR_REQUESTED), chan.Hold.GetHoldState())
-
- # Put the call back on hold ...
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED])
- q.expect('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_REQUESTED])
- assertEquals((cs.HS_HELD, cs.HSR_REQUESTED), chan.Hold.GetHoldState())
-
- # ... and request a stream.
- chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- # Syncing here to make sure SetStreamHeld happens after Ready...
- sync_dbus(bus, q, conn)
- stream_handler.Ready(jt.get_audio_codecs_dbus())
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- # Now Gabble tells the streaming implementation to go on hold (because it
- # said it was Ready), and the session is initiated.
- e = q.expect_many(
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- EventPattern('stream-iq',
- predicate=jp.action_predicate('session-initiate')),
- )[1]
-
- # Ensure that if Gabble sent the <hold/> stanza too early it's already
- # arrived.
- sync_stream(q, stream)
- q.unforbid_events(hold_event)
-
- stream.send(make_result_iq(stream, e.stanza))
-
- # We've acked the s-i, so we do speak Jingle; Gabble should send the
- # <hold/> notification.
- q.expect_many(*hold_event)
-
- # The call's still on hold, both before and after the streaming
- # implementation says it's okay with that (re-entering PENDING_HOLD seems
- # silly).
- assertEquals((cs.HS_HELD, cs.HSR_REQUESTED), chan.Hold.GetHoldState())
- stream_handler.HoldState(True)
- assertEquals((cs.HS_HELD, cs.HSR_REQUESTED), chan.Hold.GetHoldState())
-
- # The peer answers the call; they're still on hold.
- jt.parse_session_initiate(e.query)
- jt.accept()
-
- q.expect('stream-iq', iq_type='result')
-
- assertEquals((cs.HS_HELD, cs.HSR_REQUESTED), chan.Hold.GetHoldState())
-
- # Now we decide we do actually want to speak to them, and unhold.
- # Ensure that if Gabble sent the <unhold/> stanza too early it's already
- # arrived.
- sync_stream(q, stream)
- q.forbid_events(unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- )
-
- # Ensure that if Gabble sent the <unhold/> stanza too early it's already
- # arrived.
- sync_stream(q, stream)
- q.unforbid_events(unhold_event)
-
- call_async(q, stream_handler, 'HoldState', False)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
- *unhold_event
- )
-
- # Hooray! Now let's check that Hold works properly once the call's fully
- # established.
-
- # ---- Test 1: GetHoldState returns unheld and unhold is a no-op ----
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_UNHELD, hold_state
- chan.Hold.RequestHold(False)
-
- # ---- Test 2: successful hold ----
-
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- *hold_event
- )
-
- call_async(q, stream_handler, 'HoldState', True)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_REQUESTED]),
- )
-
- # ---- Test 3: GetHoldState returns held and hold is a no-op ----
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_HELD, hold_state
- chan.Hold.RequestHold(True)
-
- # ---- Test 4: successful unhold ----
-
- q.forbid_events(unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- )
-
- # Ensure that if Gabble sent the <unhold/> stanza too early it's already
- # arrived.
- sync_stream(q, stream)
- q.unforbid_events(unhold_event)
-
- call_async(q, stream_handler, 'HoldState', False)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
- *unhold_event
- )
-
- # ---- Test 5: GetHoldState returns False and unhold is a no-op ----
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_UNHELD, hold_state
- chan.Hold.RequestHold(False)
-
- # ---- Test 6: 3 parallel calls to hold ----
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_UNHELD, hold_state
-
- call_async(q, chan.Hold, 'RequestHold', True)
- call_async(q, chan.Hold, 'RequestHold', True)
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- *hold_event
- )
-
- call_async(q, stream_handler, 'HoldState', True)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_REQUESTED]),
- )
-
- # ---- Test 7: 3 parallel calls to unhold ----
-
- q.forbid_events(unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- call_async(q, chan.Hold, 'RequestHold', False)
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- )
-
- # Ensure that if Gabble sent the <unhold/> stanza too early it's already
- # arrived.
- sync_stream(q, stream)
- q.unforbid_events(unhold_event)
-
- call_async(q, stream_handler, 'HoldState', False)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
- *unhold_event
- )
-
- # ---- Test 8: hold, then change our minds before s-e has responded ----
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_UNHELD, hold_state
-
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- *hold_event
- )
-
- q.forbid_events(unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- # Gabble shouldn't send <unhold/> here because s-e might have already
- # relinquished the audio hardware.
- )
-
- sync_stream(q, stream)
- q.unforbid_events(unhold_event)
-
- call_async(q, stream_handler, 'HoldState', True)
- q.expect('dbus-return', method='HoldState', value=())
-
- call_async(q, stream_handler, 'HoldState', False)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
- *unhold_event
- )
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_UNHELD, hold_state
-
- # ---- Test 9: unhold, then change our minds before s-e has responded ----
-
- # Go to state "held" first
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- *hold_event
- )
- call_async(q, stream_handler, 'HoldState', True)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_REQUESTED]),
- )
-
- # Actually do test 9
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_HELD, hold_state
-
- # Check that Gabble doesn't send another <hold/>, or send <unhold/> before
- # we change our minds.
- q.forbid_events(unhold_event + hold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- )
-
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- )
-
-
- call_async(q, stream_handler, 'HoldState', False)
- call_async(q, stream_handler, 'HoldState', True)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_REQUESTED]),
- )
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_HELD, hold_state
-
- sync_stream(q, stream)
- q.unforbid_events(unhold_event + hold_event)
-
- # ---- Test 10: attempting to unhold fails ----
-
- # Check that Gabble doesn't send another <hold/>, or send <unhold/> even
- # though unholding fails.
- q.forbid_events(unhold_event + hold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- )
-
- call_async(q, stream_handler, 'UnholdFailure')
-
- q.expect_many(
- EventPattern('dbus-return', method='UnholdFailure', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_RESOURCE_NOT_AVAILABLE]),
- )
-
- sync_stream(q, stream)
- q.unforbid_events(unhold_event + hold_event)
-
- # ---- Test 11: when we successfully unhold, the peer gets <unhold/> ---
-
- q.forbid_events(unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- )
-
- # Ensure that if Gabble sent the <unhold/> stanza too early it's already
- # arrived.
- sync_stream(q, stream)
- q.unforbid_events(unhold_event)
-
- call_async(q, stream_handler, 'HoldState', False)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
- *unhold_event
- )
-
- # ---- The end ----
-
- chan.Group.RemoveMembers([self_handle], 'closed')
-
- # Test completed, close the connection
-
- e = q.expect('dbus-signal', signal='Close') #XXX - match against the path
-
-if __name__ == '__main__':
- test_all_dialects(test)
diff --git a/tests/twisted/jingle/hold-av.py b/tests/twisted/jingle/hold-av.py
deleted file mode 100644
index 1e150c01a..000000000
--- a/tests/twisted/jingle/hold-av.py
+++ /dev/null
@@ -1,481 +0,0 @@
-"""
-Test the Hold API.
-"""
-
-from gabbletest import make_result_iq, sync_stream
-from servicetest import (
- assertEquals, wrap_channel,
- make_channel_proxy, call_async, EventPattern, sync_dbus)
-
-import constants as cs
-
-from jingletest2 import JingleTest2, test_all_dialects
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def mutable_stream_tests(jp, jt, q, bus, conn, stream, chan, handle):
- # ---- Test 13: while the call's on hold, we add a new stream ---
- # We shouldn't go off hold locally as a result, and the new StreamHandler
- # should tell s-e to hold the stream.
-
- pending_hold = [
- EventPattern('dbus-signal', signal='HoldStateChanged',
- predicate=lambda e: e.args[0] == cs.HS_PENDING_HOLD),
- ]
- q.forbid_events(pending_hold)
-
- call_async(q, chan.StreamedMedia, 'RequestStreams', handle,
- [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- audio_stream_path = e.args[0]
- audio_stream_handler = make_channel_proxy(conn, e.args[0],
- 'Media.StreamHandler')
-
- # Syncing here to make sure SetStreamHeld happens after Ready...
- sync_dbus(bus, q, conn)
-
- audio_stream_handler.Ready(jt.get_audio_codecs_dbus())
- audio_stream_handler.NewNativeCandidate("fake",
- jt.get_remote_transports_dbus())
- audio_stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- q.expect_many(
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True],
- path=audio_stream_path),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[False],
- path=audio_stream_path),
- )
-
- assertEquals(cs.HS_HELD, chan.Hold.GetHoldState()[0])
-
- sync_dbus(bus, q, conn)
-
- # ---- Test 14: while the call's on hold, the peer adds a new stream ----
- # Again, we shouldn't go off hold locally as a result, and the new
- # StreamHandler should tell s-e to hold the stream.
-
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.peer, 'content-add', [
- jp.Content('videostream', 'initiator', 'both',
- jp.Description('video', [
- jp.PayloadType(name, str(rate), str(id), parameters) for
- (name, id, rate, parameters) in jt.video_codecs ]),
- jp.TransportGoogleP2P()) ]) ])
- stream.send(jp.xml(node))
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- video_stream_path = e.args[0]
- video_stream_handler = make_channel_proxy(conn, e.args[0],
- 'Media.StreamHandler')
-
- # Syncing here to make sure SetStreamHeld happens after Ready...
- sync_dbus(bus, q, conn)
-
- video_stream_handler.Ready(jt.get_video_codecs_dbus())
- video_stream_handler.NewNativeCandidate("fake",
- jt.get_remote_transports_dbus())
- video_stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- q.expect_many(
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True],
- path=video_stream_path),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[False],
- path=video_stream_path),
- )
-
- assertEquals(cs.HS_HELD, chan.Hold.GetHoldState()[0])
-
- sync_dbus(bus, q, conn)
- q.unforbid_events(pending_hold)
-
-
-
-def test(jp, q, bus, conn, stream):
- # These are 0- (for old dialects) or 1- (for new dialects) element lists
- # that can be splatted into expect_many with *
- hold_event = jp.rtp_info_event_list("hold")
- unhold_event = jp.rtp_info_event_list("unhold")
-
- # Let's forbid them until we're ready to start holding, to check that
- # Gabble doesn't send spurious notifications.
- q.forbid_events(hold_event)
- q.forbid_events(unhold_event)
-
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', 'foo@bar.com/Foo')
-
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]
- path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.HT_CONTACT, handle, True)
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia',
- ['Hold'])
-
- call_async(q, chan.StreamedMedia, 'RequestStreams', handle,
- [cs.MEDIA_STREAM_TYPE_AUDIO, cs.MEDIA_STREAM_TYPE_VIDEO])
-
- if not jp.can_do_video():
- # Video on GTalk? Not so much.
- e = q.expect('dbus-error', method='RequestStreams')
- # The spec and implemention say this should be NotAvailable, but wjt
- # thinks it should be NotCapable. The spec bug is #20920.
- name = e.error.get_dbus_name()
- #assert name == cs.NOT_CAPABLE, name
- return
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
-
- # FIXME: we assume this one's the audio stream, just because we requested
- # that first
- audio_stream_path = e.args[0]
- audio_stream_handler = make_channel_proxy(conn, e.args[0],
- 'Media.StreamHandler')
-
- audio_stream_handler.NewNativeCandidate("fake",
- jt.get_remote_transports_dbus())
- audio_stream_handler.Ready(jt.get_audio_codecs_dbus())
- audio_stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
-
- video_stream_path = e.args[0]
- video_stream_handler = make_channel_proxy(conn, e.args[0],
- 'Media.StreamHandler')
-
- video_stream_handler.NewNativeCandidate("fake",
- jt.get_remote_transports_dbus())
- video_stream_handler.Ready(jt.get_video_codecs_dbus())
- video_stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('session-initiate'))
- stream.send(make_result_iq(stream, e.stanza))
-
- jt.parse_session_initiate(e.query)
- jt.accept()
-
- q.expect('stream-iq', iq_type='result')
-
- # ---- Test 1: GetHoldState returns unheld and unhold is a no-op ----
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_UNHELD, hold_state
- chan.Hold.RequestHold(False)
-
- # We're about to start holding, so remove the ban on <hold/>.
- sync_stream(q, stream)
- q.unforbid_events(hold_event)
-
- # ---- Test 2: successful hold ----
-
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- *hold_event
- )
-
- call_async(q, audio_stream_handler, 'HoldState', True)
- call_async(q, video_stream_handler, 'HoldState', True)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_REQUESTED]),
- )
-
- # ---- Test 3: GetHoldState returns held and hold is a no-op ----
-
- q.forbid_events(hold_event)
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_HELD, hold_state
- chan.Hold.RequestHold(True)
-
- sync_stream(q, stream)
- q.unforbid_events(hold_event)
-
- # ---- Test 4: successful unhold ----
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- )
-
- sync_stream(q, stream)
- q.unforbid_events(unhold_event)
-
- call_async(q, audio_stream_handler, 'HoldState', False)
- call_async(q, video_stream_handler, 'HoldState', False)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
- *unhold_event
- )
-
- # ---- Test 5: GetHoldState returns False and unhold is a no-op ----
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_UNHELD, hold_state
- chan.Hold.RequestHold(False)
-
- # ---- Test 6: 3 parallel calls to hold ----
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_UNHELD, hold_state
-
- call_async(q, chan.Hold, 'RequestHold', True)
- call_async(q, chan.Hold, 'RequestHold', True)
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- *hold_event
- )
-
- call_async(q, audio_stream_handler, 'HoldState', True)
- call_async(q, video_stream_handler, 'HoldState', True)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_REQUESTED]),
- )
-
- # ---- Test 7: 3 parallel calls to unhold ----
-
- q.forbid_events(unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- call_async(q, chan.Hold, 'RequestHold', False)
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- )
-
- sync_stream(q, stream)
- q.unforbid_events(unhold_event)
-
- call_async(q, audio_stream_handler, 'HoldState', False)
- call_async(q, video_stream_handler, 'HoldState', False)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
- *unhold_event
- )
-
- # ---- Test 8: hold, then change our minds before s-e has responded ----
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_UNHELD, hold_state
-
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- *hold_event
- )
-
- # Gabble can't send <unhold/> until s-e confirms it has the resources
- q.forbid_events(unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- )
-
- call_async(q, audio_stream_handler, 'HoldState', True)
- call_async(q, video_stream_handler, 'HoldState', True)
- call_async(q, audio_stream_handler, 'HoldState', False)
-
- sync_stream(q, stream)
- q.unforbid_events(unhold_event)
-
- call_async(q, video_stream_handler, 'HoldState', False)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
- *unhold_event
- )
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_UNHELD, hold_state
-
- # ---- Test 9: unhold, then change our minds before s-e has responded ----
-
- # Go to state "held" first
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- *hold_event
- )
- call_async(q, audio_stream_handler, 'HoldState', True)
- call_async(q, video_stream_handler, 'HoldState', True)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_REQUESTED]),
- )
-
- # Actually do test 9
-
- q.forbid_events(hold_event + unhold_event)
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_HELD, hold_state
-
- call_async(q, chan.Hold, 'RequestHold', False)
- call_async(q, chan.Hold, 'RequestHold', True)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- )
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- )
-
- call_async(q, audio_stream_handler, 'HoldState', False)
- call_async(q, video_stream_handler, 'HoldState', False)
- call_async(q, audio_stream_handler, 'HoldState', True)
- call_async(q, video_stream_handler, 'HoldState', True)
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_REQUESTED]),
- )
-
- sync_stream(q, stream)
- q.unforbid_events(hold_event + unhold_event)
-
- hold_state = chan.Hold.GetHoldState()
- assert hold_state[0] == cs.HS_HELD, hold_state
-
- # ---- Test 10: attempting to unhold fails (both streams) ----
-
- q.forbid_events(hold_event + unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- )
-
- call_async(q, audio_stream_handler, 'UnholdFailure')
- call_async(q, video_stream_handler, 'UnholdFailure')
-
- q.expect_many(
- EventPattern('dbus-return', method='UnholdFailure', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_RESOURCE_NOT_AVAILABLE]),
- )
-
- sync_stream(q, stream)
- q.unforbid_events(hold_event + unhold_event)
-
- # ---- Test 11: attempting to unhold fails (first stream) ----
-
- q.forbid_events(hold_event + unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- )
-
- call_async(q, audio_stream_handler, 'UnholdFailure')
-
- q.expect_many(
- EventPattern('dbus-return', method='UnholdFailure', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_RESOURCE_NOT_AVAILABLE]),
- )
-
- sync_stream(q, stream)
- q.unforbid_events(hold_event + unhold_event)
-
- # ---- Test 12: attempting to unhold partially fails, so roll back ----
-
- q.forbid_events(hold_event + unhold_event)
-
- call_async(q, chan.Hold, 'RequestHold', False)
- q.expect_many(
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
- EventPattern('dbus-return', method='RequestHold', value=()),
- )
-
- call_async(q, audio_stream_handler, 'HoldState', False)
- q.expect('dbus-return', method='HoldState', value=())
-
- call_async(q, video_stream_handler, 'UnholdFailure')
-
- q.expect_many(
- EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
- EventPattern('dbus-return', method='UnholdFailure', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_PENDING_HOLD, cs.HSR_RESOURCE_NOT_AVAILABLE]),
- )
-
- call_async(q, audio_stream_handler, 'HoldState', True)
-
- q.expect_many(
- EventPattern('dbus-return', method='HoldState', value=()),
- EventPattern('dbus-signal', signal='HoldStateChanged',
- args=[cs.HS_HELD, cs.HSR_RESOURCE_NOT_AVAILABLE]),
- )
-
- sync_stream(q, stream)
- q.unforbid_events(hold_event + unhold_event)
-
- if jp.has_mutable_streams():
- mutable_stream_tests(jp, jt, q, bus, conn, stream, chan, handle)
-
- # ---- The end ----
-
- chan.Group.RemoveMembers([self_handle], 'closed')
-
- # Test completed, close the connection
-
- e = q.expect('dbus-signal', signal='Close') #XXX - match against the path
-
-if __name__ == '__main__':
- test_all_dialects(test)
diff --git a/tests/twisted/jingle/incoming-basics.py b/tests/twisted/jingle/incoming-basics.py
deleted file mode 100644
index 28c0598fb..000000000
--- a/tests/twisted/jingle/incoming-basics.py
+++ /dev/null
@@ -1,191 +0,0 @@
-"""
-Test incoming call handling.
-"""
-
-import dbus
-
-from gabbletest import make_result_iq
-from servicetest import (
- make_channel_proxy, unwrap, EventPattern, assertEquals, assertLength)
-from jingletest2 import JingleTest2, test_all_dialects
-import constants as cs
-
-from twisted.words.xish import xpath
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(jp, q, bus, conn, stream, peer='foo@bar.com/Foo'):
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', peer)
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]
-
- # Remote end calls us
- jt.incoming_call()
-
- # If this is a Jingle dialect that supports it, Gabble should send a
- # <ringing/> notification when it gets the session-initiate until Telepathy
- # has a way for the UI to do this.
- # https://bugs.freedesktop.org/show_bug.cgi?id=21964
- ringing_event = jp.rtp_info_event_list("ringing")
-
- if jp.dialect == 'gtalk-v0.4':
- # With gtalk4, apparently we have to send transport-accept immediately,
- # not even just before we send our transport-info. wjt tested this, and
- # indeed if we don't send this for incoming calls, the call never
- # connects.
- ta_event = [
- EventPattern('stream-iq', predicate=lambda x:
- xpath.queryForNodes("/iq/session[@type='transport-accept']",
- x.stanza)),
- ]
- else:
- ta_event = []
-
- nc, e = q.expect_many(
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewSessionHandler'),
- *(ringing_event + ta_event)
- )[0:2]
- path, ct, ht, h, _ = nc.args
-
- assert ct == cs.CHANNEL_TYPE_STREAMED_MEDIA, ct
- assert ht == cs.HT_CONTACT, ht
- assert h == remote_handle, h
-
- media_chan = make_channel_proxy(conn, path, 'Channel.Interface.Group')
- media_iface = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')
-
- # S-E was notified about new session handler, and calls Ready on it
- assert e.args[1] == 'rtp'
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- nsh_event = q.expect('dbus-signal', signal='NewStreamHandler')
-
- # S-E gets notified about a newly-created stream
- stream_handler = make_channel_proxy(conn, nsh_event.args[0],
- 'Media.StreamHandler')
-
- streams = media_iface.ListStreams()
- assertLength(1, streams)
-
- stream_id, stream_handle, stream_type, _, stream_direction, pending_flags =\
- streams[0]
- assertEquals(remote_handle, stream_handle)
- assertEquals(cs.MEDIA_STREAM_TYPE_AUDIO, stream_type)
- assertEquals(cs.MEDIA_STREAM_DIRECTION_RECEIVE, stream_direction)
- assertEquals(cs.MEDIA_STREAM_PENDING_LOCAL_SEND, pending_flags)
-
- # Exercise channel properties
- channel_props = media_chan.GetAll(
- cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE)
- assertEquals(remote_handle, channel_props['TargetHandle'])
- assertEquals(cs.HT_CONTACT, channel_props['TargetHandleType'])
- assertEquals((cs.HT_CONTACT, remote_handle),
- media_chan.GetHandle(dbus_interface=cs.CHANNEL))
- assertEquals(jt.peer_bare_jid, channel_props['TargetID'])
- assertEquals(jt.peer_bare_jid, channel_props['InitiatorID'])
- assertEquals(remote_handle, channel_props['InitiatorHandle'])
- assertEquals(False, channel_props['Requested'])
-
- group_props = media_chan.GetAll(
- cs.CHANNEL_IFACE_GROUP, dbus_interface=dbus.PROPERTIES_IFACE)
-
- assert group_props['SelfHandle'] == self_handle, \
- (group_props['SelfHandle'], self_handle)
-
- flags = group_props['GroupFlags']
- assert flags & cs.GF_PROPERTIES, flags
- # Changing members in any way other than adding or removing yourself is
- # meaningless for incoming calls, and the flags need not be sent to change
- # your own membership.
- assert not flags & cs.GF_CAN_ADD, flags
- assert not flags & cs.GF_CAN_REMOVE, flags
- assert not flags & cs.GF_CAN_RESCIND, flags
-
- assert group_props['Members'] == [remote_handle], group_props['Members']
- assert group_props['RemotePendingMembers'] == [], \
- group_props['RemotePendingMembers']
- # We're local pending because remote_handle invited us.
- assert group_props['LocalPendingMembers'] == \
- [(self_handle, remote_handle, cs.GC_REASON_INVITED, '')], \
- unwrap(group_props['LocalPendingMembers'])
-
- streams = media_chan.ListStreams(
- dbus_interface=cs.CHANNEL_TYPE_STREAMED_MEDIA)
- assert len(streams) == 1, streams
- assert len(streams[0]) == 6, streams[0]
- # streams[0][0] is the stream identifier, which in principle we can't
- # make any assertion about (although in practice it's probably 1)
- assert streams[0][1] == remote_handle, (streams[0], remote_handle)
- assert streams[0][2] == cs.MEDIA_STREAM_TYPE_AUDIO, streams[0]
- # We haven't connected yet
- assert streams[0][3] == cs.MEDIA_STREAM_STATE_DISCONNECTED, streams[0]
- # In Gabble, incoming streams start off with remote send enabled, and
- # local send requested
- assert streams[0][4] == cs.MEDIA_STREAM_DIRECTION_RECEIVE, streams[0]
- assert streams[0][5] == cs.MEDIA_STREAM_PENDING_LOCAL_SEND, streams[0]
-
- # Connectivity checks happen before we have accepted the call
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler.Ready(jt.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
- stream_handler.SupportedCodecs(jt.get_audio_codecs_dbus())
-
- # peer gets the transport
- e = q.expect('stream-iq', predicate=jp.action_predicate('transport-info'))
- assertEquals(jt.peer, e.query['initiator'])
-
- if jp.dialect in ['jingle-v0.15', 'jingle-v0.31']:
- content = xpath.queryForNodes('/iq/jingle/content', e.stanza)[0]
- assertEquals('initiator', content['creator'])
-
- stream.send(make_result_iq(stream, e.stanza))
-
- # At last, accept the call
- media_chan.AddMembers([self_handle], 'accepted')
-
- # Call is accepted, we become a member, and the stream that was pending
- # local send is now sending.
- memb, acc, _, _, _ = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [self_handle], [], [], [], self_handle,
- cs.GC_REASON_NONE]),
- EventPattern('stream-iq',
- predicate=jp.action_predicate('session-accept')),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[True]),
- EventPattern('dbus-signal', signal='SetStreamPlaying', args=[True]),
- EventPattern('dbus-signal', signal='StreamDirectionChanged',
- args=[stream_id, cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL, 0]),
- )
-
- stream.send(make_result_iq(stream, acc.stanza))
-
- # Also, if this is a Jingle dialect that supports it, Gabble should send an
- # <active/> notification when the session-accept is acked (until the
- # Telepathy spec lets the UI say it's not ringing any more).
- active_event = jp.rtp_info_event("active")
- if active_event is not None:
- q.expect_many(active_event)
-
- # we are now both in members
- members = media_chan.GetMembers()
- assert set(members) == set([self_handle, remote_handle]), members
-
- # Connected! Blah, blah, ...
-
- # 'Nuff said
- jt.terminate()
- q.expect('dbus-signal', signal='Closed', path=path)
-
-if __name__ == '__main__':
- test_all_dialects(test)
- test_all_dialects(lambda jp, q, bus, conn, stream:
- test(jp, q, bus, conn, stream, 'foo@sip.bar.com'))
diff --git a/tests/twisted/jingle/incoming-call-stream-error.py b/tests/twisted/jingle/incoming-call-stream-error.py
deleted file mode 100644
index b6a9e25b7..000000000
--- a/tests/twisted/jingle/incoming-call-stream-error.py
+++ /dev/null
@@ -1,107 +0,0 @@
-
-"""
-Test handling of Error() call on stream handler.
-
-This tests a regression in which MembersChanged was emitted with reason other
-than GC_REASON_ERROR.
-"""
-
-from servicetest import EventPattern, assertEquals, make_channel_proxy
-from jingletest2 import JingleTest2, test_all_dialects
-import constants as cs
-
-from twisted.words.xish import xpath
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def _session_terminate_predicate(event, reason, msg, jp):
- matches = jp.match_jingle_action(event.query, 'session-terminate')
-
- if matches and jp.is_modern_jingle():
- reason = xpath.queryForNodes("/iq"
- "/jingle[@action='session-terminate']"
- "/reason/%s" % reason,
- event.stanza)
- reason_text = xpath.queryForString("/iq/jingle/reason/text",
- event.stanza)
-
- return bool(reason) and reason_text == msg
-
- return matches
-
-def _test(jp, q, bus, conn, stream,
- jingle_reason, group_change_reason, stream_error):
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', 'foo@bar.com/Foo')
- jt.prepare()
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, ["foo@bar.com/Foo"])[0]
-
- # Ring ring!
- jt.incoming_call()
- new_channel, new_session_handler = q.expect_many(
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewSessionHandler'))
- assertEquals(cs.CHANNEL_TYPE_STREAMED_MEDIA, new_channel.args[1])
- assertEquals(cs.HT_CONTACT, new_channel.args[2])
- assertEquals(remote_handle, new_channel.args[3])
- assertEquals('rtp', new_session_handler.args[1])
-
- channel_path = new_channel.args[0]
-
- # Client calls Ready on new session handler.
- session_handler = make_channel_proxy(
- conn, new_session_handler.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- # Client gets notified about a newly created stream...
- new_stream_handler = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_id = new_stream_handler.args[1]
- stream_handler = make_channel_proxy(
- conn, new_stream_handler.args[0], 'Media.StreamHandler')
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler.Ready(jt.dbusify_codecs([("FOO", 5, 8000, {})]))
-
- q.expect('dbus-signal', signal='SetRemoteCodecs')
-
- msg = u"o noes"
-
- # ...but something goes wrong.
- stream_handler.Error(stream_error, msg)
-
- q.expect("stream-iq", iq_type="set",
- predicate=lambda x: _session_terminate_predicate(x, jingle_reason,
- msg, jp))
- # Bye bye members.
- mc = q.expect('dbus-signal', signal='MembersChanged',
- interface=cs.CHANNEL_IFACE_GROUP, path=channel_path,
- args=[msg, [], [self_handle, remote_handle], [],
- [], self_handle, group_change_reason])
-
- q.expect('dbus-signal', signal='StreamError',
- interface=cs.CHANNEL_TYPE_STREAMED_MEDIA,
- args=[stream_id, stream_error, msg])
-
- # Bye bye stream
- q.expect('dbus-signal', signal='Close')
- q.expect('dbus-signal', signal='StreamRemoved')
-
- # Bye bye channel.
- q.expect('dbus-signal', signal='Closed')
- q.expect('dbus-signal', signal='ChannelClosed')
-
-def test_connection_error(jp, q, bus, conn, stream):
- _test(jp, q, bus, conn, stream, "connectivity-error", cs.GC_REASON_ERROR,
- cs.MEDIA_STREAM_ERROR_NETWORK_ERROR)
-
-def test_codec_negotiation_fail(jp, q, bus, conn, stream):
- _test(jp, q, bus, conn, stream, "failed-application", cs.GC_REASON_ERROR,
- cs.MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED)
-
-if __name__ == '__main__':
- test_all_dialects(test_connection_error)
- test_all_dialects(test_codec_negotiation_fail)
diff --git a/tests/twisted/jingle/incoming-gmail-modern-jingle.py b/tests/twisted/jingle/incoming-gmail-modern-jingle.py
deleted file mode 100644
index 033a9975d..000000000
--- a/tests/twisted/jingle/incoming-gmail-modern-jingle.py
+++ /dev/null
@@ -1,190 +0,0 @@
-"""
-Tests workarounds for calls with the GMail client, which supports a (currently
-quirky) variation on the theme of modern Jingle.
-"""
-
-from servicetest import EventPattern, wrap_channel, make_channel_proxy, assertEquals
-from gabbletest import elem, elem_iq, exec_test
-from jingletest2 import JingleTest2, JingleProtocol031
-import ns
-import constants as cs
-from twisted.words.xish import xpath
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-class GMail(JingleTest2):
- remote_caps = {
- 'ext': 'pmuc-v1 sms-v1 camera-v1 video-v1 voice-v1',
- 'ver': '1.1',
- 'node': 'http://mail.google.com/xmpp/client/caps',
- }
-
-def test(q, bus, conn, stream):
- peer = 'foo@gmail.com/gmail.7E1F07D0'
- self = 'test@localhost/test'
- jp = JingleProtocol031()
- jt = GMail(jp, conn, q, stream, 'test@localhost', peer)
- jt.prepare(send_roster=False)
-
- sid = 'c1025763497'
- iq_id = 'session_init_iq'
- si = elem_iq(stream, 'set', from_=peer, to=self, id=iq_id)(
- elem(ns.JINGLE, 'jingle', action='session-initiate', sid=sid, initiator=peer)(
- elem('content', name='video')(
- elem(ns.JINGLE_RTP, 'description', media='video')(
- elem('payload-type', id='99', name='H264-SVC')(
- elem('parameter', name='width', value='320'),
- elem('parameter', name='height', value='200'),
- elem('parameter', name='framerate', value='30'),
- ),
- # ... other codecs elided ...
- elem('encryption'),
- ),
- elem(ns.GOOGLE_P2P, 'transport'),
- ),
- elem('content', name='audio')(
- elem(ns.JINGLE_RTP, 'description', media='audio')(
- elem('payload-type', id='103', name='ISAC', clockrate='16000')(
- elem('parameter', name='bitrate', value='32000'),
- ),
- # ... other codecs elided ...
- elem('encryption'),
- ),
- elem(ns.GOOGLE_P2P, 'transport'),
- )
- ),
- elem(ns.GOOGLE_SESSION, 'session', action='initiate', sid='c1025763497', initiator=peer)(
- elem(ns.GOOGLE_SESSION_VIDEO, 'description')(
- elem('payload-type', id='99', name='H264-SVC', width='320', height='200', framerate='30'),
- # ... other codecs elided ...
- elem(ns.JINGLE_RTP, 'encryption')(
- elem(ns.GOOGLE_SESSION_VIDEO, 'usage'),
- ),
- elem(ns.GOOGLE_SESSION_PHONE, 'payload-type', id='103', name='ISAC', bitrate='32000', clockrate='16000'),
- # ... other codecs elided ...
- elem(ns.JINGLE_RTP, 'encryption')(
- elem(ns.GOOGLE_SESSION_PHONE, 'usage'),
- ),
- ),
- ),
- )
- stream.send(si)
-
- ok, nc, nsh = q.expect_many(
- # fd.o #65131: we have to tell Google which dialect we're speaking
- EventPattern('stream-iq', iq_type='result',
- query_name='jingle', query_ns=ns.JINGLE,
- iq_id=iq_id),
- EventPattern('dbus-signal', signal='NewChannels'),
- EventPattern('dbus-signal', signal='NewSessionHandler'),
- )
-
- path, properties = nc.args[0][0]
-
- # It's an audio+video call
- assert properties[cs.INITIAL_AUDIO]
- assert properties[cs.INITIAL_VIDEO]
- # Google can't add and remove streams on the fly. We special-case GMail.
- assert properties[cs.IMMUTABLE_STREAMS]
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia')
- session_handler = make_channel_proxy(conn, nsh.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- path, _, _, _ = q.expect('dbus-signal', signal='NewStreamHandler').args
- stream1 = make_channel_proxy(conn, path, 'Media.StreamHandler')
- path, _, _, _ = q.expect('dbus-signal', signal='NewStreamHandler').args
- stream2 = make_channel_proxy(conn, path, 'Media.StreamHandler')
-
- stream1.Ready([])
- stream2.Ready([])
-
- # Audio rtcp
- stream.send(
- elem_iq(stream, from_=peer, to=self, type='set')(
- elem(ns.JINGLE, 'jingle', action='transport-info', sid=sid)(
- elem('content', name='audio')(
- elem(ns.GOOGLE_P2P, 'transport')(
- elem('candidate', address='172.22.64.192', port='54335',
- name='rtcp', username='+wJqkmRVYotCz+Rd',
- password='POWPzg5Pks4+ywAz', preference='1', protocol='udp',
- generation='0', network='1', type='local')
- )
- )
- )
- )
- )
- q.expect('dbus-signal', signal='AddRemoteCandidate', path=stream1.object_path)
-
- # audio rtp
- stream.send(
- elem_iq(stream, from_=peer, to=self, type='set')(
- elem(ns.JINGLE, 'jingle', action='transport-info', sid=sid)(
- elem('content', name='audio')(
- elem(ns.GOOGLE_P2P, 'transport')(
- elem('candidate', address='172.22.64.192', port='54337',
- name='rtp', username='F7rgdWcCgH3Q/HgE',
- password='ioh2IDwd3iZEZHzM', preference='1', protocol='udp',
- generation='0', network='1', type='local')
- )
- )
- )
- )
- )
- q.expect('dbus-signal', signal='AddRemoteCandidate', path=stream1.object_path)
-
- # video rtcp: note the weird name='' field which Gabble has to work around
- stream.send(
- elem_iq(stream, from_=peer, to=self, type='set')(
- elem(ns.JINGLE, 'jingle', action='transport-info', sid=sid)(
- elem('content', name='video')(
- elem(ns.GOOGLE_P2P, 'transport')(
- elem('candidate', address='172.22.64.192', port='54339',
- name='video_rtcp', username='fnLduEIu6VHsSOqh',
- password='IYeNu/HWzMpx2zrS', preference='1', protocol='udp',
- generation='0', network='1', type='local')
- )
- )
- )
- )
- )
- q.expect('dbus-signal', signal='AddRemoteCandidate', path=stream2.object_path)
-
- # video rtp: ditto
- stream.send(
- elem_iq(stream, from_=peer, to=self, type='set')(
- elem(ns.JINGLE, 'jingle', action='transport-info', sid=sid)(
- elem('content', name='video')(
- elem(ns.GOOGLE_P2P, 'transport')(
- elem('candidate', address='172.22.64.192', port='54341',
- name='video_rtp', username='mZVBFdQ2LyAP6oyE',
- password='3uoyCHP8zwE+/Ylw', preference='1', protocol='udp',
- generation='0', network='1', type='local')
- )
- )
- )
- )
- )
- q.expect('dbus-signal', signal='AddRemoteCandidate', path=stream2.object_path)
-
- # Test that we're sending with name='video_rtp' as well, but only for the video stream.
- stream1.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- e = q.expect('stream-iq', predicate=jp.action_predicate('transport-info'))
- candidate = xpath.queryForNodes(
- '/iq/jingle/content[@name="audio"]/transport/candidate',
- e.stanza)[0]
- assertEquals('rtp', candidate['name'])
-
- stream2.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- e = q.expect('stream-iq', predicate=jp.action_predicate('transport-info'))
- candidate = xpath.queryForNodes(
- '/iq/jingle/content[@name="video"]/transport/candidate',
- e.stanza)[0]
- assertEquals('video_rtp', candidate['name'])
-
-if __name__ == '__main__':
- exec_test(test)
diff --git a/tests/twisted/jingle/initial-audio-video.py b/tests/twisted/jingle/initial-audio-video.py
deleted file mode 100644
index 49bb285aa..000000000
--- a/tests/twisted/jingle/initial-audio-video.py
+++ /dev/null
@@ -1,192 +0,0 @@
-"""
-Tests outgoing calls created with InitialAudio and/or InitialVideo, and
-exposing the initial contents of incoming calls as values of InitialAudio and
-InitialVideo
-"""
-
-import operator
-
-from servicetest import (
- assertContains, assertEquals, assertLength,
- wrap_channel, EventPattern, call_async, make_channel_proxy)
-
-from jingletest2 import JingleTest2, test_all_dialects
-
-import constants as cs
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def outgoing(jp, q, bus, conn, stream):
- remote_jid = 'flames@cold.mountain/beyond'
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', remote_jid)
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, [remote_jid])[0]
-
- rccs = conn.Properties.Get(cs.CONN_IFACE_REQUESTS, 'RequestableChannelClasses')
- media_classes = [ rcc for rcc in rccs
- if rcc[0][cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAMED_MEDIA ]
-
- assertLength(1, media_classes)
- fixed, allowed = media_classes[0]
- assertContains(cs.INITIAL_AUDIO, allowed)
- assertContains(cs.INITIAL_VIDEO, allowed)
-
- check_neither(q, conn, bus, stream, remote_handle)
- check_iav(jt, q, conn, bus, stream, remote_handle, True, False)
- check_iav(jt, q, conn, bus, stream, remote_handle, False, True)
- check_iav(jt, q, conn, bus, stream, remote_handle, True, True)
-
-def check_neither(q, conn, bus, stream, remote_handle):
- """
- Make a channel without specifying InitialAudio or InitialVideo; check
- that it's announced with both False, and that they're both present and
- false in GetAll().
- """
-
- path, props = conn.Requests.CreateChannel({
- cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_HANDLE: remote_handle})
-
- assertContains((cs.INITIAL_AUDIO, False), props.items())
- assertContains((cs.INITIAL_VIDEO, False), props.items())
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path),
- cs.CHANNEL_TYPE_STREAMED_MEDIA, ['MediaSignalling'])
- props = chan.Properties.GetAll(cs.CHANNEL_TYPE_STREAMED_MEDIA)
- assertContains(('InitialAudio', False), props.items())
- assertContains(('InitialVideo', False), props.items())
-
- # We shouldn't have started a session yet, so there shouldn't be any
- # session handlers. Strictly speaking, there could be a session handler
- # with no stream handlers, but...
- session_handlers = chan.MediaSignalling.GetSessionHandlers()
- assertLength(0, session_handlers)
-
-def check_iav(jt, q, conn, bus, stream, remote_handle, initial_audio,
- initial_video):
- """
- Make a channel and check that its InitialAudio and InitialVideo properties
- come out correctly.
- """
-
- call_async(q, conn.Requests, 'CreateChannel', {
- cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_HANDLE: remote_handle,
- cs.INITIAL_AUDIO: initial_audio,
- cs.INITIAL_VIDEO: initial_video,
- })
- if initial_video and (not jt.jp.can_do_video()
- or (not initial_audio and not jt.jp.can_do_video_only ())):
- # Some protocols can't do video
- event = q.expect('dbus-error', method='CreateChannel')
- assertEquals(cs.NOT_CAPABLE, event.error.get_dbus_name())
- else:
- path, props = q.expect('dbus-return', method='CreateChannel').value
-
- assertContains((cs.INITIAL_AUDIO, initial_audio), props.items())
- assertContains((cs.INITIAL_VIDEO, initial_video), props.items())
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path),
- cs.CHANNEL_TYPE_STREAMED_MEDIA, ['MediaSignalling'])
- props = chan.Properties.GetAll(cs.CHANNEL_TYPE_STREAMED_MEDIA)
- assertContains(('InitialAudio', initial_audio), props.items())
- assertContains(('InitialVideo', initial_video), props.items())
-
- session_handlers = chan.MediaSignalling.GetSessionHandlers()
-
- assertLength(1, session_handlers)
- path, type = session_handlers[0]
- assertEquals('rtp', type)
- session_handler = make_channel_proxy(conn, path, 'Media.SessionHandler')
- session_handler.Ready()
-
- stream_handler_paths = []
- stream_handler_types = []
-
- for x in [initial_audio, initial_video]:
- if x:
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_handler_paths.append(e.args[0])
- stream_handler_types.append(e.args[2])
-
- if initial_audio:
- assertContains(cs.MEDIA_STREAM_TYPE_AUDIO, stream_handler_types)
-
- if initial_video:
- assertContains(cs.MEDIA_STREAM_TYPE_VIDEO, stream_handler_types)
-
- for x in xrange (0, len(stream_handler_paths)):
- p = stream_handler_paths[x]
- t = stream_handler_types[x]
- sh = make_channel_proxy(conn, p, 'Media.StreamHandler')
- sh.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- if t == cs.MEDIA_STREAM_TYPE_AUDIO:
- sh.Ready(jt.get_audio_codecs_dbus())
- else:
- sh.Ready(jt.get_video_codecs_dbus())
- sh.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq',
- predicate=jt.jp.action_predicate('session-initiate'))
- jt.parse_session_initiate (e.query)
-
- jt.accept()
-
- events = reduce(operator.concat,
- [ [ EventPattern('dbus-signal', signal='SetRemoteCodecs', path=p),
- EventPattern('dbus-signal', signal='SetStreamPlaying', path=p),
- ] for p in stream_handler_paths
- ], [])
- q.expect_many(*events)
-
- chan.Close()
-
-def incoming(jp, q, bus, conn, stream):
- remote_jid = 'skinny.fists@heaven/antennas'
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', remote_jid)
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, [remote_jid])[0]
-
- for a, v in [("audio1", None), (None, "video1"), ("audio1", "video1")]:
- if v!= None and not jp.can_do_video():
- continue
- if a == None and v != None and not jp.can_do_video_only():
- continue
-
- jt.incoming_call(audio=a, video=v)
- e = q.expect('dbus-signal', signal='NewChannels',
- predicate=lambda e:
- cs.CHANNEL_TYPE_CONTACT_LIST not in e.args[0][0][1].values())
- chans = e.args[0]
- assertLength(1, chans)
-
- path, props = chans[0]
-
- assertEquals(cs.CHANNEL_TYPE_STREAMED_MEDIA, props[cs.CHANNEL_TYPE])
- assertEquals(a != None, props[cs.INITIAL_AUDIO])
- assertEquals(v != None, props[cs.INITIAL_VIDEO])
-
- # FIXME: This doesn't check non-Google contacts that can only do one
- # media type, as such contacts as simulated by JingleTest2 can always
- # do both.
- assertEquals(not jp.can_do_video() or not jp.can_do_video_only(),
- props[cs.IMMUTABLE_STREAMS])
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path),
- cs.CHANNEL_TYPE_STREAMED_MEDIA)
- chan.Close()
-
-
-if __name__ == '__main__':
- test_all_dialects(outgoing)
- test_all_dialects(incoming)
diff --git a/tests/twisted/jingle/jingletest2.py b/tests/twisted/jingle/jingletest2.py
index 64eaa40e8..1883960c1 100644
--- a/tests/twisted/jingle/jingletest2.py
+++ b/tests/twisted/jingle/jingletest2.py
@@ -823,18 +823,18 @@ class JingleTest2(object):
def get_call_audio_md_dbus(self, handle = 0):
d = dbus.Dictionary(
- { cs.CALL_CONTENT_MEDIADESCRIPTION + '.Codecs': self.__get_call_audio_codecs_dbus(),
+ { cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.Codecs': self.__get_call_audio_codecs_dbus(),
}, signature='sv')
if handle != 0:
- d[cs.CALL_CONTENT_MEDIADESCRIPTION + '.RemoteContact'] = dbus.UInt32 (handle)
+ d[cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.RemoteContact'] = dbus.UInt32 (handle)
return d
def get_call_video_md_dbus(self, handle = 0):
d = dbus.Dictionary(
- { cs.CALL_CONTENT_MEDIADESCRIPTION + '.Codecs': self.__get_call_video_codecs_dbus(),
+ { cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.Codecs': self.__get_call_video_codecs_dbus(),
}, signature='sv')
if handle != 0:
- d[cs.CALL_CONTENT_MEDIADESCRIPTION + '.RemoteContact'] = dbus.UInt32 (handle)
+ d[cs.CALL_CONTENT_MEDIA_DESCRIPTION + '.RemoteContact'] = dbus.UInt32 (handle)
return d
def get_remote_transports_dbus(self):
diff --git a/tests/twisted/jingle/misuse.py b/tests/twisted/jingle/misuse.py
deleted file mode 100644
index 51283b4c0..000000000
--- a/tests/twisted/jingle/misuse.py
+++ /dev/null
@@ -1,52 +0,0 @@
-"""
-Test misuse of the streamed media API, which should return error messages
-rather than asserting Gabble.
-"""
-
-from dbus import DBusException
-
-from servicetest import make_channel_proxy, wrap_channel, assertEquals
-from gabbletest import exec_test
-from jingletest2 import JingleTest2, JingleProtocol031
-
-import constants as cs
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(q, bus, conn, stream):
- jp = JingleProtocol031()
- remote_jid = 'foo@example.com/misc'
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', remote_jid)
-
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, [remote_jid])[0]
- path, _ = conn.Requests.CreateChannel({
- cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_HANDLE: remote_handle})
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia')
-
- # In Gabble, the StreamedMedia channel is secretly also the SessionHandler.
- # Let's make up a proxy and call some methods on it. They should fail
- # gracefully, rather than crashing Gabble.
- session_handler = make_channel_proxy(conn, path, 'Media.SessionHandler')
-
- try:
- session_handler.Ready()
- except DBusException, e:
- assertEquals(cs.NOT_AVAILABLE, e.get_dbus_name())
-
- try:
- session_handler.Error(0, "slowing down but with a sense of speeding up")
- except DBusException, e:
- assertEquals(cs.NOT_AVAILABLE, e.get_dbus_name())
-
-if __name__ == '__main__':
- exec_test(test)
diff --git a/tests/twisted/jingle/outgoing-basics.py b/tests/twisted/jingle/outgoing-basics.py
deleted file mode 100644
index 0e9a5f269..000000000
--- a/tests/twisted/jingle/outgoing-basics.py
+++ /dev/null
@@ -1,349 +0,0 @@
-"""
-Test basic outgoing call handling, using CreateChannel and all three variations
-of RequestChannel.
-"""
-from functools import partial
-import dbus
-from twisted.words.xish import xpath
-
-from gabbletest import exec_test
-from servicetest import (
- make_channel_proxy, wrap_channel,
- EventPattern, call_async,
- assertEquals, assertContains, assertLength,
- )
-import constants as cs
-from jingletest2 import JingleTest2, test_all_dialects
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-# There are various deprecated APIs for requesting calls, documented at
-# <http://telepathy.freedesktop.org/wiki/Requesting StreamedMedia channels>.
-# These are ordered from most recent to most deprecated.
-CREATE = 0 # CreateChannel({TargetHandleType: Contact, TargetHandle: h});
- # RequestStreams()
-REQUEST_ANONYMOUS = 1 # RequestChannel(HandleTypeNone, 0); RequestStreams()
-REQUEST_ANONYMOUS_AND_ADD = 2 # RequestChannel(HandleTypeNone, 0);
- # AddMembers([h], ...); RequestStreams(h,...)
-REQUEST_NONYMOUS = 3 # RequestChannel(HandleTypeContact, h);
- # RequestStreams(h, ...)
-
-def create(jp, q, bus, conn, stream, peer='foo@bar.com/Res'):
- worker(jp, q, bus, conn, stream, CREATE, peer)
-
-def request_anonymous(jp, q, bus, conn, stream, peer='publish@foo.com/Res'):
- worker(jp, q, bus, conn, stream, REQUEST_ANONYMOUS, peer)
-
-def request_anonymous_and_add(jp, q, bus, conn, stream,
- peer='publish-subscribe@foo.com/Res'):
- worker(jp, q, bus, conn, stream, REQUEST_ANONYMOUS_AND_ADD, peer)
-
-def request_nonymous(jp, q, bus, conn, stream, peer='subscribe@foo.com/Res'):
- worker(jp, q, bus, conn, stream, REQUEST_NONYMOUS, peer)
-
-def worker(jp, q, bus, conn, stream, variant, peer):
- jt2 = JingleTest2(jp, conn, q, stream, 'test@localhost', peer)
- jt2.prepare(send_presence=True, send_roster=True)
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(1, [jt2.peer])[0]
-
- if variant == REQUEST_NONYMOUS:
- path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.HT_CONTACT, remote_handle, True)
- elif variant == CREATE:
- path = conn.Requests.CreateChannel({
- cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_HANDLE: remote_handle,
- })[0]
- else:
- path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.HT_NONE, 0, True)
-
- old_sig, new_sig = q.expect_many(
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewChannels',
- predicate=lambda e:
- cs.CHANNEL_TYPE_CONTACT_LIST not in e.args[0][0][1].values()),
- )
-
- if variant == REQUEST_NONYMOUS or variant == CREATE:
- assertEquals( [path, cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.HT_CONTACT,
- remote_handle, True], old_sig.args)
- else:
- assertEquals( [path, cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.HT_NONE, 0,
- True], old_sig.args)
-
- assertLength(1, new_sig.args)
- assertLength(1, new_sig.args[0]) # one channel
- assertLength(2, new_sig.args[0][0]) # two struct members
- emitted_props = new_sig.args[0][0][1]
-
- assertEquals(
- cs.CHANNEL_TYPE_STREAMED_MEDIA, emitted_props[cs.CHANNEL_TYPE])
-
- if variant == REQUEST_NONYMOUS or variant == CREATE:
- assertEquals(remote_handle, emitted_props[cs.TARGET_HANDLE])
- assertEquals(cs.HT_CONTACT, emitted_props[cs.TARGET_HANDLE_TYPE])
- assertEquals(jt2.peer_bare_jid, emitted_props[cs.TARGET_ID])
- else:
- assertEquals(0, emitted_props[cs.TARGET_HANDLE])
- assertEquals(cs.HT_NONE, emitted_props[cs.TARGET_HANDLE_TYPE])
- assertEquals('', emitted_props[cs.TARGET_ID])
-
- assertEquals(True, emitted_props[cs.REQUESTED])
- assertEquals(self_handle, emitted_props[cs.INITIATOR_HANDLE])
- assertEquals('test@localhost', emitted_props[cs.INITIATOR_ID])
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia',
- ['MediaSignalling'])
-
- # Exercise basic Channel Properties
- channel_props = chan.Properties.GetAll(cs.CHANNEL)
-
- assertEquals(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- channel_props.get('ChannelType'))
-
- if variant == REQUEST_NONYMOUS or variant == CREATE:
- assertEquals(remote_handle, channel_props['TargetHandle'])
- assertEquals(cs.HT_CONTACT, channel_props['TargetHandleType'])
- assertEquals(jt2.peer_bare_jid, channel_props['TargetID'])
- assertEquals((cs.HT_CONTACT, remote_handle), chan.GetHandle())
- else:
- assertEquals(0, channel_props['TargetHandle'])
- assertEquals(cs.HT_NONE, channel_props['TargetHandleType'])
- assertEquals('', channel_props['TargetID'])
- assertEquals((cs.HT_NONE, 0), chan.GetHandle())
-
- for interface in [
- cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_MEDIA_SIGNALLING,
- cs.TP_AWKWARD_PROPERTIES, cs.CHANNEL_IFACE_HOLD]:
- assertContains(interface, channel_props['Interfaces'])
-
- assertEquals(True, channel_props['Requested'])
- assertEquals('test@localhost', channel_props['InitiatorID'])
- assertEquals(conn.GetSelfHandle(), channel_props['InitiatorHandle'])
-
- # Exercise Group Properties
- group_props = chan.Properties.GetAll(cs.CHANNEL_IFACE_GROUP)
-
- assertEquals([self_handle], group_props['Members'])
- assertEquals([], group_props['LocalPendingMembers'])
-
- if variant == REQUEST_NONYMOUS:
- # In this variant, they're meant to be in RP even though we've sent
- # nothing
- assertEquals([remote_handle], group_props['RemotePendingMembers'])
- else:
- # For an anonymous channel, the peer isn't yet known; for a Create-d
- # channel, the peer only appears in RP when we actually send them the
- # session-initiate
- assertEquals([], group_props['RemotePendingMembers'])
-
- if variant == REQUEST_ANONYMOUS_AND_ADD:
- # but we should be allowed to add the peer.
- chan.Group.AddMembers([remote_handle], 'I love backwards compat')
-
- base_flags = cs.GF_MEMBERS_CHANGED_DETAILED | cs.GF_PROPERTIES | cs.GF_MESSAGE_REMOVE \
- | cs.GF_MESSAGE_REJECT | cs.GF_MESSAGE_RESCIND
-
- if variant == REQUEST_ANONYMOUS_AND_ADD or variant == REQUEST_ANONYMOUS:
- expected_flags = base_flags | cs.GF_CAN_ADD
- else:
- expected_flags = base_flags
- assertEquals(expected_flags, group_props['GroupFlags'])
- assertEquals({}, group_props['HandleOwners'])
-
- assertEquals([], chan.StreamedMedia.ListStreams())
- streams = chan.StreamedMedia.RequestStreams(remote_handle,
- [cs.MEDIA_STREAM_TYPE_AUDIO])
- assertEquals(streams, chan.StreamedMedia.ListStreams())
- assertLength(1, streams)
-
- # streams[0][0] is the stream identifier, which in principle we can't
- # make any assertion about (although in practice it's probably 1)
-
- assertEquals((
- remote_handle,
- cs.MEDIA_STREAM_TYPE_AUDIO,
- # We haven't connected yet
- cs.MEDIA_STREAM_STATE_DISCONNECTED,
- # In Gabble, requested streams start off bidirectional
- cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL,
- 0),
- streams[0][1:])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", jt2.get_remote_transports_dbus())
- stream_handler.Ready(jt2.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- sh_props = stream_handler.GetAll(
- cs.STREAM_HANDLER, dbus_interface=dbus.PROPERTIES_IFACE)
- assertEquals('gtalk-p2p', sh_props['NATTraversal'])
- assertEquals(True, sh_props['CreatedLocally'])
-
- if variant == CREATE:
- # When we actually send XML to the peer, they should pop up in remote
- # pending.
- session_initiate, _ = q.expect_many(
- EventPattern('stream-iq', iq_type='set', predicate=lambda e:
- jp.match_jingle_action(e.query, 'session-initiate')),
- EventPattern('dbus-signal', signal='MembersChanged',
- args=["", [], [], [], [remote_handle], self_handle,
- cs.GC_REASON_INVITED]),
- )
- else:
- forbidden = []
-
- if peer.split('/', 1)[0] in (
- 'publish@foo.com', 'publish-subscribe@foo.com'):
- forbidden = [EventPattern('stream-presence')]
- q.forbid_events(forbidden)
- else:
- # we're calling someone not on our roster, so we'll send directed
- # presence first
- presence = q.expect('stream-presence')
- assert (xpath.queryForNodes('/presence/c', presence.stanza)
- is not None)
- assert (xpath.queryForNodes(
- '/presence/x[@xmlns="vcard-temp:x:update"]', presence.stanza)
- is not None)
-
- session_initiate = q.expect('stream-iq',
- predicate=jp.action_predicate('session-initiate'))
-
- if forbidden:
- q.unforbid_events(forbidden)
-
- jt2.parse_session_initiate(session_initiate.query)
- stream.send(jp.xml(jp.ResultIq('test@localhost', session_initiate.stanza,
- [])))
-
- # Check the Group interface's properties again. Regardless of the call
- # requesting API in use, the state should be the same here:
- group_props = chan.Properties.GetAll(cs.CHANNEL_IFACE_GROUP)
- assertContains('HandleOwners', group_props)
- assertEquals([self_handle], group_props['Members'])
- assertEquals([], group_props['LocalPendingMembers'])
- assertEquals([remote_handle], group_props['RemotePendingMembers'])
-
- if jp.dialect == 'gtalk-v0.4':
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'transport-accept', [
- jp.TransportGoogleP2P() ]) ])
- stream.send(jp.xml(node))
-
- # FIXME: expect transport-info, then if we're gtalk3, send
- # candidates, and check that gabble resends transport-info as
- # candidates
- jt2.accept()
-
- q.expect_many(
- EventPattern('stream-iq', iq_type='result'),
- # Call accepted
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [remote_handle], [], [], [], remote_handle,
- cs.GC_REASON_NONE]),
- )
-
- # Time passes ... afterwards we close the chan
-
- chan.Group.RemoveMembers([self_handle], 'closed')
-
- # Make sure gabble sends proper terminate action
- if jp.dialect.startswith('gtalk'):
- terminate = EventPattern('stream-iq', predicate=lambda x:
- xpath.queryForNodes("/iq/session[@type='terminate']",
- x.stanza))
- else:
- terminate = EventPattern('stream-iq', predicate=lambda x:
- xpath.queryForNodes("/iq/jingle[@action='session-terminate']",
- x.stanza))
-
- mc_event, _, _ = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged'),
- EventPattern('dbus-signal', signal='Close'),
- terminate,
- )
- # Check that we're the actor
- assertEquals(self_handle, mc_event.args[5])
-
-def rccs(q, bus, conn, stream):
- """
- Tests that the connection's RequestableChannelClasses for StreamedMedia are
- sane.
- """
- rccs = conn.Properties.Get(cs.CONN_IFACE_REQUESTS,
- 'RequestableChannelClasses')
-
- # Test Channel.Type.StreamedMedia
- media_classes = [ rcc for rcc in rccs
- if rcc[0][cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAMED_MEDIA ]
-
- assertLength(1, media_classes)
-
- fixed, allowed = media_classes[0]
-
- assertEquals(cs.HT_CONTACT, fixed[cs.TARGET_HANDLE_TYPE])
-
- expected_allowed = [
- cs.TARGET_ID, cs.TARGET_HANDLE,
- cs.INITIAL_VIDEO, cs.INITIAL_AUDIO
- ]
-
- allowed.sort()
- expected_allowed.sort()
- assertEquals(expected_allowed, allowed)
-
- # Test Channel.Type.Call
- media_classes = [ rcc for rcc in rccs
- if rcc[0][cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_CALL ]
- assertLength(2, media_classes)
-
- hts = []
-
- for mc in media_classes:
- fixed, allowed = mc
-
- hts.append (fixed[cs.TARGET_HANDLE_TYPE])
-
- expected_allowed = [
- cs.TARGET_ID, cs.TARGET_HANDLE,
- cs.CALL_INITIAL_VIDEO, cs.CALL_INITIAL_AUDIO,
- cs.CALL_INITIAL_VIDEO_NAME, cs.CALL_INITIAL_AUDIO_NAME,
- cs.CALL_MUTABLE_CONTENTS
- ]
-
- allowed.sort()
- expected_allowed.sort()
- assertEquals(expected_allowed, allowed)
-
- assertEquals(sorted([cs.HT_CONTACT, cs.HT_ROOM]), sorted(hts))
-
-if __name__ == '__main__':
- exec_test(rccs)
- test_all_dialects(create)
- test_all_dialects(request_anonymous)
- test_all_dialects(request_anonymous_and_add)
- test_all_dialects(request_nonymous)
- test_all_dialects(partial(create, peer='foo@gw.bar.com'))
- test_all_dialects(partial(request_anonymous, peer='foo@gw.bar.com'))
- test_all_dialects(partial(request_anonymous_and_add, peer='foo@gw.bar.com'))
- test_all_dialects(partial(request_nonymous, peer='foo@gw.bar.com'))
diff --git a/tests/twisted/jingle/outgoing-ensure.py b/tests/twisted/jingle/outgoing-ensure.py
deleted file mode 100644
index a5bab23c7..000000000
--- a/tests/twisted/jingle/outgoing-ensure.py
+++ /dev/null
@@ -1,217 +0,0 @@
-"""
-Test making outgoing calls using EnsureChannel, and retrieving existing calls
-using EnsureChannel.
-
-This also exercises calls to a contact on a SIP gateway, who has no resource,
-only a bare JID.
-"""
-
-from functools import partial
-from gabbletest import exec_test
-from servicetest import (
- wrap_channel,
- call_async, EventPattern,
- assertEquals, assertLength,
- )
-import constants as cs
-from jingletest2 import JingleProtocol031, JingleTest2
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(q, bus, conn, stream, channel_type):
- jt = JingleTest2(JingleProtocol031(), conn, q, stream, 'test@localhost',
- 'foo@sip.bar.com')
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]
-
- request = { cs.CHANNEL_TYPE: channel_type,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_HANDLE: handle}
-
- if channel_type == cs.CHANNEL_TYPE_CALL:
- request[cs.CALL_INITIAL_AUDIO] = True
-
- # Ensure a channel that doesn't exist yet.
- call_async(q, conn.Requests, 'EnsureChannel', request)
-
- ret, old_sig, new_sig = q.expect_many(
- EventPattern('dbus-return', method='EnsureChannel'),
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewChannels',
- predicate=lambda e:
- cs.CHANNEL_TYPE_CONTACT_LIST not in e.args[0][0][1].values()),
- )
-
- yours, path, props = ret.value
-
- # this channel was created in response to our EnsureChannel call, so it
- # should be ours.
- assert yours, ret.value
-
- sig_path, sig_ct, sig_ht, sig_h, sig_sh = old_sig.args
-
- assertEquals(sig_path, path)
- assertEquals(channel_type, sig_ct)
- assertEquals(cs.HT_CONTACT, sig_ht)
- assertEquals(handle, sig_h)
- assert sig_sh # suppress handler
-
- assertLength(1, new_sig.args)
- assertLength(1, new_sig.args[0]) # one channel
- assertLength(2, new_sig.args[0][0]) # two struct members
- assertEquals(path, new_sig.args[0][0][0])
- emitted_props = new_sig.args[0][0][1]
-
- assertEquals(channel_type, emitted_props[cs.CHANNEL_TYPE])
- assertEquals(cs.HT_CONTACT, emitted_props[cs.TARGET_HANDLE_TYPE])
- assertEquals(handle, emitted_props[cs.TARGET_HANDLE])
- assertEquals(jt.peer_bare_jid, emitted_props[cs.TARGET_ID])
- assert emitted_props[cs.REQUESTED]
- assertEquals(self_handle, emitted_props[cs.INITIATOR_HANDLE])
- assertEquals('test@localhost', emitted_props[cs.INITIATOR_ID])
-
- # Now ensure a media channel with the same contact, and check it's the
- # same.
- call_async(q, conn.Requests, 'EnsureChannel', request)
-
- event = q.expect('dbus-return', method='EnsureChannel')
- yours2, path2, props2 = event.value
-
- # We should have got back the same channel we created a page or so ago.
- assertEquals(path2, path)
- # It's not been created for this call, so Yours should be False.
- assert not yours2
-
- # Time passes ... afterwards we close the chan
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia')
- chan.Close()
-
-
- # Ensure a channel that doesn't exist yet.
- call_async(q, conn.Requests, 'EnsureChannel', request)
-
- # Re-ensure a channel that is hopefully still pending creation.
- call_async(q, conn.Requests, 'EnsureChannel', request)
-
- ret, ret2, old_sig, new_sig = q.expect_many(
- EventPattern('dbus-return', method='EnsureChannel'),
- EventPattern('dbus-return', method='EnsureChannel'),
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewChannels',
- predicate=lambda e:
- cs.CHANNEL_TYPE_CONTACT_LIST not in e.args[0][0][1].values()),
- )
-
- yours, path, props = ret.value
-
- # this channel was created in response to our EnsureChannel call, so it
- # should be ours.
- assert yours, ret.value
-
- sig_path, sig_ct, sig_ht, sig_h, sig_sh = old_sig.args
-
- assertEquals(sig_path, path)
- assertEquals(channel_type, sig_ct)
- assertEquals(cs.HT_CONTACT, sig_ht)
- assertEquals(handle, sig_h)
- assert sig_sh # suppress handler
-
- assertLength(1, new_sig.args)
- assertLength(1, new_sig.args[0]) # one channel
- assertLength(2, new_sig.args[0][0]) # two struct members
- assertEquals(path, new_sig.args[0][0][0])
- emitted_props = new_sig.args[0][0][1]
-
- assertEquals(channel_type, emitted_props[cs.CHANNEL_TYPE])
- assertEquals(cs.HT_CONTACT, emitted_props[cs.TARGET_HANDLE_TYPE])
- assertEquals(handle, emitted_props[cs.TARGET_HANDLE])
- assertEquals(jt.peer_bare_jid, emitted_props[cs.TARGET_ID])
- assert emitted_props[cs.REQUESTED]
- assertEquals(self_handle, emitted_props[cs.INITIATOR_HANDLE])
- assertEquals('test@localhost', emitted_props[cs.INITIATOR_ID])
-
- yours2, path2, props2 = ret2.value
-
- # We should have got back the same channel we created a page or so ago.
- assertEquals(path2, path)
- # It's not been created for this call, so Yours should be False.
- assert not yours2
-
- # Time passes ... afterwards we close the chan
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia')
- chan.Close()
-
-
- # The remaining checks don't apply to calls
- if channel_type == cs.CHANNEL_TYPE_CALL:
- return
-
- # Now, create an anonymous channel with RequestChannel, add the other
- # person to it with RequestStreams, then Ensure a media channel with that
- # person. We should get the anonymous channel back.
- call_async(
- q, conn, 'RequestChannel', channel_type, 0, 0, True)
-
- ret, old_sig, new_sig = q.expect_many(
- EventPattern('dbus-return', method='RequestChannel'),
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewChannels',
- predicate=lambda e:
- cs.CHANNEL_TYPE_CONTACT_LIST not in e.args[0][0][1].values()),
- )
-
- path = ret.value[0]
- assertEquals(
- [path, channel_type, cs.HT_NONE, 0, True],
- old_sig.args)
-
- assertLength(1, new_sig.args)
- assertLength(1, new_sig.args[0]) # one channel
- assertLength(2, new_sig.args[0][0]) # two struct members
- assertEquals(path, new_sig.args[0][0][0])
- emitted_props = new_sig.args[0][0][1]
-
- assertEquals(channel_type, emitted_props[cs.CHANNEL_TYPE])
- assertEquals(cs.HT_NONE, emitted_props[cs.TARGET_HANDLE_TYPE])
- assertEquals(0, emitted_props[cs.TARGET_HANDLE])
- assertEquals('', emitted_props[cs.TARGET_ID])
- assert emitted_props[cs.REQUESTED]
- assertEquals(self_handle, emitted_props[cs.INITIATOR_HANDLE])
- assertEquals('test@localhost', emitted_props[cs.INITIATOR_ID])
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia')
-
- # Request streams with the other person. This should make them the
- # channel's "peer" property.
- chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- # Now, Ensuring a media channel with handle should yield the channel just
- # created.
-
- call_async(q, conn.Requests, 'EnsureChannel', request)
-
- event = q.expect('dbus-return', method='EnsureChannel')
- yours, path2, _ = event.value
-
- # we should have got back the anonymous channel we got with requestchannel
- # and called RequestStreams(handle) on.
- assertEquals(path2, path)
- # It's not been created for this call, so Yours should be False.
- assert not yours
-
- chan.Close()
-
-if __name__ == '__main__':
- exec_test(partial(test, channel_type=cs.CHANNEL_TYPE_STREAMED_MEDIA))
- exec_test(partial(test, channel_type=cs.CHANNEL_TYPE_CALL))
diff --git a/tests/twisted/jingle/outgoing-many-streams.py b/tests/twisted/jingle/outgoing-many-streams.py
deleted file mode 100644
index b93ce616c..000000000
--- a/tests/twisted/jingle/outgoing-many-streams.py
+++ /dev/null
@@ -1,221 +0,0 @@
-
-"""
-Test making outgoing call using CreateChannel. This tests the happy scenario
-when the remote party accepts the call.
-"""
-
-import dbus
-
-from gabbletest import exec_test, sync_stream
-from servicetest import (
- make_channel_proxy, call_async, EventPattern)
-import jingletest2
-import gabbletest
-
-import constants as cs
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(q, bus, conn, stream):
- worker(q, bus, conn, stream, 'foo@bar.com/Foo')
- worker(q, bus, conn, stream, 'foo@sip.bar.com')
-
-def worker(q, bus, conn, stream, peer):
- jp = jingletest2.JingleProtocol031()
- jt = jingletest2.JingleTest2(jp, conn, q, stream, 'test@localhost', peer)
-
- self_handle = conn.GetSelfHandle()
- jt.send_presence_and_caps()
-
- handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]
-
- call_async(q, conn.Requests, 'CreateChannel',
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_HANDLE: handle,
- })
-
- ret, old_sig, new_sig = q.expect_many(
- EventPattern('dbus-return', method='CreateChannel'),
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewChannels',
- predicate=lambda e:
- cs.CHANNEL_TYPE_CONTACT_LIST not in e.args[0][0][1].values()),
- )
-
- path = ret.value[0]
-
- sig_path, sig_ct, sig_ht, sig_h, sig_sh = old_sig.args
-
- assert sig_path == path, (sig_path, path)
- assert sig_ct == cs.CHANNEL_TYPE_STREAMED_MEDIA, sig_ct
- assert sig_ht == cs.HT_CONTACT, sig_ht
- assert sig_h == handle, sig_h
- assert sig_sh == True # suppress handler
-
- assert len(new_sig.args) == 1
- assert len(new_sig.args[0]) == 1 # one channel
- assert len(new_sig.args[0][0]) == 2 # two struct members
- assert new_sig.args[0][0][0] == path
- emitted_props = new_sig.args[0][0][1]
-
- assert emitted_props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAMED_MEDIA
- assert emitted_props[cs.TARGET_HANDLE_TYPE] == cs.HT_CONTACT
- assert emitted_props[cs.TARGET_HANDLE] == handle
- assert emitted_props[cs.TARGET_ID] == jt.peer_bare_jid, emitted_props
- assert emitted_props[cs.REQUESTED] == True
- assert emitted_props[cs.INITIATOR_HANDLE] == self_handle
- assert emitted_props[cs.INITIATOR_ID] == 'test@localhost'
-
- signalling_iface = make_channel_proxy(conn, path, 'Channel.Interface.MediaSignalling')
- media_iface = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')
- group_iface = make_channel_proxy(conn, path, 'Channel.Interface.Group')
-
- # Exercise basic Channel Properties from spec 0.17.7
- channel_props = group_iface.GetAll(cs.CHANNEL,
- dbus_interface=dbus.PROPERTIES_IFACE)
- assert channel_props.get('TargetHandle') == handle, \
- channel_props.get('TargetHandle')
- assert channel_props.get('TargetHandleType') == cs.HT_CONTACT,\
- channel_props.get('TargetHandleType')
- assert media_iface.GetHandle(dbus_interface=cs.CHANNEL) == (cs.HT_CONTACT,
- handle)
- assert channel_props.get('ChannelType') == cs.CHANNEL_TYPE_STREAMED_MEDIA,\
- channel_props.get('ChannelType')
-
- interfaces = channel_props['Interfaces']
- for i in [cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_MEDIA_SIGNALLING,
- cs.TP_AWKWARD_PROPERTIES, cs.CHANNEL_IFACE_HOLD]:
- assert i in interfaces, (i, interfaces)
-
- assert channel_props['TargetID'] == jt.peer_bare_jid, channel_props
- assert channel_props['Requested'] == True
- assert channel_props['InitiatorID'] == 'test@localhost'
- assert channel_props['InitiatorHandle'] == self_handle
-
- # Exercise Group Properties from spec 0.17.6 (in a basic way)
- group_props = group_iface.GetAll(cs.CHANNEL_IFACE_GROUP,
- dbus_interface=dbus.PROPERTIES_IFACE)
- assert 'HandleOwners' in group_props, group_props
- assert 'Members' in group_props, group_props
- assert 'LocalPendingMembers' in group_props, group_props
- assert 'RemotePendingMembers' in group_props, group_props
- assert 'GroupFlags' in group_props, group_props
-
- # The remote contact shouldn't be in remote pending yet (nor should it be
- # in members!)
- assert handle not in group_props['RemotePendingMembers'], group_props
- assert handle not in group_props['Members'], group_props
-
- list_streams_result = media_iface.ListStreams()
- assert len(list_streams_result) == 0, list_streams_result
-
- # Asking for 4 audio and 3 video streams is pathological, but we claim to
- # support up to 99 streams, so we should test a decent number of them.
- #
- # More practically, the success of this test implies that the simpler case
- # of one audio stream and one video stream should easily work.
- streams = media_iface.RequestStreams(handle,
- [cs.MEDIA_STREAM_TYPE_AUDIO,
- cs.MEDIA_STREAM_TYPE_VIDEO,
- cs.MEDIA_STREAM_TYPE_VIDEO,
- cs.MEDIA_STREAM_TYPE_AUDIO,
- cs.MEDIA_STREAM_TYPE_AUDIO,
- cs.MEDIA_STREAM_TYPE_VIDEO,
- cs.MEDIA_STREAM_TYPE_AUDIO])
- assert len(streams) == 7, streams
-
- streams_by_id = {}
-
- for s in streams:
- streams_by_id[s[0]] = s
-
- assert len(s) == 6, s
- assert s[1] == handle, (s, handle)
- assert s[2] in (cs.MEDIA_STREAM_TYPE_AUDIO,
- cs.MEDIA_STREAM_TYPE_VIDEO), s
- # We haven't connected yet
- assert s[3] == cs.MEDIA_STREAM_STATE_DISCONNECTED, s
- # In Gabble, requested streams start off bidirectional
- assert s[4] == cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL, s
- assert s[5] == 0, s # no pending send
-
- # the streams should all have unique IDs
- stream_ids = streams_by_id.keys()
- assert len(stream_ids) == 7
-
- # the streams should come out in the same order as the requests
- assert streams[0][2] == cs.MEDIA_STREAM_TYPE_AUDIO, streams[0]
- assert streams[1][2] == cs.MEDIA_STREAM_TYPE_VIDEO, streams[0]
- assert streams[2][2] == cs.MEDIA_STREAM_TYPE_VIDEO, streams[0]
- assert streams[3][2] == cs.MEDIA_STREAM_TYPE_AUDIO, streams[0]
- assert streams[4][2] == cs.MEDIA_STREAM_TYPE_AUDIO, streams[0]
- assert streams[5][2] == cs.MEDIA_STREAM_TYPE_VIDEO, streams[0]
- assert streams[6][2] == cs.MEDIA_STREAM_TYPE_AUDIO, streams[0]
-
- # The ListStreams() result must be the streams we got from RequestStreams,
- # but this time the order is unimportant
- list_streams_result = media_iface.ListStreams()
- listed_streams_by_id = {}
-
- for s in list_streams_result:
- listed_streams_by_id[s[0]] = s
-
- assert listed_streams_by_id == streams_by_id, (listed_streams_by_id,
- streams_by_id)
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler_path = e.args[0]
- session_handler = make_channel_proxy(conn, session_handler_path,
- 'Media.SessionHandler')
- session_handler.Ready()
-
- stream_handler_paths = []
-
- # give all 7 streams some candidates
- for i in xrange(7):
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_handler_paths.append(e.args[0])
- stream_handler = make_channel_proxy(conn, e.args[0],
- 'Media.StreamHandler')
- stream_handler.NewNativeCandidate("fake",
- jt.get_remote_transports_dbus())
- stream_handler.Ready(jt.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq')
- assert e.query.name == 'jingle'
- assert e.query['action'] == 'session-initiate'
- stream.send(gabbletest.make_result_iq(stream, e.stanza))
- jt.parse_session_initiate(e.query)
-
- jt.accept()
-
- q.expect('stream-iq', iq_type='result')
-
- # Time passes ... afterwards we close the chan
-
- group_iface.RemoveMembers([self_handle], 'closed')
-
- # Everything closes
- closes = [ EventPattern('dbus-signal', signal='Close',
- path=stream_handler_paths[i])
- for i in range(0,7) ]
- removeds = [ EventPattern('dbus-signal', signal='StreamRemoved',
- args=[stream_ids[i]], path=path)
- for i in range(0,7) ]
- q.expect_many(
- EventPattern('dbus-signal', signal='ChannelClosed', args=[path]),
- *(closes + removeds)
- )
-
-if __name__ == '__main__':
- exec_test(test)
diff --git a/tests/twisted/jingle/payload-types.py b/tests/twisted/jingle/payload-types.py
deleted file mode 100644
index 64a300ff1..000000000
--- a/tests/twisted/jingle/payload-types.py
+++ /dev/null
@@ -1,108 +0,0 @@
-"""
-Regression test for https://bugs.freedesktop.org/show_bug.cgi?id=18918
-"""
-
-import dbus
-
-from gabbletest import exec_test
-from servicetest import wrap_channel, make_channel_proxy
-import jingletest2
-import constants as cs
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(q, bus, conn, stream):
- jp = jingletest2.JingleProtocol031()
- jt = jingletest2.JingleTest2(jp, conn, q, stream, 'test@localhost',
- 'foo@bar.com/Foo')
-
- self_handle = conn.GetSelfHandle()
-
- jt.send_presence_and_caps()
-
- handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]
- path = conn.RequestChannel(
- cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.HT_CONTACT, handle, True)
-
- channel = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia')
-
- # Test that codec parameters are correctly sent in <parameter> children of
- # <payload-type> rather than as attributes of the latter.
-
- channel.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_id = e.args[1]
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
-
- codecs = dbus.Array( [ (96, 'speex', 0, 16000, 0, {'vbr': 'on'}) ],
- signature='(usuuua{ss})')
- stream_handler.Ready(codecs)
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq')
- content = list(e.query.elements())[0]
- assert content.name == 'content'
- for child in content.elements():
- if child.name == 'description':
- description = child
- break
- assert description is not None
-
- # there should be one <payload-type> tag for speex:
- assert len(list(description.elements())) == 1
- payload_type = list(description.elements())[0]
- assert payload_type.name == 'payload-type'
- assert payload_type['name'] == 'speex'
-
- # the vbr parameter should not be an attribute on the <payload-type>, but
- # a child <parameter/> tag
- assert 'vbr' not in payload_type.attributes
- assert len(list(payload_type.elements())) == 1
- parameter = list(payload_type.elements())[0]
- assert parameter.name == 'parameter'
- assert parameter['name'] == 'vbr'
- assert parameter['value'] == 'on'
-
- channel.Close()
-
-
- # Test that codec parameters are correctly extracted from <parameter>
- # children of <payload-type> rather than from attributes of the latter.
-
- jt.audio_codecs = [ ('GSM', 3, 8000, {'misc': 'other'}) ]
- jt.incoming_call()
-
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_id = e.args[1]
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
- stream_handler.Ready( dbus.Array( [], signature='(usuuua{ss})'))
-
- e = q.expect('dbus-signal', signal='SetRemoteCodecs')
- for codec in e.args[0]:
- id, name, type, rate, channels, parameters = codec
- assert len(parameters) == 1, parameters
- assert parameters['misc'] == 'other', parameters
-
-if __name__ == '__main__':
- exec_test(test)
diff --git a/tests/twisted/jingle/session-id-collision.py b/tests/twisted/jingle/session-id-collision.py
index 724537fe0..b9815407b 100644
--- a/tests/twisted/jingle/session-id-collision.py
+++ b/tests/twisted/jingle/session-id-collision.py
@@ -27,14 +27,14 @@ def test(jp, q, bus, conn, stream):
jt2.sid = '1'
jt1.incoming_call()
- q.expect('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args)
+ q.expect('dbus-signal', signal='NewChannels',
+ predicate=lambda e: cs.CHANNEL_TYPE_CALL in e.args[0][0][1][cs.CHANNEL_TYPE])
# If Gabble confuses the two sessions, it'll NAK the IQ rather than
# realising this is a new call.
jt2.incoming_call()
- q.expect('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args)
+ q.expect('dbus-signal', signal='NewChannels',
+ predicate=lambda e: cs.CHANNEL_TYPE_CALL in e.args[0][0][1][cs.CHANNEL_TYPE])
# On the other hand, if the same person calls twice with the same sid,
# Gabble _should_ NAK the second s-i.
diff --git a/tests/twisted/jingle/stream-errors-on-content-reject.py b/tests/twisted/jingle/stream-errors-on-content-reject.py
deleted file mode 100644
index 404373c72..000000000
--- a/tests/twisted/jingle/stream-errors-on-content-reject.py
+++ /dev/null
@@ -1,246 +0,0 @@
-"""
-Test StreamError events when new content is rejected in-call.
-"""
-
-import dbus
-
-from gabbletest import make_result_iq, sync_stream, exec_test
-from servicetest import (
- make_channel_proxy, unwrap, EventPattern, assertEquals, assertLength)
-from jingletest2 import JingleTest2, JingleProtocol031
-import constants as cs
-
-from twisted.words.xish import xpath
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def _content_reject_predicate(event):
- reason = xpath.queryForNodes("/iq"
- "/jingle[@action='content-reject']"
- "/reason/failed-application",
- event.stanza)
-
- return bool(reason)
-
-def _start_audio_session(jp, q, bus, conn, stream, incoming):
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', 'foo@bar.com/Foo')
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]
-
- if incoming:
- jt.incoming_call()
- else:
- ret = conn.Requests.CreateChannel(
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_HANDLE: remote_handle,
- cs.INITIAL_AUDIO: True
- })
-
- nc, e = q.expect_many(
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewSessionHandler'))
-
- path = nc.args[0]
-
- media_chan = make_channel_proxy(conn, path, 'Channel.Interface.Group')
- media_iface = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')
-
- # S-E was notified about new session handler, and calls Ready on it
- session_handler = make_channel_proxy(conn, e.args[0],
- 'Media.SessionHandler')
- session_handler.Ready()
-
- nsh_event = q.expect('dbus-signal', signal='NewStreamHandler')
-
- # S-E gets notified about a newly-created stream
- stream_handler = make_channel_proxy(conn, nsh_event.args[0],
- 'Media.StreamHandler')
-
- group_props = media_chan.GetAll(
- cs.CHANNEL_IFACE_GROUP, dbus_interface=dbus.PROPERTIES_IFACE)
-
- if incoming:
- assertEquals([remote_handle], group_props['Members'])
- assertEquals(unwrap(group_props['LocalPendingMembers']),
- [(self_handle, remote_handle, cs.GC_REASON_INVITED, '')])
- else:
- assertEquals([self_handle], group_props['Members'])
-
- streams = media_chan.ListStreams(
- dbus_interface=cs.CHANNEL_TYPE_STREAMED_MEDIA)
-
- stream_id = streams[0][0]
-
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler.Ready(jt.dbusify_codecs([("FOO", 5, 8000, {})]))
-
- msg = u"None of the codecs are good for us, damn!"
-
- expected_events = []
-
- if incoming:
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
- stream_handler.SupportedCodecs(jt.get_audio_codecs_dbus())
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('transport-info'))
- assertEquals(jt.peer, e.query['initiator'])
- content = xpath.queryForNodes('/iq/jingle/content', e.stanza)[0]
- assertEquals('initiator', content['creator'])
-
- stream.send(make_result_iq(stream, e.stanza))
-
- media_chan.AddMembers([self_handle], 'accepted')
-
- memb, acc, _, _, _ = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [self_handle], [], [], [], self_handle,
- cs.GC_REASON_NONE]),
- EventPattern('stream-iq',
- predicate=jp.action_predicate('session-accept')),
- EventPattern('dbus-signal', signal='SetStreamSending',
- args=[True]),
- EventPattern('dbus-signal', signal='SetStreamPlaying',
- args=[True]),
- EventPattern('dbus-signal', signal='StreamDirectionChanged',
- args=[stream_id,
- cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL, 0]))
-
- stream.send(make_result_iq(stream, acc.stanza))
-
- active_event = jp.rtp_info_event("active")
- if active_event is not None:
- q.expect_many(active_event)
-
- members = media_chan.GetMembers()
- assert set(members) == set([self_handle, remote_handle]), members
- else:
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
- session_initiate = q.expect(
- 'stream-iq',
- predicate=jp.action_predicate('session-initiate'))
-
- q.expect('dbus-signal', signal='MembersChanged', path=path,
- args=['', [], [], [], [remote_handle], self_handle,
- cs.GC_REASON_INVITED])
-
- jt.parse_session_initiate(session_initiate.query)
- stream.send(jp.xml(jp.ResultIq('test@localhost',
- session_initiate.stanza, [])))
-
- jt.accept()
-
- q.expect_many(
- EventPattern('stream-iq', iq_type='result'),
- # Call accepted
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [remote_handle], [], [], [], remote_handle,
- cs.GC_REASON_NONE]),
- )
- return jt, media_iface
-
-def _start_audio_session_outgoing(jp, q, bus, conn, stream):
- return _start_audio_session(jp, q, bus, conn, stream, False)
-
-def _start_audio_session_incoming(jp, q, bus, conn, stream):
- return _start_audio_session(jp, q, bus, conn, stream, True)
-
-def _remote_content_add(jp, q, bus, conn, stream, initiate_call_func):
- jt, chan = initiate_call_func(jp, q, bus, conn, stream)
-
- video_codecs = [
- jp.PayloadType(name, str(rate), str(id), parameters) \
- for (name, id, rate, parameters) in jt.video_codecs]
-
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.peer, 'content-add', [
- jp.Content(
- 'videostream', 'initiator', 'both',
- jp.Description('video', video_codecs),
- jp.TransportGoogleP2P()) ]) ])
- stream.send(jp.xml(node))
-
- _, nsh = q.expect_many(
- EventPattern('dbus-signal', signal='StreamAdded'),
- EventPattern('dbus-signal', signal='NewStreamHandler'))
-
- stream_handler_path, stream_id, media_type, direction = nsh.args
-
- video_handler = make_channel_proxy(conn, stream_handler_path,
- 'Media.StreamHandler')
-
- video_handler.NewNativeCandidate("fake",
- jt.get_remote_transports_dbus())
- video_handler.Ready(jt.dbusify_codecs([("FOO", 5, 8000, {})]))
-
- msg = u"None of the codecs are good for us, damn!"
-
- video_handler.Error(cs.MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED, msg)
-
- q.expect_many(
- EventPattern('dbus-signal', signal='StreamError',
- args=[stream_id,
- cs.MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED,
- msg]),
- EventPattern('stream-iq', predicate=_content_reject_predicate))
-
-def _local_content_add(jp, q, bus, conn, stream, initiate_call_func):
- jt, chan = initiate_call_func(jp, q, bus, conn, stream)
-
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]
-
- chan.RequestStreams(remote_handle, [cs.MEDIA_STREAM_TYPE_VIDEO])
-
- nsh = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_handler_path, stream_id, media_type, direction = nsh.args
- video_handler = make_channel_proxy(conn, stream_handler_path,
- 'Media.StreamHandler')
-
- video_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- video_handler.Ready(jt.get_audio_codecs_dbus())
- video_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('content-add'))
- c = e.query.firstChildElement()
- stream.send(make_result_iq(stream, e.stanza))
-
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.peer, 'content-reject', [
- ('reason', None, {}, [
- ('failed-application', None, {}, [])]),
- jp.Content(c['name'], c['creator'], c['senders']) ]) ])
- stream.send(jp.xml(node))
-
- q.expect('dbus-signal', signal='StreamError',
- args=[stream_id,
- cs.MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED,
- ""]),
-
-def test_remote_content_add_incoming(jp, q, bus, conn, stream):
- _remote_content_add(jp, q, bus, conn, stream,
- _start_audio_session_incoming)
-
-def test_remote_content_add_outgoing(jp, q, bus, conn, stream):
- _remote_content_add(jp, q, bus, conn, stream,
- _start_audio_session_outgoing)
-
-def test_local_content_add_incoming(jp, q, bus, conn, stream):
- _local_content_add(jp, q, bus, conn, stream, _start_audio_session_incoming)
-
-def test_local_content_add_outgoing(jp, q, bus, conn, stream):
- _local_content_add(jp, q, bus, conn, stream, _start_audio_session_outgoing)
-
-if __name__ == '__main__':
- for f in (test_local_content_add_incoming,
- test_local_content_add_outgoing,
- test_remote_content_add_incoming,
- test_remote_content_add_outgoing):
- exec_test(
- lambda q, b, c, s: f(JingleProtocol031(), q, b, c, s))
diff --git a/tests/twisted/jingle/stream-errors-on-terminate.py b/tests/twisted/jingle/stream-errors-on-terminate.py
deleted file mode 100644
index 2fc403cd5..000000000
--- a/tests/twisted/jingle/stream-errors-on-terminate.py
+++ /dev/null
@@ -1,140 +0,0 @@
-"""
-Test StreamError events and on session terminate, both directions.
-"""
-
-import dbus
-
-from gabbletest import make_result_iq, sync_stream, exec_test
-from servicetest import (
- make_channel_proxy, unwrap, EventPattern, assertEquals, assertLength)
-from jingletest2 import JingleTest2, JingleProtocol031
-import constants as cs
-
-from twisted.words.xish import xpath
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def _session_terminate_predicate(event, msg):
- reason = xpath.queryForNodes("/iq"
- "/jingle[@action='session-terminate']"
- "/reason/failed-application",
- event.stanza)
- reason_text = xpath.queryForString("/iq/jingle/reason/text",
- event.stanza)
-
- return reason is not None and reason_text == msg
-
-def _test_terminate_reason(jp, q, bus, conn, stream, incoming):
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', 'foo@bar.com/Foo')
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]
-
- if incoming:
- jt.incoming_call()
- else:
- ret = conn.Requests.CreateChannel(
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_HANDLE: remote_handle,
- cs.INITIAL_AUDIO: True
- })
-
- nc, e = q.expect_many(
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewSessionHandler'))
-
- path = nc.args[0]
-
- media_chan = make_channel_proxy(conn, path, 'Channel.Interface.Group')
- media_iface = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')
-
- # S-E was notified about new session handler, and calls Ready on it
- session_handler = make_channel_proxy(conn, e.args[0],
- 'Media.SessionHandler')
- session_handler.Ready()
-
- nsh_event = q.expect('dbus-signal', signal='NewStreamHandler')
-
- # S-E gets notified about a newly-created stream
- stream_handler = make_channel_proxy(conn, nsh_event.args[0],
- 'Media.StreamHandler')
-
- group_props = media_chan.GetAll(
- cs.CHANNEL_IFACE_GROUP, dbus_interface=dbus.PROPERTIES_IFACE)
-
- if incoming:
- assertEquals([remote_handle], group_props['Members'])
- assertEquals(unwrap(group_props['LocalPendingMembers']),
- [(self_handle, remote_handle, cs.GC_REASON_INVITED, '')])
- else:
- assertEquals([self_handle], group_props['Members'])
-
- streams = media_chan.ListStreams(
- dbus_interface=cs.CHANNEL_TYPE_STREAMED_MEDIA)
-
- stream_id = streams[0][0]
-
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler.Ready(jt.dbusify_codecs([("FOO", 5, 8000, {})]))
-
- msg = u"None of the codecs are good for us, damn!"
-
- expected_events = []
-
- if incoming:
- q.expect('dbus-signal', signal='SetRemoteCodecs')
- stream_handler.Error(cs.MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED,
- msg)
- expected_events = [EventPattern(
- "stream-iq", iq_type="set",
- predicate=lambda x: _session_terminate_predicate(x, msg))]
- rejector = self_handle
- else:
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
- session_initiate = q.expect(
- 'stream-iq',
- predicate=jp.action_predicate('session-initiate'))
-
- q.expect('dbus-signal', signal='MembersChanged', path=path,
- args=['', [], [], [], [remote_handle], self_handle,
- cs.GC_REASON_INVITED])
-
- jt.parse_session_initiate(session_initiate.query)
- stream.send(jp.xml(jp.ResultIq('test@localhost',
- session_initiate.stanza, [])))
- jt.terminate('failed-application', msg)
- rejector = remote_handle
-
- expected_events += [
- EventPattern('dbus-signal', signal='StreamError',
- interface=cs.CHANNEL_TYPE_STREAMED_MEDIA, path=path,
- args=[stream_id,
- cs.MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED,
- msg]),
- EventPattern('dbus-signal', signal='MembersChanged',
- interface=cs.CHANNEL_IFACE_GROUP, path=path,
- args=[msg, [], [self_handle, remote_handle], [], [],
- rejector, cs.GC_REASON_ERROR])]
-
-
- q.expect_many(*expected_events)
-
- q.expect('dbus-signal', signal='Closed', path=path)
-
-def test_terminate_outgoing(jp, q, bus, conn, stream):
- _test_terminate_reason(jp, q, bus, conn, stream, False)
-
-def test_terminate_incoming(jp, q, bus, conn, stream):
- _test_terminate_reason(jp, q, bus, conn, stream, True)
-
-if __name__ == '__main__':
- for f in (test_terminate_incoming, test_terminate_outgoing):
- exec_test(
- lambda q, b, c, s: f(JingleProtocol031(), q, b, c, s))
diff --git a/tests/twisted/jingle/stream-handler-error.py b/tests/twisted/jingle/stream-handler-error.py
deleted file mode 100644
index 5b05f6d15..000000000
--- a/tests/twisted/jingle/stream-handler-error.py
+++ /dev/null
@@ -1,64 +0,0 @@
-"""
-Test handling of errors from StreamHandler during calls. This is a regression
-test for a bug introduced by 54021cee0ad38 which removed an idle callback
-masking refcounting assumptions.
-"""
-
-from functools import partial
-
-from gabbletest import exec_test
-from servicetest import make_channel_proxy
-import jingletest2
-
-import constants as cs
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(q, bus, conn, stream, call_error_on):
- jp = jingletest2.JingleProtocol031()
- jt = jingletest2.JingleTest2(jp, conn, q, stream, 'test@localhost',
- 'foo@bar.com/Foo')
-
- remote_handle = conn.RequestHandles(1, [jt.peer])[0]
-
- # Remote end calls us
- jt.incoming_call()
-
- # FIXME: these signals are not observable by real clients, since they
- # happen before NewChannels.
- # The caller is in members
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [remote_handle], [], [], [], 0, 0])
-
- # We're pending because of remote_handle
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [], [], [1L], [], remote_handle, cs.GC_REASON_INVITED])
-
- media_chan_suffix = e.path
-
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
-
- if call_error_on == 'session':
- session_handler.Error(0, "this has been deprecated for years")
- else:
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
-
- # S-E gets notified about a newly-created stream
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- # Something goes wrong immediately!
- stream_handler.Error(0, "i'll have the eggs tostada please")
-
- # Gabble doesn't fall over, and the channel closes nicely.
- e = q.expect('dbus-signal', signal='Closed', path=media_chan_suffix)
-
-if __name__ == '__main__':
- exec_test(partial(test, call_error_on='stream'))
- exec_test(partial(test, call_error_on='session'))
diff --git a/tests/twisted/jingle/stun-server.py b/tests/twisted/jingle/stun-server.py
index 0676993d4..aa481c0ab 100644
--- a/tests/twisted/jingle/stun-server.py
+++ b/tests/twisted/jingle/stun-server.py
@@ -15,7 +15,7 @@ from jingletest2 import test_all_dialects, JingleTest2
import constants as cs
import ns
-from config import CHANNEL_TYPE_CALL_ENABLED, GOOGLE_RELAY_ENABLED, VOIP_ENABLED
+from config import GOOGLE_RELAY_ENABLED, VOIP_ENABLED
if not VOIP_ENABLED:
print "NOTE: built with --disable-voip"
@@ -77,121 +77,10 @@ def init_test(jp, q, conn, stream, google=False, google_push_replacements=None):
jt.send_presence_and_caps()
- remote_handle = conn.RequestHandles(1, ["foo@bar.com/Foo"])[0]
+ remote_handle = conn.get_contact_handle_sync("foo@bar.com/Foo")
return jt, remote_handle
-def test_streamed_media(jp, q, bus, conn, stream,
- expected_stun_servers=None, google=False, google_push_replacements=None,
- expected_relays=[]):
- # Initialize the test values
- jt, remote_handle = init_test(jp, q, conn, stream, google, google_push_replacements)
-
- # Remote end calls us
- jt.incoming_call()
-
- # FIXME: these signals are not observable by real clients, since they
- # happen before NewChannels.
- # The caller is in members
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [remote_handle], [], [], [], 0, 0])
-
- # We're pending because of remote_handle
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [], [], [1L], [], remote_handle, cs.GC_REASON_INVITED])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- media_chan = make_channel_proxy(conn, e.path, 'Channel.Interface.Group')
-
- # Exercise channel properties
- channel_props = media_chan.GetAll(
- cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE)
- assert channel_props['TargetHandle'] == remote_handle
- assert channel_props['TargetHandleType'] == 1
- assert channel_props['TargetID'] == 'foo@bar.com'
- assert channel_props['Requested'] == False
- assert channel_props['InitiatorID'] == 'foo@bar.com'
- assert channel_props['InitiatorHandle'] == remote_handle
-
- # The new API for STUN servers etc.
- sh_props = stream_handler.GetAll(
- 'org.freedesktop.Telepathy.Media.StreamHandler',
- dbus_interface=dbus.PROPERTIES_IFACE)
-
- assert sh_props['NATTraversal'] == 'gtalk-p2p'
- assert sh_props['CreatedLocally'] == False
-
- test_stun_server(sh_props['STUNServers'], expected_stun_servers)
- assert sh_props['RelayInfo'] == expected_relays
-
- # consistency check, since we currently reimplement Get separately
- for k in sh_props:
- assert sh_props[k] == stream_handler.Get(
- 'org.freedesktop.Telepathy.Media.StreamHandler', k,
- dbus_interface=dbus.PROPERTIES_IFACE), k
-
- # The old API for STUN servers etc. still needs supporting, for farsight 1
- tp_prop_list = media_chan.ListProperties(dbus_interface=cs.TP_AWKWARD_PROPERTIES)
- tp_props = {}
- tp_prop_ids = {}
-
- for spec in tp_prop_list:
- tp_prop_ids[spec[0]] = spec[1]
- tp_props[spec[1]] = { 'id': spec[0], 'sig': spec[2], 'flags': spec[3] }
-
- assert 'nat-traversal' in tp_props
- assert tp_props['nat-traversal']['sig'] == 's'
- assert tp_props['nat-traversal']['flags'] == cs.PROPERTY_FLAG_READ
- assert 'stun-server' in tp_props
- assert tp_props['stun-server']['sig'] == 's'
- assert 'stun-port' in tp_props
- assert tp_props['stun-port']['sig'] in ('u', 'q')
- assert 'gtalk-p2p-relay-token' in tp_props
- assert tp_props['gtalk-p2p-relay-token']['sig'] == 's'
-
- assert tp_props['stun-server']['flags'] == cs.PROPERTY_FLAG_READ
- assert tp_props['stun-port']['flags'] == cs.PROPERTY_FLAG_READ
-
- if google:
- assert tp_props['gtalk-p2p-relay-token']['flags'] == cs.PROPERTY_FLAG_READ
- else:
- assert tp_props['gtalk-p2p-relay-token']['flags'] == 0
-
- tp_prop_values = media_chan.GetProperties(
- [tp_props[k]['id'] for k in tp_props if tp_props[k]['flags']],
- dbus_interface=cs.TP_AWKWARD_PROPERTIES)
-
- for value in tp_prop_values:
- assert value[0] in tp_prop_ids
- tp_props[tp_prop_ids[value[0]]]['value'] = value[1]
-
- assert tp_props['nat-traversal']['value'] == 'gtalk-p2p'
-
- if expected_stun_servers is not None:
- expected_stun_server, expected_stun_port = expected_stun_servers[0]
- assert tp_props['stun-server']['value'] == expected_stun_server
- assert tp_props['stun-port']['value'] == expected_stun_port
-
- if google:
- assert tp_props['gtalk-p2p-relay-token']['value'] == 'jingle all the way'
-
- media_chan.RemoveMembers([dbus.UInt32(1)], 'rejected')
-
- q.expect_many(
- EventPattern('stream-iq',
- predicate=jp.action_predicate('session-terminate')),
- EventPattern('dbus-signal', signal='Closed'),
- )
-
def test_call(jp, q, bus, conn, stream,
expected_stun_servers=None, google=False, google_push_replacements=None,
expected_relays=[]):
@@ -264,53 +153,18 @@ def test_call(jp, q, bus, conn, stream,
assertEquals(True, stream_props['HasServerInfo'])
if __name__ == '__main__':
- # StreamedMedia tests
- test_all_dialects(partial(test_streamed_media,
+ # Call tests
+ test_all_dialects(partial(test_call,
google=False))
- test_all_dialects(partial(test_streamed_media,
+ test_all_dialects(partial(test_call,
google=False, expected_stun_servers=[('5.4.3.2', 54321)]),
params={'fallback-stun-server': 'resolves-to-5.4.3.2',
'fallback-stun-port': dbus.UInt16(54321)})
- test_all_dialects(partial(test_streamed_media, google=False,
- expected_stun_servers=[('5.4.3.2', 1)]),
+ test_all_dialects(partial(test_call,
+ google=False, expected_stun_servers=[('5.4.3.2', 1)]),
params={'account': 'test@stunning.localhost'})
if GOOGLE_RELAY_ENABLED:
- test_all_dialects(partial(test_streamed_media,
- google=True, expected_stun_servers=[('1.2.3.4', 12345)]),
- protocol=GoogleXmlStream)
- test_all_dialects(partial(test_streamed_media,
- google=True, expected_stun_servers=[('5.4.3.2', 54321)]),
- protocol=GoogleXmlStream,
- params={'stun-server': 'resolves-to-5.4.3.2',
- 'stun-port': dbus.UInt16(54321)})
- test_all_dialects(partial(test_streamed_media,
- google=True, expected_stun_servers=[('1.2.3.4', 12345)]),
- protocol=GoogleXmlStream,
- params={'fallback-stun-server': 'resolves-to-5.4.3.2',
- 'fallback-stun-port': dbus.UInt16(54321)})
- test_all_dialects(partial(test_streamed_media,
- google=True, google_push_replacements=('resolves-to-5.4.3.2', '3838'),
- expected_stun_servers=[('5.4.3.2', 3838)]),
- protocol=GoogleXmlStream)
- else:
- print "NOTE: built with --disable-google-relay; omitting StreamedMedia tests with Google relay"
-
- # Call tests
- if CHANNEL_TYPE_CALL_ENABLED:
- test_all_dialects(partial(test_call,
- google=False))
- test_all_dialects(partial(test_call,
- google=False, expected_stun_servers=[('5.4.3.2', 54321)]),
- params={'fallback-stun-server': 'resolves-to-5.4.3.2',
- 'fallback-stun-port': dbus.UInt16(54321)})
- test_all_dialects(partial(test_call,
- google=False, expected_stun_servers=[('5.4.3.2', 1)]),
- params={'account': 'test@stunning.localhost'})
- else:
- print "NOTE: built with --disable-channel-type-call; omitting Call tests"
-
- if CHANNEL_TYPE_CALL_ENABLED and GOOGLE_RELAY_ENABLED:
test_all_dialects(partial(test_call,
google=True, expected_stun_servers=[('1.2.3.4', 12345)]),
protocol=GoogleXmlStream)
@@ -329,5 +183,5 @@ if __name__ == '__main__':
expected_stun_servers=[('5.4.3.2', 3838)]),
protocol=GoogleXmlStream)
else:
- print "NOTE: built with --disable-channel-type-call or with --disable-google-relay; omitting Call tests with Google relay"
+ print "NOTE: built with --disable-google-relay; omitting Call tests with Google relay"
diff --git a/tests/twisted/jingle/test-content-adding-removal.py b/tests/twisted/jingle/test-content-adding-removal.py
deleted file mode 100644
index db33274f7..000000000
--- a/tests/twisted/jingle/test-content-adding-removal.py
+++ /dev/null
@@ -1,168 +0,0 @@
-"""
-Test content adding and removal during the session. We start
-session with only one stream, then add one more, then remove
-the first one and lastly remove the second stream, which
-closes the session.
-"""
-
-from gabbletest import make_result_iq, sync_stream
-from servicetest import (
- wrap_channel, make_channel_proxy, assertEquals, EventPattern)
-from jingletest2 import (
- JingleTest2, test_dialects, JingleProtocol031, JingleProtocol015,
- )
-import constants as cs
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def gabble_terminates(jp, q, bus, conn, stream):
- test(jp, q, bus, conn, stream, False)
-
-def peer_terminates(jp, q, bus, conn, stream):
- test(jp, q, bus, conn, stream, True)
-
-def test(jp, q, bus, conn, stream, peer_removes_final_content):
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', 'foo@bar.com/Foo')
- jt.prepare()
-
- handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]
- path = conn.RequestChannel(
- cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.HT_CONTACT, handle, True)
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia')
-
- chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_id = e.args[1]
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
-
- # Before sending the initiate, request another stream
-
- chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_VIDEO])
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_id2 = e.args[1]
-
- stream_handler2 = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
- stream_handler2.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
-
- # Before the CM can initiate session, we modify a stream direction. This
- # should result in a no-op since there's no need to inform the peer of
- # change.
- chan.StreamedMedia.RequestStreamDirection(stream_id2,
- cs.MEDIA_STREAM_DIRECTION_RECEIVE)
-
- # We set both streams as ready, which will trigger the session initiate
- stream_handler.Ready(jt.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
- stream_handler2.Ready(jt.get_audio_codecs_dbus())
- stream_handler2.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- # We changed our mind locally, don't want video
- chan.StreamedMedia.RemoveStreams([stream_id2])
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('session-initiate'))
- stream.send(make_result_iq(stream, e.stanza))
-
- jt.parse_session_initiate(e.query)
-
- # Gabble sends content-remove for the video stream...
- e2 = q.expect('stream-iq', predicate=jp.action_predicate('content-remove'))
-
- # ...but before the peer notices, they accept the call.
- jt.accept()
-
- # Only now the remote end removes the video stream; if gabble mistakenly
- # marked it as accepted on session acceptance, it'll crash right about
- # now. If it's good, stream will be really removed, and
- # we can proceed.
- stream.send(make_result_iq(stream, e2.stanza))
-
- q.expect('dbus-signal', signal='StreamRemoved')
-
- # Actually, we *do* want video!
- chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_VIDEO])
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- stream2_id = e.args[1]
-
- stream_handler2 = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- stream_handler2.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler2.Ready(jt.get_audio_codecs_dbus())
- stream_handler2.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('content-add'))
- c = e.query.firstChildElement()
- assertEquals('initiator', c['creator'])
- stream.send(make_result_iq(stream, e.stanza))
-
- # Peer accepts
- jt.content_accept(e.query, 'video')
-
- # Let's start sending and receiving video!
- q.expect_many(
- EventPattern('dbus-signal', signal='SetStreamPlaying', args=[True]),
- EventPattern('dbus-signal', signal='SetStreamSending', args=[True]),
- )
-
- # Now, the call draws to a close.
- # We first remove the original stream
- chan.StreamedMedia.RemoveStreams([stream_id])
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('content-remove'))
- content_remove_ack = make_result_iq(stream, e.stanza)
-
- if peer_removes_final_content:
- # The peer removes the final countdo^W content. From a footnote (!) in
- # XEP 0166:
- # If the content-remove results in zero content definitions for the
- # session, the entity that receives the content-remove SHOULD send
- # a session-terminate action to the other party (since a session
- # with no content definitions is void).
- # So, Gabble should respond to the content-remove with a
- # session-terminate.
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.peer, 'content-remove', [
- jp.Content(c['name'], c['creator'], c['senders']) ]) ])
- stream.send(jp.xml(node))
- else:
- # The Telepathy client removes the second stream; Gabble should
- # terminate the session rather than sending a content-remove.
- chan.StreamedMedia.RemoveStreams([stream2_id])
-
- st, closed = q.expect_many(
- EventPattern('stream-iq',
- predicate=jp.action_predicate('session-terminate')),
- # Gabble shouldn't wait for the peer to ack the terminate before
- # considering the call finished.
- EventPattern('dbus-signal', signal='Closed', path=path))
-
- # Only now does the peer ack the content-remove. This serves as a
- # regression test for contents outliving the session; if the content didn't
- # die properly, this crashed Gabble.
- stream.send(content_remove_ack)
- sync_stream(q, stream)
-
- # The peer can ack the terminate too, just for completeness.
- stream.send(make_result_iq(stream, st.stanza))
-
-if __name__ == '__main__':
- test_dialects(gabble_terminates, [JingleProtocol015, JingleProtocol031])
- test_dialects(peer_terminates, [JingleProtocol015, JingleProtocol031])
-
diff --git a/tests/twisted/jingle/test-content-complex.py b/tests/twisted/jingle/test-content-complex.py
deleted file mode 100644
index c23f2c9a0..000000000
--- a/tests/twisted/jingle/test-content-complex.py
+++ /dev/null
@@ -1,257 +0,0 @@
-"""
-Test everything related to contents
-"""
-
-from gabbletest import sync_stream
-from servicetest import (
- make_channel_proxy, assertEquals, EventPattern)
-import constants as cs
-from jingletest2 import (
- JingleTest2, JingleProtocol015, JingleProtocol031, test_dialects)
-
-from twisted.words.xish import xpath
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def worker(jp, q, bus, conn, stream):
-
- def make_stream_request(stream_type):
- media_iface.RequestStreams(remote_handle, [stream_type])
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- stream_id = e.args[1]
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", jt2.get_remote_transports_dbus())
- stream_handler.Ready(jt2.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
- return (stream_handler, stream_id)
-
-
- jt2 = JingleTest2(jp, conn, q, stream, 'test@localhost', 'foo@bar.com/Foo')
- jt2.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, ["foo@bar.com/Foo"])[0]
-
- # Remote end calls us
- jt2.incoming_call()
-
- # FIXME: these signals are not observable by real clients, since they
- # happen before NewChannels.
- # The caller is in members
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [remote_handle], [], [], [], 0, 0])
-
- # We're pending because of remote_handle
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [], [], [self_handle], [], remote_handle,
- cs.GC_REASON_INVITED])
-
- media_chan = make_channel_proxy(conn, e.path, 'Channel.Interface.Group')
- signalling_iface = make_channel_proxy(conn, e.path, 'Channel.Interface.MediaSignalling')
- media_iface = make_channel_proxy(conn, e.path, 'Channel.Type.StreamedMedia')
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- media_chan.AddMembers([self_handle], 'accepted')
-
- # S-E gets notified about a newly-created stream
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- id1 = e.args[1]
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- # We are now in members too
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [self_handle], [], [], [], self_handle,
- cs.GC_REASON_NONE])
-
- # we are now both in members
- members = media_chan.GetMembers()
- assert set(members) == set([self_handle, remote_handle]), members
-
- stream_handler.NewNativeCandidate("fake", jt2.get_remote_transports_dbus())
- stream_handler.Ready(jt2.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- # First one is transport-info
- e = q.expect('stream-iq', predicate=jp.action_predicate('transport-info'))
- assertEquals('foo@bar.com/Foo', e.query['initiator'])
-
- # stream.send(gabbletest.make_result_iq(stream, e.stanza))
- stream.send(jp.xml(jp.ResultIq('test@localhost', e.stanza, [])))
-
- # S-E reports codec intersection, after which gabble can send acceptance
- stream_handler.SupportedCodecs(jt2.get_audio_codecs_dbus())
-
- # Second one is session-accept
- e = q.expect('stream-iq', predicate=jp.action_predicate('session-accept'))
-
- # stream.send(gabbletest.make_result_iq(stream, e.stanza))
- stream.send(jp.xml(jp.ResultIq('test@localhost', e.stanza, [])))
-
- # Here starts the interesting part of this test
- # Remote end tries to create a content we can't handle
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'content-add', [
- jp.Content('bogus', 'initiator', 'both',
- jp.Description('hologram', [
- jp.PayloadType(name, str(rate), str(id), parameters) for
- (name, id, rate, parameters) in jt2.audio_codecs ]),
- jp.TransportGoogleP2P()) ]) ])
- stream.send(jp.xml(node))
-
- # In older Jingle, this is a separate namespace, which isn't
- # recognized, but it's a valid request, so it gets ackd and rejected
- if jp.dialect == 'jingle-v0.15':
- # Gabble should acknowledge content-add
- q.expect('stream-iq', iq_type='result')
-
- # .. and then send content-reject for the bogus content
- e = q.expect('stream-iq', iq_type='set', predicate=lambda x:
- xpath.queryForNodes("/iq/jingle[@action='content-reject']/content[@name='bogus']",
- x.stanza))
-
- # In new Jingle, this is a bogus subtype of recognized namespace,
- # so Gabble returns a bad request error
- else:
- q.expect('stream-iq', iq_type='error')
-
- # Remote end then tries to create a content with a name it's already used
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'content-add', [
- jp.Content(jt2.audio_names[0], 'initiator', 'both',
- jp.Description('audio', [
- jp.PayloadType(name, str(rate), str(id), parameters) for
- (name, id, rate, parameters) in jt2.audio_codecs ]),
- jp.TransportGoogleP2P()) ]) ])
- stream.send(jp.xml(node))
-
- # Gabble should return error (content already exists)
- q.expect('stream-iq', iq_type='error')
-
- # We try to add a stream
- (stream_handler2, id2) = make_stream_request(cs.MEDIA_STREAM_TYPE_VIDEO)
-
- # Gabble should now send content-add
- e = q.expect('stream-iq', iq_type='set', predicate=lambda x:
- xpath.queryForNodes("/iq/jingle[@action='content-add']",
- x.stanza))
-
- c = e.query.firstChildElement()
- assert c['creator'] == 'responder', c['creator']
-
- stream.send(jp.xml(jp.ResultIq('test@localhost', e.stanza, [])))
-
- # We try to add yet another stream
- (stream_handler3, id3) = make_stream_request(cs.MEDIA_STREAM_TYPE_VIDEO)
-
- # Gabble should send another content-add
- e = q.expect('stream-iq', iq_type='set', predicate=lambda x:
- xpath.queryForNodes("/iq/jingle[@action='content-add']",
- x.stanza))
-
- d = e.query.firstChildElement()
- assertEquals('responder', d['creator'])
-
- stream.send(jp.xml(jp.ResultIq('test@localhost', e.stanza, [])))
-
- # Remote end rejects the first stream we tried to add.
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'content-reject', [
- jp.Content(c['name'], c['creator'], c['senders']) ]) ])
- stream.send(jp.xml(node))
-
- # Gabble removes the stream
- q.expect('dbus-signal', signal='StreamRemoved',
- interface=cs.CHANNEL_TYPE_STREAMED_MEDIA)
-
- # Remote end tries to add a content with the same name as the second one we
- # just added
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'content-add', [
- jp.Content(d['name'], 'initiator', 'both',
- jp.Description('audio', [
- jp.PayloadType(name, str(rate), str(id), parameters) for
- (name, id, rate, parameters) in jt2.audio_codecs ]),
- jp.TransportGoogleP2P()) ]) ])
- stream.send(jp.xml(node))
-
- # Because stream names are namespaced by creator, Gabble should be okay
- # with that.
- q.expect_many(
- EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
- EventPattern('dbus-signal', signal='StreamAdded'),
- )
-
- # Remote end thinks better of that, and removes the similarly-named stream
- # it tried to add.
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'content-remove', [
- jp.Content(d['name'], 'initiator', d['senders']) ]) ])
- stream.send(jp.xml(node))
-
- q.expect_many(
- EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
- EventPattern('dbus-signal', signal='StreamRemoved'),
- )
-
- # Remote end finally accepts. When Gabble did not namespace contents by
- # their creator, it would NAK this IQ:
- # - Gabble (responder) created a stream called 'foo';
- # - test suite (initiator) created a stream called 'foo', which Gabble
- # decided would replace its own stream called 'foo';
- # - test suite removed its 'foo';
- # - test suite accepted Gabble's 'foo', but Gabble didn't believe a stream
- # called 'foo' existed any more.
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'content-accept', [
- jp.Content(d['name'], d['creator'], d['senders'],
- jp.Description('video', [
- jp.PayloadType(name, str(rate), str(id), parameters) for
- (name, id, rate, parameters ) in jt2.audio_codecs ]),
- jp.TransportGoogleP2P()) ]) ])
- stream.send(jp.xml(node))
-
- # We get remote codecs
- e = q.expect('dbus-signal', signal='SetRemoteCodecs')
-
- # Now, both we and remote peer try to remove the content simultaneously:
- # Telepathy client calls RemoveStreams...
- media_iface.RemoveStreams([id3])
-
- # ...so Gabble sends a content-remove...
- e = q.expect('stream-iq', iq_type='set', predicate=lambda x:
- xpath.queryForNodes("/iq/jingle[@action='content-remove']",
- x.stanza))
-
- # ...but before it's acked the peer sends its own content-remove...
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'content-remove', [
- jp.Content(c['name'], c['creator'], c['senders']) ]) ])
- stream.send(jp.xml(node))
-
- # ...and we don't want Gabble to break when that happens.
- sync_stream(q, stream)
-
- # Now we want to remove the first stream
- media_iface.RemoveStreams([id1])
-
- # Since this is the last stream, Gabble will just terminate the session.
- e = q.expect('stream-iq', iq_type='set', predicate=lambda x:
- xpath.queryForNodes("/iq/jingle[@action='session-terminate']",
- x.stanza))
-
-if __name__ == '__main__':
- test_dialects(worker, [JingleProtocol015, JingleProtocol031])
diff --git a/tests/twisted/jingle/test-description-info.py b/tests/twisted/jingle/test-description-info.py
deleted file mode 100644
index 1adda17ba..000000000
--- a/tests/twisted/jingle/test-description-info.py
+++ /dev/null
@@ -1,213 +0,0 @@
-"""
-Test emition and handling of codec update using description-info
-"""
-
-from gabbletest import exec_test, sync_stream
-from servicetest import (
- wrap_channel, assertEquals, make_channel_proxy, unwrap, EventPattern,
- call_async)
-from jingletest2 import JingleTest2, JingleProtocol031
-import constants as cs
-
-from twisted.words.xish import xpath
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def extract_params(payload_type):
- ret = {}
- for node in payload_type.elements():
- assert node.name == 'parameter'
- ret[node['name']] = node['value']
- return ret
-
-def early_description_info(q, bus, conn, stream):
- test(q, bus, conn, stream, send_early_description_info=True)
-
-def test(q, bus, conn, stream, send_early_description_info=False):
- jp = JingleProtocol031()
- jt2 = JingleTest2(jp, conn, q, stream, 'test@localhost', 'foo@bar.com/Foo')
- jt2.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, ["foo@bar.com/Foo"])[0]
-
- # Remote end calls us
- jt2.incoming_call()
-
- # FIXME: these signals are not observable by real clients, since they
- # happen before NewChannels.
- # The caller is in members
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [remote_handle], [], [], [], 0, 0])
-
- # We're pending because of remote_handle
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [], [], [self_handle], [], remote_handle,
- cs.GC_REASON_INVITED])
-
- chan = wrap_channel(bus.get_object(conn.bus_name, e.path),
- 'StreamedMedia')
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- if send_early_description_info:
- """
- Regression test for a bug where Gabble would crash if you sent it
- description-info before calling Ready() on the relevant StreamHandler,
- and then for a bug where Gabble would never accept the call if a
- description-info was received before all StreamHandlers were Ready().
- """
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'description-info', [
- jp.Content('stream1', 'initiator', 'both',
- jp.Description('audio', [ ])) ]) ])
- stream.send(jp.xml(node))
-
- sync_stream(q, stream)
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- chan.Group.AddMembers([self_handle], 'accepted')
-
- # S-E gets notified about a newly-created stream
- e = q.expect('dbus-signal', signal='NewStreamHandler')
- id1 = e.args[1]
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- # We are now in members too
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [self_handle], [], [], [], self_handle,
- cs.GC_REASON_NONE])
-
- # we are now both in members
- members = chan.Group.GetMembers()
- assert set(members) == set([self_handle, remote_handle]), members
-
- local_codecs = [('GSM', 3, 8000, {}),
- ('PCMA', 8, 8000, {'helix':'woo yay'}),
- ('PCMU', 0, 8000, {}) ]
- local_codecs_dbus = jt2.dbusify_codecs_with_params(local_codecs)
-
- stream_handler.NewNativeCandidate("fake", jt2.get_remote_transports_dbus())
- stream_handler.Ready(local_codecs_dbus)
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- stream_handler.CodecsUpdated(local_codecs_dbus)
-
- local_codecs = [('GSM', 3, 8000, {}),
- ('PCMA', 8, 8000, {'gstreamer':'rock on'}),
- ('PCMU', 0, 8000, {}) ]
- local_codecs_dbus = jt2.dbusify_codecs_with_params(local_codecs)
- stream_handler.CodecsUpdated(local_codecs_dbus)
-
-
- # First IQ is transport-info; also, we expect to be told what codecs the
- # other end wants.
- e, src = q.expect_many(
- EventPattern('stream-iq',
- predicate=jp.action_predicate('transport-info')),
- EventPattern('dbus-signal', signal='SetRemoteCodecs')
- )
- assertEquals('foo@bar.com/Foo', e.query['initiator'])
-
- assert jt2.audio_codecs == [ (name, id, rate, parameters)
- for id, name, type, rate, channels, parameters in unwrap(src.args[0]) ], \
- (jt2.audio_codecs, unwrap(src.args[0]))
-
- stream.send(jp.xml(jp.ResultIq('test@localhost', e.stanza, [])))
-
- # S-E reports codec intersection, after which gabble can send acceptance
- stream_handler.SupportedCodecs(local_codecs_dbus)
-
- # Second one is session-accept
- e = q.expect('stream-iq', predicate=jp.action_predicate('session-accept'))
-
- # farstream is buggy, and tells tp-fs to tell Gabble to change the third
- # codec's clockrate. This isn't legal, so Gabble says no.
- new_codecs = [ ('GSM', 3, 8000, {}),
- ('PCMA', 8, 8000, {}),
- ('PCMU', 0, 4000, {}) ]
- call_async(q, stream_handler, 'CodecsUpdated',
- jt2.dbusify_codecs(new_codecs))
- event = q.expect('dbus-error', method='CodecsUpdated')
- assert event.error.get_dbus_name() == cs.INVALID_ARGUMENT, \
- event.error.get_dbus_name()
-
- # With its tail between its legs, tp-fs decides it wants to add some
- # parameters to the first two codecs, not changing the third.
- new_codecs = [ ('GSM', 3, 8000, {'type': 'banana'}),
- ('PCMA', 8, 8000, {'helix': 'BUFFERING'}),
- ('PCMU', 0, 8000, {}) ]
- stream_handler.CodecsUpdated(jt2.dbusify_codecs_with_params(new_codecs))
-
- audio_content = jt2.audio_names[0]
-
- e = q.expect('stream-iq', iq_type='set', predicate=lambda x:
- xpath.queryForNodes("/iq/jingle[@action='description-info']",
- x.stanza))
- payload_types = xpath.queryForNodes(
- "/iq/jingle/content[@name='%s']/description/payload-type"
- % audio_content,
- e.stanza)
- # Gabble SHOULD only include the changed codecs in description-info
- assert len(payload_types) == 2, payload_types
-
- payload_types_tupled = [ (pt['name'], int(pt['id']), int(pt['clockrate']),
- extract_params(pt))
- for pt in payload_types ]
- assert sorted(payload_types_tupled) == sorted(new_codecs[0:2]), \
- (payload_types_tupled, new_codecs[0:2])
-
- # The remote end decides it wants to change the number of channels in the
- # third codec. This is not meant to happen, so Gabble should send it an IQ
- # error back.
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'description-info', [
- jp.Content(audio_content, 'initiator', 'both',
- jp.Description('audio', [
- jp.PayloadType('PCMU', '1600', '0') ])) ]) ])
- stream.send(jp.xml(node))
- q.expect('stream-iq', iq_type='error',
- predicate=lambda x: x.stanza['id'] == node[2]['id'])
-
- # Instead, the remote end decides to add a parameter to the third codec.
- new_codecs = [ ('GSM', 3, 8000, {}),
- ('PCMA', 8, 8000, {}),
- ('PCMU', 0, 8000, {'choppy': 'false'}),
- ]
- # As per the XEP, it only sends the ones which have changed.
- c = new_codecs[2]
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'description-info', [
- jp.Content(audio_content, 'initiator', 'both',
- jp.Description('audio', [
- jp.PayloadType(c[0], str(c[2]), str(c[1]), c[3])
- ])) ]) ])
- stream.send(jp.xml(node))
-
- # Gabble should patch its idea of the remote codecs with the update it just
- # got, and emit SetRemoteCodecs for them all.
- e = q.expect('dbus-signal', signal='SetRemoteCodecs')
- new_codecs_dbus = unwrap(jt2.dbusify_codecs_with_params(new_codecs))
- announced = unwrap(e.args[0])
- assert new_codecs_dbus == announced, (new_codecs_dbus, announced)
-
- # We close the session by removing the stream
- chan.StreamedMedia.RemoveStreams([id1])
-
- e = q.expect('stream-iq', iq_type='set', predicate=lambda x:
- xpath.queryForNodes("/iq/jingle[@action='session-terminate']",
- x.stanza))
-
-if __name__ == '__main__':
- exec_test(test)
- exec_test(early_description_info)
-
diff --git a/tests/twisted/jingle/test-incoming-call-reject.py b/tests/twisted/jingle/test-incoming-call-reject.py
deleted file mode 100644
index 581ea7f60..000000000
--- a/tests/twisted/jingle/test-incoming-call-reject.py
+++ /dev/null
@@ -1,112 +0,0 @@
-"""
-Test incoming call handling - reject a call because we're busy, and for no
-reason.
-"""
-
-from twisted.words.xish import xpath
-
-from servicetest import make_channel_proxy, EventPattern, call_async
-from jingletest2 import JingleTest2, test_all_dialects
-
-import constants as cs
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test_busy(jp, q, bus, conn, stream):
- test(jp, q, bus, conn, stream, True)
-
-def test_no_reason(jp, q, bus, conn, stream):
- test(jp, q, bus, conn, stream, False)
-
-def test(jp, q, bus, conn, stream, busy):
- remote_jid = 'foo@bar.com/Foo'
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', remote_jid)
-
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, [remote_jid])[0]
-
- # Remote end calls us
- jt.incoming_call()
-
- # FIXME: these signals are not observable by real clients, since they
- # happen before NewChannels.
- # The caller is in members
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [remote_handle], [], [], [], 0, 0])
-
- # We're pending because of remote_handle
- e = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [], [], [self_handle], [], remote_handle,
- cs.GC_REASON_INVITED])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- media_chan = make_channel_proxy(conn, e.path, 'Channel.Interface.Group')
-
- # Exercise channel properties
- channel_props = media_chan.GetAll(cs.CHANNEL,
- dbus_interface=cs.PROPERTIES_IFACE)
- assert channel_props['TargetHandle'] == remote_handle
- assert channel_props['TargetHandleType'] == 1
- assert channel_props['TargetID'] == 'foo@bar.com'
- assert channel_props['Requested'] == False
- assert channel_props['InitiatorID'] == 'foo@bar.com'
- assert channel_props['InitiatorHandle'] == remote_handle
-
- if busy:
- # First, try using a reason that doesn't make any sense
- call_async(q, media_chan, 'RemoveMembersWithReason',
- [self_handle], "what kind of a reason is Separated?!",
- cs.GC_REASON_SEPARATED)
- e = q.expect('dbus-error', method='RemoveMembersWithReason')
- assert e.error.get_dbus_name() == cs.INVALID_ARGUMENT
-
- # Now try a more sensible reason.
- media_chan.RemoveMembersWithReason([self_handle],
- "which part of 'Do Not Disturb' don't you understand?",
- cs.GC_REASON_BUSY)
- else:
- media_chan.RemoveMembers([self_handle], 'rejected')
-
- iq, mc, _ = q.expect_many(
- EventPattern('stream-iq',
- predicate=jp.action_predicate('session-terminate')),
- EventPattern('dbus-signal', signal='MembersChanged'),
- EventPattern('dbus-signal', signal='Closed'),
- )
-
- _, added, removed, lp, rp, actor, reason = mc.args
- assert added == [], added
- assert set(removed) == set([self_handle, remote_handle]), \
- (removed, self_handle, remote_handle)
- assert lp == [], lp
- assert rp == [], rp
- assert actor == self_handle, (actor, self_handle)
- if busy:
- assert reason == cs.GC_REASON_BUSY, reason
- else:
- assert reason == cs.GC_REASON_NONE, reason
-
- if jp.is_modern_jingle():
- jingle = iq.query
- if busy:
- r = "/jingle/reason/busy"
- else:
- r = "/jingle/reason/cancel"
- assert xpath.queryForNodes(r, jingle) is not None, (jingle.toXml(), r)
-
-if __name__ == '__main__':
- test_all_dialects(test_busy)
- test_all_dialects(test_no_reason)
-
diff --git a/tests/twisted/jingle/test-incoming-iceudp.py b/tests/twisted/jingle/test-incoming-iceudp.py
deleted file mode 100644
index f59e44355..000000000
--- a/tests/twisted/jingle/test-incoming-iceudp.py
+++ /dev/null
@@ -1,104 +0,0 @@
-"""
-Test usage of ICE-UDP in incoming calls.
-"""
-
-from twisted.words.xish import xpath
-
-from gabbletest import exec_test
-from servicetest import (
- make_channel_proxy, wrap_channel, assertEquals, EventPattern, assertLength,
- )
-import ns
-import constants as cs
-
-from jingletest2 import *
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def worker(jp, q, bus, conn, stream):
- jp.features.append(ns.JINGLE_TRANSPORT_ICEUDP)
- jt2 = JingleTest2(jp, conn, q, stream, 'test@localhost', 'foo@bar.com/Foo')
- jt2.prepare()
-
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, ["foo@bar.com/Foo"])[0]
-
- # Remote end calls us
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'session-initiate', [
- jp.Content('stream1', 'initiator', 'both',
- jp.Description('audio', [
- jp.PayloadType(name, str(rate), str(id), parameters) for
- (name, id, rate, parameters) in jt2.audio_codecs ]),
- jp.TransportIceUdp()) ]) ])
- stream.send(jp.xml(node))
-
- nc, e = q.expect_many(
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewSessionHandler'),
- )
- path = nc.args[0]
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia')
-
- hrggh = chan.ListProperties(dbus_interface=cs.TP_AWKWARD_PROPERTIES)
- id = [x for x, name, _, _ in hrggh if name == 'nat-traversal'][0]
- nrgrg = chan.GetProperties([id], dbus_interface=cs.TP_AWKWARD_PROPERTIES)
- _, nat_traversal = nrgrg[0]
- assertEquals('ice-udp', nat_traversal)
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- chan.Group.AddMembers([conn.GetSelfHandle()], 'accepted')
-
- # S-E gets notified about a newly-created stream
- e = q.expect('dbus-signal', signal='NewStreamHandler')
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", jt2.get_remote_transports_dbus())
- stream_handler.Ready(jt2.get_audio_codecs_dbus())
- stream_handler.StreamState(2)
-
- # First one is transport-info
- e = q.expect('stream-iq', predicate=jp.action_predicate('transport-info'))
- transport_stanza = xpath.queryForNodes(
- "/iq/jingle/content/transport[@xmlns='%s']"
- % ns.JINGLE_TRANSPORT_ICEUDP, e.stanza)[0]
-
- # username
- assertEquals(transport_stanza['ufrag'], jt2.remote_transports[0][7])
- # password
- assertEquals(transport_stanza['pwd'], jt2.remote_transports[0][8])
-
- children = list(transport_stanza.elements())
- assertLength(1, children)
-
- stream.send(jp.xml(jp.ResultIq('test@localhost', e.stanza, [])))
-
- # Set codec intersection so gabble can accept the session
- stream_handler.SupportedCodecs(jt2.get_audio_codecs_dbus())
-
- # Second one is session-accept
- e = q.expect('stream-iq', predicate=jp.action_predicate('session-accept'))
- assert xpath.queryForNodes("/iq/jingle/content/transport[@xmlns='%s']" %
- ns.JINGLE_TRANSPORT_ICEUDP, e.stanza)
-
- stream.send(jp.xml(jp.ResultIq('test@localhost', e.stanza, [])))
-
- # Connected! Blah, blah, ...
-
- jt2.terminate()
-
- e = q.expect('dbus-signal', signal='Close')
-
-def test031(q, bus, conn, stream):
- return worker(JingleProtocol031(),q, bus, conn, stream)
-
-if __name__ == '__main__':
- exec_test(test031)
diff --git a/tests/twisted/jingle/test-outgoing-call-rejected.py b/tests/twisted/jingle/test-outgoing-call-rejected.py
deleted file mode 100644
index 819249ee7..000000000
--- a/tests/twisted/jingle/test-outgoing-call-rejected.py
+++ /dev/null
@@ -1,86 +0,0 @@
-"""
-Test outgoing call handling. This tests the case when the
-remote party rejects our call because they're busy.
-"""
-
-from gabbletest import make_result_iq
-from servicetest import make_channel_proxy, assertEquals
-import constants as cs
-from jingletest2 import JingleTest2, test_all_dialects
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def _test(jp, q, bus, conn, stream,
- jingle_reason, group_change_reason, stream_error):
- remote_jid = 'foo@bar.com/Foo'
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', remote_jid)
-
- jt.prepare()
-
- self_handle = conn.GetSelfHandle()
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, [remote_jid])[0]
-
- path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.HT_CONTACT, remote_handle, True)
-
- signalling_iface = make_channel_proxy(conn, path, 'Channel.Interface.MediaSignalling')
- media_iface = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')
-
- media_iface.RequestStreams(remote_handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
- stream_handler.Ready(jt.get_audio_codecs_dbus())
- stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('session-initiate'))
- stream.send(make_result_iq(stream, e.stanza))
-
- text = u"begone!"
-
- jt.parse_session_initiate(e.query)
- jt.terminate(reason=jingle_reason, text=text)
-
- mc = q.expect('dbus-signal', signal='MembersChanged')
- message, added, removed, lp, rp, actor, reason = mc.args
- assert added == [], added
- assert set(removed) == set([self_handle, remote_handle]), \
- (removed, self_handle, remote_handle)
- assert lp == [], lp
- assert rp == [], rp
- assert actor == remote_handle, (actor, remote_handle)
- if jp.is_modern_jingle():
- assertEquals(text, message)
- assertEquals(group_change_reason, reason)
-
- if jp.is_modern_jingle() and stream_error:
- se = q.expect('dbus-signal', signal='StreamError')
- assertEquals(stream_error, se.args[1])
-
- q.expect('dbus-signal', signal='Close') #XXX - match against the path
-
-def test_busy(jp, q, bus, conn, stream):
- _test(jp, q, bus, conn, stream, "busy", cs.GC_REASON_BUSY, None)
-
-def test_codec_fail(jp, q, bus, conn, stream):
- _test(jp, q, bus, conn, stream, "failed-application", cs.GC_REASON_ERROR,
- cs.MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED)
-
-if __name__ == '__main__':
- test_all_dialects(test_busy)
- test_all_dialects(test_codec_fail)
diff --git a/tests/twisted/jingle/test-outgoing-iceudp.py b/tests/twisted/jingle/test-outgoing-iceudp.py
deleted file mode 100644
index fbdad9472..000000000
--- a/tests/twisted/jingle/test-outgoing-iceudp.py
+++ /dev/null
@@ -1,162 +0,0 @@
-"""
-Test outgoing call using ICE-UDP transport mechanism.
-"""
-
-from gabbletest import exec_test, sync_stream
-from servicetest import (
- wrap_channel, make_channel_proxy, EventPattern, call_async,
- assertEquals)
-import gabbletest
-import dbus
-import time
-from twisted.words.xish import xpath
-import ns
-import constants as cs
-
-from jingletest2 import *
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def worker(jp, q, bus, conn, stream):
- jp.features.remove(ns.GOOGLE_P2P)
- jp.features.append(ns.JINGLE_TRANSPORT_ICEUDP)
- jt2 = JingleTest2(jp, conn, q, stream, 'test@localhost', 'foo@bar.com/Foo')
- jt2.prepare()
-
- remote_handle = conn.RequestHandles(cs.HT_CONTACT, ["foo@bar.com/Foo"])[0]
-
- call_async(q, conn, 'RequestChannel', cs.CHANNEL_TYPE_STREAMED_MEDIA, 0, 0,
- True)
-
- ret, old_sig, new_sig = q.expect_many(
- EventPattern('dbus-return', method='RequestChannel'),
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
- EventPattern('dbus-signal', signal='NewChannels',
- predicate=lambda e:
- cs.CHANNEL_TYPE_CONTACT_LIST not in e.args[0][0][1].values()),
- )
- path = ret.value[0]
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia')
-
- chan.StreamedMedia.RequestStreams(remote_handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- # S-E gets notified about new session handler, and calls Ready on it
- e = q.expect('dbus-signal', signal='NewSessionHandler')
- assert e.args[1] == 'rtp'
-
- # The 'nat-traversal' tp property should be "ice-udp"
- hrggh = chan.ListProperties(dbus_interface=cs.TP_AWKWARD_PROPERTIES)
- id = [x for x, name, _, _ in hrggh if name == 'nat-traversal'][0]
- nrgrg = chan.GetProperties([id], dbus_interface=cs.TP_AWKWARD_PROPERTIES)
- _, nat_traversal = nrgrg[0]
- assertEquals('ice-udp', nat_traversal)
-
- session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- session_handler.Ready()
-
- e = q.expect('dbus-signal', signal='NewStreamHandler')
-
- stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
-
- stream_handler.NewNativeCandidate("fake", jt2.get_remote_transports_dbus())
- stream_handler.Ready(jt2.get_audio_codecs_dbus())
- stream_handler.StreamState(2)
-
- e = q.expect('stream-iq', predicate=jp.action_predicate('session-initiate'))
- # The session-initiate "MUST include a <transport/> child element qualified
- # by the [ice-udp] namespace"
- node = xpath.queryForNodes("/iq/jingle/content/transport[@xmlns='%s']" %
- ns.JINGLE_TRANSPORT_ICEUDP, e.stanza)[0]
- jt2.parse_session_initiate(e.query)
-
- # ...which SHOULD contain the higher-priority ICE candidates. We supplied
- # one candidate, so...
- assertEquals('username', node['ufrag'])
- assertEquals('password', node['pwd'])
- node = [ x for x in node.children if type(x) != unicode ][0]
- assertEquals('candidate', node.name)
- assert node['foundation'] is not None
-
- stream.send(jp.xml(jp.ResultIq('test@localhost', e.stanza, [])))
-
- # Make sure that it doesn't send a duplicate of our one ICE candidate here.
- ti_event = [
- EventPattern('stream-iq',
- predicate=jp.action_predicate('transport-info'))
- ]
- q.forbid_events(ti_event)
- sync_stream(q, stream)
- q.unforbid_events(ti_event)
-
- # XEP-0166 6.4 Negotiation: "The allowable negotiations include:
- # Exchanging particular transport candidates via the transport-info action."
- candidate = (
- "192.168.0.69", # host
- 668, # port
- 0, # protocol = TP_MEDIA_STREAM_BASE_PROTO_UDP
- "RTP", # protocol subtype
- "AVP", # profile
- 1.0, # preference
- 0, # transport type = TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL,
- "username",
- "password" )
- transport = jp.TransportIceUdp([candidate])
-
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'transport-info', [
- jp.Content('Audio', 'initiator', 'both',
- transport = transport) ]) ])
- stream.send(jp.xml(node))
-
- candidate_e, result_e = q.expect_many(
- EventPattern('dbus-signal', signal='AddRemoteCandidate'),
- EventPattern('stream-iq', iq_type='result'))
-
- fake_, (returned_candidate,) = candidate_e.args
- assertEquals(candidate, returned_candidate[1:])
-
- candidate = (
- "192.168.0.69", # host
- 670, # port
- 0, # protocol = TP_MEDIA_STREAM_BASE_PROTO_UDP
- "RTP", # protocol subtype
- "AVP", # profile
- 1.0, # preference
- 0, # transport type = TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL,
- "username",
- "password" )
- transport = jp.TransportIceUdp([candidate])
-
- # It is also valid to send transports in the accept.
- # This is what pidgin does.
- node = jp.SetIq(jt2.peer, jt2.jid, [
- jp.Jingle(jt2.sid, jt2.peer, 'session-accept', [
- jp.Content('Audio', 'initiator', 'both',
- jp.Description('audio', [
- jp.PayloadType(name, str(rate), str(id), parameters) for
- (name, id, rate, parameters) in jt2.audio_codecs ]),
- transport) ]) ])
- stream.send(jp.xml(node))
-
- candidate_e, result_e = q.expect_many(
- EventPattern('dbus-signal', signal='AddRemoteCandidate'),
- EventPattern('stream-iq', iq_type='result'))
-
- fake_, (returned_candidate,) = candidate_e.args
- assertEquals(candidate, returned_candidate[1:])
-
- chan.Close()
- e = q.expect('stream-iq',
- predicate=jp.action_predicate('session-terminate'))
-
-def test031(q, bus, conn, stream):
- return worker(JingleProtocol031(),q, bus, conn, stream)
-
-if __name__ == '__main__':
- exec_test(test031)
diff --git a/tests/twisted/jingle/test-wait-for-caps-incomplete.py b/tests/twisted/jingle/test-wait-for-caps-incomplete.py
deleted file mode 100644
index e6e97c226..000000000
--- a/tests/twisted/jingle/test-wait-for-caps-incomplete.py
+++ /dev/null
@@ -1,71 +0,0 @@
-"""
-Test that Gabble properly cleans up delayed RequestStream contexts
-and returns an error when Disconnect is called and there are
-incomplete requests.
-"""
-
-from functools import partial
-from gabbletest import exec_test, disconnect_conn
-from servicetest import make_channel_proxy, call_async, sync_dbus, EventPattern
-
-import constants as cs
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(q, bus, conn, stream, channel_type):
- peer = 'foo@bar.com/Foo'
- # We intentionally DON'T set remote presence yet. Since Gabble is still
- # unsure whether to treat contact as offline for this purpose, it
- # will tentatively allow channel creation and contact handle addition
-
- handle = conn.RequestHandles(cs.HT_CONTACT, [peer])[0]
-
- if channel_type == cs.CHANNEL_TYPE_STREAMED_MEDIA:
- path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA,
- cs.HT_CONTACT, handle, True)
- media_iface = make_channel_proxy(conn, path,
- 'Channel.Type.StreamedMedia')
-
- # So it turns out that the calls to RequestStreams and Disconnect could be
- # reordered while the first waits on the result of introspecting the
- # channel's object which is kicked off by making a proxy object for it,
- # whereas the connection proxy is long ago introspected. Isn't dbus-python
- # great? Syncing here forces that introspection to finish so we can rely on
- # the ordering of RequestStreams and Disconnect. Yay.
- sync_dbus(bus, q, conn)
-
- # Now we request streams before either <presence> or caps have arrived
- if channel_type == cs.CHANNEL_TYPE_STREAMED_MEDIA:
- call_async(q, media_iface, 'RequestStreams', handle,
- [cs.MEDIA_STREAM_TYPE_AUDIO])
-
- before_events, after_events = disconnect_conn(q, conn, stream,
- [EventPattern('dbus-error', method='RequestStreams')])
-
- # RequestStreams should now return NotAvailable
- assert before_events[0].error.get_dbus_name() == cs.NOT_AVAILABLE, \
- before_events[0].error
- else:
- call_async(q, conn.Requests, 'CreateChannel',
- { cs.CHANNEL_TYPE: channel_type,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_ID: peer,
- cs.CALL_INITIAL_AUDIO: True
- })
-
- before_events, after_events = disconnect_conn(q, conn, stream,
- [EventPattern('dbus-error', method='CreateChannel')])
-
- # CreateChannel should now return Disconnected
- assert before_events[0].error.get_dbus_name() == cs.DISCONNECTED, \
- before_events[0].error
-
-if __name__ == '__main__':
- exec_test(partial(test, channel_type=cs.CHANNEL_TYPE_STREAMED_MEDIA),
- timeout=10)
- exec_test(partial(test, channel_type=cs.CHANNEL_TYPE_CALL),
- timeout=10)
diff --git a/tests/twisted/jingle/test-wait-for-caps.py b/tests/twisted/jingle/test-wait-for-caps.py
deleted file mode 100644
index 98221ef8e..000000000
--- a/tests/twisted/jingle/test-wait-for-caps.py
+++ /dev/null
@@ -1,99 +0,0 @@
-"""
-Test use-case when client requests going online and immediately
-attempts to call a contact. Gabble should delay the RequestStreams
-call until caps have arrived.
-"""
-
-from functools import partial
-from gabbletest import exec_test
-from servicetest import make_channel_proxy, call_async, sync_dbus
-import jingletest2
-
-import dbus
-
-import constants as cs
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(q, bus, conn, stream, channel_type):
- jp = jingletest2.JingleProtocol031()
- jt = jingletest2.JingleTest2(jp, conn, q, stream, 'test@localhost',
- 'foo@bar.com/Foo')
- jt2 = jingletest2.JingleTest2(jp, conn, q, stream, 'test@localhost',
- 'foo2@bar.com/Foo')
- # Make gabble think this is a different client
- jt2.remote_caps['node'] = 'http://example.com/fake-client1'
-
- run_test(q, bus, conn, stream, jt, True, channel_type)
- run_test(q, bus, conn, stream, jt2, False, channel_type)
-
-def run_test(q, bus, conn, stream, jt, request_before_presence, channel_type):
- """
- Requests streams on a media channel to jt.peer, either before their
- presence is received (if request_before_presence is True) or after their
- presence is received but before we've got a disco response for their
- capabilities (otherwise).
- """
-
- # We intentionally DON'T set remote presence yet. Since Gabble is still
- # unsure whether to treat contact as offline for this purpose, it
- # will tentatively allow channel creation and contact handle addition
- request = dbus.Dictionary({ cs.CHANNEL_TYPE: channel_type,
- cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
- cs.TARGET_ID: jt.peer,
- }, signature='sv')
-
- if channel_type == cs.CHANNEL_TYPE_CALL:
- request[cs.CALL_INITIAL_AUDIO] = True
-
- if channel_type == cs.CHANNEL_TYPE_STREAMED_MEDIA:
- path, props = conn.CreateChannel(request,
- dbus_interface=cs.CONN_IFACE_REQUESTS)
- media_iface = make_channel_proxy(conn, path,
- 'Channel.Type.StreamedMedia')
-
- handle = props[cs.TARGET_HANDLE]
-
- sync_dbus(bus, q, conn)
-
- def call_request_streams():
- if channel_type == cs.CHANNEL_TYPE_STREAMED_MEDIA:
- call_async(q, media_iface, 'RequestStreams', handle,
- [cs.MEDIA_STREAM_TYPE_AUDIO])
- else:
- call_async(q, conn.Requests, 'CreateChannel', request)
-
- if request_before_presence:
- # Request streams before either <presence> or caps have arrived. Gabble
- # should wait for both to arrive before returning from RequestStreams.
- call_request_streams()
-
- # Ensure Gabble's received the method call.
- sync_dbus(bus, q, conn)
-
- # Now send the presence.
- info_event = jt.send_presence()
- else:
- info_event = jt.send_presence()
-
- # Now call RequestStreams; it should wait for the disco reply.
- call_request_streams()
-
- jt.send_remote_disco_reply(info_event.stanza)
-
- # RequestStreams should now happily complete
- if channel_type == cs.CHANNEL_TYPE_STREAMED_MEDIA:
- q.expect('dbus-return', method='RequestStreams')
- else:
- q.expect('dbus-return', method='CreateChannel')
-
-if __name__ == '__main__':
- exec_test(partial(test, channel_type=cs.CHANNEL_TYPE_STREAMED_MEDIA),
- timeout=10)
- exec_test(partial(test, channel_type=cs.CHANNEL_TYPE_CALL),
- timeout=10)
-
diff --git a/tests/twisted/jingle/transport-info-parsing.py b/tests/twisted/jingle/transport-info-parsing.py
deleted file mode 100644
index b84d84770..000000000
--- a/tests/twisted/jingle/transport-info-parsing.py
+++ /dev/null
@@ -1,86 +0,0 @@
-"""
-Test whether we parse the transport info with multiple contents correctly
-"""
-
-from gabbletest import exec_test
-from servicetest import ( make_channel_proxy, EventPattern,
- assertEquals, assertNotEquals )
-from jingletest2 import *
-
-from config import VOIP_ENABLED
-
-if not VOIP_ENABLED:
- print "NOTE: built with --disable-voip"
- raise SystemExit(77)
-
-def test(q, bus, conn, stream, peer='foo@bar.com/Foo'):
- jp = JingleProtocol031()
-
- jt = JingleTest2(jp, conn, q, stream, 'test@localhost', peer)
- jt.prepare()
-
- # Remote end calls us
- jt.incoming_call(audio = "Audio", video = "Video")
-
- e = q.expect ('dbus-signal', signal='NewSessionHandler')
- handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
- handler.Ready()
-
- events = q.expect_many (
- EventPattern('dbus-signal', signal='NewStreamHandler'),
- EventPattern('dbus-signal', signal='NewStreamHandler')
- )
- for e in events:
- handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
- handler.Ready([])
-
- candidate0 = (
- "1.2.3.4", # host
- 666, # port
- 0, # protocol = TP_MEDIA_STREAM_BASE_PROTO_UDP
- "RTP", # protocol subtype
- "AVP", # profile
- 1.0, # preference
- 0, # transport type = TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL,
- "username",
- "password" )
-
- candidate1 = (
- "5.6.7.8", # host
- 999, # port
- 0, # protocol = TP_MEDIA_STREAM_BASE_PROTO_UDP
- "RTP", # protocol subtype
- "AVP", # profile
- 1.0, # preference
- 0, # transport type = TP_MEDIA_STREAM_TRANSPORT_TYPE_LOCAL,
- "username",
- "password" )
-
- node = jp.SetIq(jt.peer, jt.jid, [
- jp.Jingle(jt.sid, jt.peer, 'transport-info', [
- jp.Content('Audio', 'initiator', 'both',
- transport = jp.TransportGoogleP2P([candidate0])),
- jp.Content('Video', 'initiator', 'both',
- transport = jp.TransportGoogleP2P([candidate1])),
- ] ) ])
-
- stream.send(jp.xml(node))
-
- q.expect ('stream-iq', iq_type='result')
- (c0, c1) = q.expect_many(
- EventPattern('dbus-signal', signal='AddRemoteCandidate'),
- EventPattern('dbus-signal', signal='AddRemoteCandidate'))
-
- assertNotEquals(c0.path, c1.path)
-
- mapping = { 666: candidate0, 999: candidate1}
-
- # Candidate without component number to compare
- candidate = c0.args[1][0][1:]
- assertEquals(mapping[candidate[1]], candidate)
-
- candidate = c1.args[1][0][1:]
- assertEquals(mapping[candidate[1]], candidate)
-
-if __name__ == '__main__':
- exec_test(test)
diff --git a/tests/twisted/last-activity.py b/tests/twisted/last-activity.py
index fd3da5a36..7f82e6f23 100644
--- a/tests/twisted/last-activity.py
+++ b/tests/twisted/last-activity.py
@@ -1,7 +1,7 @@
"""
Trivial smoke-test for XEP-0012 support.
"""
-from servicetest import assertEquals, assertContains
+from servicetest import assertEquals
from gabbletest import exec_test, elem, elem_iq
import ns
diff --git a/tests/twisted/mail-notification.py b/tests/twisted/mail-notification.py
index ef19c7d79..a56eee24f 100644
--- a/tests/twisted/mail-notification.py
+++ b/tests/twisted/mail-notification.py
@@ -56,7 +56,6 @@ def test_google_featured(q, bus, conn, stream):
# Email thread 3 data
thread3_id = "3"
thread3_date = 1235L
- thread3_url = 'http://mail.google.com/mail/#inbox/%x' % long(thread3_id)
thread3_senders = [('Le Chat', 'le@chat.fr'),]
thread3_subject = "subject3"
thread3_snippet = "body3"
@@ -333,7 +332,7 @@ def test_no_google_featured(q, bus, conn, stream):
def test(q, bus, conn, stream):
- interfaces = conn.GetInterfaces()
+ interfaces = conn.Properties.Get(cs.CONN, 'Interfaces')
if stream.__class__ is GoogleXmlStream:
assert cs.CONN_IFACE_MAIL_NOTIFICATION in interfaces
diff --git a/tests/twisted/muc/avatars.py b/tests/twisted/muc/avatars.py
index 91cc17f31..323b63b24 100644
--- a/tests/twisted/muc/avatars.py
+++ b/tests/twisted/muc/avatars.py
@@ -7,12 +7,11 @@
import hashlib
from servicetest import (
- call_async, EventPattern, assertEquals, assertLength, sync_dbus,
- wrap_channel,
+ call_async, EventPattern, assertEquals, assertLength, wrap_channel,
)
from gabbletest import (
exec_test, expect_and_handle_get_vcard, expect_and_handle_set_vcard,
- make_muc_presence, elem,
+ make_muc_presence,
)
from twisted.words.xish import xpath
import ns
@@ -35,7 +34,7 @@ def extract_hash_from_presence(stanza):
stanza)
def test(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
# When Gabble initially requests its avatar from the server, it discovers
# it has none.
@@ -101,13 +100,12 @@ def test(q, bus, conn, stream):
photo=AVATAR_1_SHA1))
path, _ = q.expect('dbus-return', method='CreateChannel').value
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text',
- ['Messages'])
+ chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
members = chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'Members')
assertLength(3, members)
- fredrik, wendy, muc_self_handle = conn.RequestHandles(cs.HT_CONTACT,
+ fredrik, wendy, muc_self_handle = conn.get_contact_handles_sync(
['%s/%s' % (MUC, x) for x in ["fredrik", "wendy", "test"]])
known = conn.Avatars.GetKnownAvatarTokens(members)
diff --git a/tests/twisted/muc/chat-states.py b/tests/twisted/muc/chat-states.py
index 4be5f50b2..5aaee085c 100644
--- a/tests/twisted/muc/chat-states.py
+++ b/tests/twisted/muc/chat-states.py
@@ -31,7 +31,7 @@ def check_state_notification(elem, name, allow_body=False):
assert len(elem.children) == 1, elem.toXml()
def test(q, bus, conn, stream):
- (muc_handle, chan, user, bob) = join_muc_and_check(q, bus, conn, stream,
+ (chan, user, bob) = join_muc_and_check(q, bus, conn, stream,
MUC)
states = chan.Properties.Get(cs.CHANNEL_IFACE_CHAT_STATE, 'ChatStates')
@@ -108,7 +108,7 @@ def test(q, bus, conn, stream):
# XEP 0085:
# every content message SHOULD contain an <active/> notification.
- chan.Text.Send(0, 'hi.')
+ chan.send_msg_sync('hi.')
stream_message = q.expect('stream-message')
stanza = stream_message.stanza
diff --git a/tests/twisted/muc/conference.py b/tests/twisted/muc/conference.py
index d8e87fa3c..5d5e8e7c1 100644
--- a/tests/twisted/muc/conference.py
+++ b/tests/twisted/muc/conference.py
@@ -3,8 +3,7 @@ Test the different ways to request a channel using the Conference interface
"""
from gabbletest import exec_test, make_muc_presence
-from servicetest import (call_async, EventPattern, assertEquals,
- assertContains)
+from servicetest import (call_async, assertEquals, assertContains)
import constants as cs
import dbus
diff --git a/tests/twisted/muc/kicked.py b/tests/twisted/muc/kicked.py
index e32648853..307b96f25 100644
--- a/tests/twisted/muc/kicked.py
+++ b/tests/twisted/muc/kicked.py
@@ -14,13 +14,14 @@ MUC = 'deerhoof@evil.lit'
def test(q, bus, conn, stream):
# The user happily joins a MUC
- _, chan, _, _ = join_muc(q, bus, conn, stream, MUC)
- muc_self_handle = chan.Group.GetSelfHandle()
- muc_self_jid, = conn.InspectHandles(cs.HT_CONTACT, [muc_self_handle])
+ chan, _, _ = join_muc(q, bus, conn, stream, MUC)
+ muc_self_handle = chan.Properties.Get(cs.CHANNEL_IFACE_GROUP,
+ "SelfHandle")
+ muc_self_jid = conn.inspect_contact_sync(muc_self_handle)
# But then Bob kicks us.
bob_jid = '%s/bob' % MUC
- bob_handle, = conn.RequestHandles(cs.HT_CONTACT, [bob_jid])
+ bob_handle = conn.get_contact_handle_sync(bob_jid)
stream.send(
elem('presence', from_=muc_self_jid, type='unavailable')(
elem(ns.MUC_USER, 'x')(
diff --git a/tests/twisted/muc/name-conflict.py b/tests/twisted/muc/name-conflict.py
index 512c16e0b..2aee8d2f3 100644
--- a/tests/twisted/muc/name-conflict.py
+++ b/tests/twisted/muc/name-conflict.py
@@ -78,7 +78,7 @@ def test_join(q, bus, conn, stream, room_jid, transient_conflict):
text_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
group_props = unwrap(text_chan.Properties.GetAll(cs.CHANNEL_IFACE_GROUP))
- t, t_ = conn.RequestHandles(cs.HT_CONTACT, [member, member_])
+ t, t_ = conn.get_contact_handles_sync([member, member_])
# Check that Gabble think our nickname in the room is test_, not test
muc_self_handle = group_props['SelfHandle']
@@ -101,7 +101,7 @@ def test_join(q, bus, conn, stream, room_jid, transient_conflict):
# Check that test_'s handle owner is us, and that test (if it's there) has
# no owner.
handle_owners = group_props['HandleOwners']
- assertEquals (conn.GetSelfHandle(), handle_owners[t_])
+ assertEquals (conn.Properties.Get(cs.CONN, "SelfHandle"), handle_owners[t_])
if not transient_conflict:
assertEquals (0, handle_owners[t])
@@ -184,8 +184,8 @@ def test_gtalk_weirdness(q, bus, conn, stream, room_jid):
# resources of the same contact. There is no race between this method
# returning and MembersChangedDetailed firing, because libdbus reorders
# messages when you make blocking calls.
- handle, handle_, handle__, foobar_handle = conn.RequestHandles(
- cs.HT_CONTACT, jids + ['%s/foobar_gmail.com' % room_jid])
+ handle, handle_, handle__, foobar_handle = conn.get_contact_handles_sync(
+ jids + ['%s/foobar_gmail.com' % room_jid])
q.expect('dbus-signal', signal='MembersChangedDetailed',
predicate=lambda e: e.args[0:4] == [[foobar_handle], [], [], []])
diff --git a/tests/twisted/muc/only-text-when-needed.py b/tests/twisted/muc/only-text-when-needed.py
index 260d26c8a..744e47ef0 100644
--- a/tests/twisted/muc/only-text-when-needed.py
+++ b/tests/twisted/muc/only-text-when-needed.py
@@ -3,14 +3,11 @@ Test support for creating MUC text channels when necessary, not all
the time.
"""
-import dbus
-
from servicetest import call_async, EventPattern, assertEquals, \
sync_dbus, wrap_channel
-from gabbletest import exec_test, acknowledge_iq, make_muc_presence, \
+from gabbletest import exec_test, make_muc_presence, \
sync_stream, elem
import constants as cs
-import ns
from mucutil import echo_muc_presence
@@ -295,7 +292,7 @@ def test_message(q, bus, conn, stream):
tube_chan, tube_path, _ = stream_tube(q, bus, conn, stream, 'CreateChannel', jid)
bob_jid = '%s/bob' % jid
- bob_handle = conn.RequestHandles(cs.HT_CONTACT, [bob_jid])[0]
+ bob_handle = conn.get_contact_handle_sync(bob_jid)
# now let's send a message
stream.send(
@@ -337,7 +334,7 @@ def test_requested_message(q, bus, conn, stream):
presence=False)
bob_jid = '%s/bob' % jid
- bob_handle = conn.RequestHandles(cs.HT_CONTACT, [bob_jid])[0]
+ bob_handle = conn.get_contact_handle_sync(bob_jid)
# make sure it says we requested it
props = text_chan.Properties.GetAll(cs.CHANNEL)
diff --git a/tests/twisted/muc/password.py b/tests/twisted/muc/password.py
index 7a67d17af..ee1ec3300 100644
--- a/tests/twisted/muc/password.py
+++ b/tests/twisted/muc/password.py
@@ -1,4 +1,4 @@
-from gabbletest import exec_test, elem, request_muc_handle, make_muc_presence
+from gabbletest import exec_test, elem, make_muc_presence
from servicetest import call_async, EventPattern, wrap_channel, assertEquals
import constants as cs
import ns
@@ -12,12 +12,11 @@ def expect_attempt(q, expected_muc_jid, expected_password):
def test(q, bus, conn, stream):
room = 'chat@conf.localhost'
- handle = request_muc_handle(q, conn, stream, room)
call_async(q, conn.Requests, 'CreateChannel', {
cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
- cs.TARGET_HANDLE: handle})
+ cs.TARGET_ID: room })
expected_muc_jid = '%s/%s' % (room, 'test')
q.expect('stream-presence', to=expected_muc_jid)
@@ -39,8 +38,7 @@ def test(q, bus, conn, stream):
EventPattern('dbus-signal', signal='PasswordFlagsChanged',
args=[cs.PASSWORD_FLAG_PROVIDE, 0]))
- chan = wrap_channel(bus.get_object(conn.bus_name, cc.value[0]), 'Text',
- ['Password'])
+ chan = wrap_channel(bus.get_object(conn.bus_name, cc.value[0]), 'Text')
flags = chan.Password.GetPasswordFlags()
assertEquals(cs.PASSWORD_FLAG_PROVIDE, flags)
diff --git a/tests/twisted/muc/presence-before-closing.py b/tests/twisted/muc/presence-before-closing.py
index b89abef4f..f2f96e54a 100644
--- a/tests/twisted/muc/presence-before-closing.py
+++ b/tests/twisted/muc/presence-before-closing.py
@@ -2,15 +2,11 @@
Test for fd.o#19930.
"""
-import dbus
-
-from twisted.words.xish import domish
-
from gabbletest import (
- exec_test, make_result_iq, request_muc_handle, wrap_channel, elem,
+ exec_test, wrap_channel, elem,
)
-from servicetest import (EventPattern, assertEquals, assertLength,
- assertContains, sync_dbus, call_async)
+from servicetest import (EventPattern, assertEquals,
+ sync_dbus, call_async)
import constants as cs
import ns
@@ -19,7 +15,7 @@ from mucutil import join_muc, echo_muc_presence
def test(q, bus, conn, stream):
room = 'test@conf.localhost'
- room_handle, chan, path, props, disco = join_muc(q, bus, conn, stream,
+ chan, path, props, disco = join_muc(q, bus, conn, stream,
room,
also_capture=[EventPattern('stream-iq', iq_type='get',
query_name='query', query_ns=ns.DISCO_INFO, to=room)])
@@ -56,7 +52,7 @@ def test(q, bus, conn, stream):
# now that the channel has finally closed, let's try and request
# it again which should succeed!
- _, chan, _, _ = join_muc(q, bus, conn, stream, room)
+ chan, _, _ = join_muc(q, bus, conn, stream, room)
# let's clear up though.
chan.Close()
@@ -68,7 +64,7 @@ def test(q, bus, conn, stream):
def test_then_disconnect(q, bus, conn, stream):
room = 'test@conf.localhost'
- room_handle, chan, path, props, disco = join_muc(q, bus, conn, stream,
+ chan, path, props, disco = join_muc(q, bus, conn, stream,
room,
also_capture=[EventPattern('stream-iq', iq_type='get',
query_name='query', query_ns=ns.DISCO_INFO, to=room)])
@@ -106,12 +102,11 @@ def test_then_disconnect(q, bus, conn, stream):
def test_with_password(q, bus, conn, stream):
room = 'chat@conf.localhost'
- handle = request_muc_handle(q, conn, stream, room)
call_async(q, conn.Requests, 'CreateChannel', {
cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
- cs.TARGET_HANDLE: handle})
+ cs.TARGET_ID: room })
expected_muc_jid = '%s/%s' % (room, 'test')
q.expect('stream-presence', to=expected_muc_jid)
diff --git a/tests/twisted/muc/renamed.py b/tests/twisted/muc/renamed.py
index ed86ed3ff..a5578b588 100644
--- a/tests/twisted/muc/renamed.py
+++ b/tests/twisted/muc/renamed.py
@@ -5,28 +5,27 @@ Test dealing with the server giving you a nick you didn't ask for.
import dbus
from gabbletest import (
- exec_test, make_muc_presence, request_muc_handle
+ exec_test, make_muc_presence
)
from servicetest import call_async, unwrap
from constants import (
- HT_CONTACT, HT_ROOM,
+ HT_ROOM,
CONN_IFACE_REQUESTS, CHANNEL_TYPE_TEXT, CHANNEL_IFACE_GROUP,
- CHANNEL_TYPE, TARGET_HANDLE_TYPE, TARGET_HANDLE,
+ CHANNEL_TYPE, TARGET_HANDLE_TYPE, TARGET_ID,
)
import constants as cs
def test(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
requests = dbus.Interface(conn, CONN_IFACE_REQUESTS)
room_jid = 'chat@conf.localhost'
- room_handle = request_muc_handle(q, conn, stream, room_jid)
call_async(q, requests, 'CreateChannel',
dbus.Dictionary({ CHANNEL_TYPE: CHANNEL_TYPE_TEXT,
TARGET_HANDLE_TYPE: HT_ROOM,
- TARGET_HANDLE: room_handle,
+ TARGET_ID: room_jid,
}, signature='sv'))
expected_jid = '%s/%s' % (room_jid, 'test')
@@ -54,7 +53,7 @@ def test(q, bus, conn, stream):
group_props = unwrap(text_chan.GetAll(CHANNEL_IFACE_GROUP,
dbus_interface=dbus.PROPERTIES_IFACE))
- liz, toofer, expected_handle = conn.RequestHandles(HT_CONTACT,
+ liz, toofer, expected_handle = conn.get_contact_handles_sync(
["%s/%s" % (room_jid, m) for m in ['liz', 'toofer', 'test']])
# Check that Gabble think our nickname in the room is toofer not test
diff --git a/tests/twisted/muc/room-config.py b/tests/twisted/muc/room-config.py
index ef5c78a74..c7cfd9282 100644
--- a/tests/twisted/muc/room-config.py
+++ b/tests/twisted/muc/room-config.py
@@ -8,9 +8,9 @@ from twisted.words.xish import xpath
from gabbletest import (
exec_test, make_result_iq, acknowledge_iq, make_muc_presence,
- request_muc_handle, sync_stream, disconnect_conn)
+ disconnect_conn)
from servicetest import (
- call_async, wrap_channel, EventPattern, assertEquals, assertSameSets,
+ call_async, EventPattern, assertEquals, assertSameSets,
assertContains,
)
from mucutil import join_muc
@@ -118,7 +118,7 @@ def handle_disco_info_iq(stream, stanza):
stream.send(iq)
def test_some_stuff(q, bus, conn, stream):
- _, text_chan, _, _, disco_iq, owner_iq, _ = join_muc(q, bus, conn, stream,
+ text_chan, _, _, disco_iq, owner_iq, _ = join_muc(q, bus, conn, stream,
'chat@conf.localhost', role='moderator', affiliation='owner',
also_capture=[
EventPattern('stream-iq', to='chat@conf.localhost', iq_type='get',
@@ -255,7 +255,7 @@ def test_role_changes(q, bus, conn, stream):
# The test user joins a room. Bob is an owner (and moderator); the test
# user starts out with no affiliation and the rôle of participant.
MUC = 'aoeu@snth'
- _, chan, _, immutable_props, disco = join_muc(q, bus, conn, stream,
+ chan, _, immutable_props, disco = join_muc(q, bus, conn, stream,
MUC, role='participant',
also_capture=[
EventPattern('stream-iq', to=MUC, iq_type='get',
@@ -331,7 +331,7 @@ def test_role_changes(q, bus, conn, stream):
def test_broken_server(q, bus, conn, stream):
MUC = 'bro@ken'
- _, chan, _ , _ = join_muc(q, bus, conn, stream, MUC, affiliation='owner')
+ chan, _ , _ = join_muc(q, bus, conn, stream, MUC, affiliation='owner')
owner_iq = q.expect('stream-iq', to=MUC, iq_type='get', query_ns=ns.MUC_OWNER)
handle_muc_owner_get_iq(stream, owner_iq.stanza)
@@ -350,7 +350,7 @@ def test_disconnect_during_update_configuration(q, bus, conn, stream):
changes to be acked.
"""
def join_me_up_buttercup(muc):
- _, chan, _, _ = join_muc(q, bus, conn, stream, muc, affiliation='owner')
+ chan, _, _ = join_muc(q, bus, conn, stream, muc, affiliation='owner')
# Gabble grabs the owner configuration form to see whether it's
# possible to change the room description.
owner_iq = q.expect('stream-iq', to=muc, iq_type='get',
diff --git a/tests/twisted/muc/room.py b/tests/twisted/muc/room.py
index e047fdc6e..a67a89fd4 100644
--- a/tests/twisted/muc/room.py
+++ b/tests/twisted/muc/room.py
@@ -3,12 +3,9 @@ Test the different ways to request a channel using the Room interface
"""
from gabbletest import exec_test, make_muc_presence
-from servicetest import (call_async, EventPattern, assertEquals,
- assertContains)
+from servicetest import (call_async, assertEquals)
import constants as cs
-import dbus
-
import re
def create_muc(q, conn, stream, props):
diff --git a/tests/twisted/muc/roomlist.py b/tests/twisted/muc/roomlist.py
index cd29dc254..d16fc8987 100644
--- a/tests/twisted/muc/roomlist.py
+++ b/tests/twisted/muc/roomlist.py
@@ -6,7 +6,7 @@ Test MUC support.
import dbus
from gabbletest import make_result_iq, exec_test, sync_stream, disconnect_conn
-from servicetest import call_async, EventPattern, tp_name_prefix
+from servicetest import call_async, EventPattern, assertEquals
import constants as cs
def test(q, bus, conn, stream):
@@ -32,129 +32,55 @@ def test(q, bus, conn, stream):
# Make sure the stream has been processed
sync_stream(q, stream)
- properties = conn.GetAll(
- tp_name_prefix + '.Connection.Interface.Requests',
- dbus_interface=dbus.PROPERTIES_IFACE)
+ properties = conn.Properties.GetAll(cs.CONN_IFACE_REQUESTS)
assert properties.get('Channels') == [], properties['Channels']
- assert ({tp_name_prefix + '.Channel.ChannelType':
- tp_name_prefix + '.Channel.Type.RoomList',
- tp_name_prefix + '.Channel.TargetHandleType': 0,
+ assert ({ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_ROOM_LIST,
+ cs.TARGET_HANDLE_TYPE: cs.HT_NONE,
},
- [tp_name_prefix + '.Channel.Type.RoomList.Server'],
+ [cs.CHANNEL_TYPE_ROOM_LIST + '.Server'],
) in properties.get('RequestableChannelClasses'),\
properties['RequestableChannelClasses']
- call_async(q, conn, 'RequestChannel',
- tp_name_prefix + '.Channel.Type.RoomList', 0, 0, True)
-
- ret, old_sig, new_sig = q.expect_many(
- EventPattern('dbus-return', method='RequestChannel'),
- EventPattern('dbus-signal', signal='NewChannel'),
- EventPattern('dbus-signal', signal='NewChannels'),
- )
-
- bus = dbus.SessionBus()
- path1 = ret.value[0]
- chan = bus.get_object(conn.bus_name, path1)
-
- assert new_sig.args[0][0][0] == path1
-
- props = new_sig.args[0][0][1]
- assert props[tp_name_prefix + '.Channel.ChannelType'] ==\
- tp_name_prefix + '.Channel.Type.RoomList'
- assert props[tp_name_prefix + '.Channel.TargetHandleType'] == 0
- assert props[tp_name_prefix + '.Channel.TargetHandle'] == 0
- assert props[tp_name_prefix + '.Channel.TargetID'] == ''
- assert props[tp_name_prefix + '.Channel.Requested'] == True
- assert props[tp_name_prefix + '.Channel.InitiatorHandle'] \
- == conn.GetSelfHandle()
- assert props[tp_name_prefix + '.Channel.InitiatorID'] \
- == 'test@localhost'
- assert props[tp_name_prefix + '.Channel.Type.RoomList.Server'] == \
- 'conf.localhost'
-
- assert old_sig.args[0] == path1
- assert old_sig.args[1] == tp_name_prefix + '.Channel.Type.RoomList'
- assert old_sig.args[2] == 0 # handle type
- assert old_sig.args[3] == 0 # handle
- assert old_sig.args[4] == 1 # suppress handler
-
- # Exercise basic Channel Properties from spec 0.17.7
- channel_props = chan.GetAll(
- tp_name_prefix + '.Channel',
- dbus_interface=dbus.PROPERTIES_IFACE)
- assert channel_props.get('TargetHandle') == 0,\
- channel_props.get('TargetHandle')
- assert channel_props['TargetID'] == '', channel_props
- assert channel_props.get('TargetHandleType') == 0,\
- channel_props.get('TargetHandleType')
- assert channel_props.get('ChannelType') == \
- tp_name_prefix + '.Channel.Type.RoomList',\
- channel_props.get('ChannelType')
- assert channel_props['Requested'] == True
- assert channel_props['InitiatorID'] == 'test@localhost'
- assert channel_props['InitiatorHandle'] == conn.GetSelfHandle()
-
- assert chan.Get(
- tp_name_prefix + '.Channel.Type.RoomList', 'Server',
- dbus_interface=dbus.PROPERTIES_IFACE) == \
- 'conf.localhost'
-
# FIXME: actually list the rooms!
call_async(q, conn.Requests, 'CreateChannel',
- { tp_name_prefix + '.Channel.ChannelType':
- tp_name_prefix + '.Channel.Type.RoomList',
- tp_name_prefix + '.Channel.TargetHandleType': 0,
- tp_name_prefix + '.Channel.Type.RoomList.Server':
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_ROOM_LIST,
+ cs.TARGET_HANDLE_TYPE: cs.HT_NONE,
+ cs.CHANNEL_TYPE_ROOM_LIST + '.Server':
'conference.example.net',
})
- ret, old_sig, new_sig = q.expect_many(
+ ret, sig = q.expect_many(
EventPattern('dbus-return', method='CreateChannel'),
- EventPattern('dbus-signal', signal='NewChannel'),
EventPattern('dbus-signal', signal='NewChannels'),
)
path2 = ret.value[0]
chan = bus.get_object(conn.bus_name, path2)
props = ret.value[1]
- assert props[tp_name_prefix + '.Channel.ChannelType'] ==\
- tp_name_prefix + '.Channel.Type.RoomList'
- assert props[tp_name_prefix + '.Channel.TargetHandleType'] == 0
- assert props[tp_name_prefix + '.Channel.TargetHandle'] == 0
- assert props[tp_name_prefix + '.Channel.TargetID'] == ''
- assert props[tp_name_prefix + '.Channel.Requested'] == True
- assert props[tp_name_prefix + '.Channel.InitiatorHandle'] \
- == conn.GetSelfHandle()
- assert props[tp_name_prefix + '.Channel.InitiatorID'] \
- == 'test@localhost'
- assert props[tp_name_prefix + '.Channel.Type.RoomList.Server'] == \
- 'conference.example.net'
-
- assert new_sig.args[0][0][0] == path2
- assert new_sig.args[0][0][1] == props
-
- assert old_sig.args[0] == path2
- assert old_sig.args[1] == tp_name_prefix + '.Channel.Type.RoomList'
- assert old_sig.args[2] == 0 # handle type
- assert old_sig.args[3] == 0 # handle
- assert old_sig.args[4] == 1 # suppress handler
-
- assert chan.Get(
- tp_name_prefix + '.Channel.Type.RoomList', 'Server',
+ assertEquals(cs.CHANNEL_TYPE_ROOM_LIST, props[cs.CHANNEL_TYPE])
+ assertEquals(cs.HT_NONE, props[cs.TARGET_HANDLE_TYPE])
+ assertEquals(0, props[cs.TARGET_HANDLE])
+ assertEquals('', props[cs.TARGET_ID])
+ assertEquals(True, props[cs.REQUESTED])
+ assertEquals(conn.Properties.Get(cs.CONN, "SelfHandle"), props[cs.INITIATOR_HANDLE])
+ assertEquals('test@localhost', props[cs.INITIATOR_ID])
+ assertEquals('conference.example.net', props[cs.CHANNEL_TYPE_ROOM_LIST+ '.Server'])
+
+ assert sig.args[0][0][0] == path2
+ assert sig.args[0][0][1] == props
+
+ assert chan.Get(cs.CHANNEL_TYPE_ROOM_LIST, 'Server',
dbus_interface=dbus.PROPERTIES_IFACE) == \
'conference.example.net'
# FIXME: actually list the rooms!
call_async(q, conn.Requests, 'EnsureChannel',
- { tp_name_prefix + '.Channel.ChannelType':
- tp_name_prefix + '.Channel.Type.RoomList',
- tp_name_prefix + '.Channel.TargetHandleType': 0,
- tp_name_prefix + '.Channel.Type.RoomList.Server':
- 'conference.example.net',
- })
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_ROOM_LIST,
+ cs.TARGET_HANDLE_TYPE: cs.HT_NONE,
+ cs.CHANNEL_TYPE_ROOM_LIST + '.Server': 'conference.example.net',
+ })
ret = q.expect('dbus-return', method='EnsureChannel')
yours, ensured_path, ensured_props = ret.value
@@ -163,9 +89,7 @@ def test(q, bus, conn, stream):
assert ensured_path == path2, (ensured_path, path2)
disconnect_conn(q, conn, stream, [
- EventPattern('dbus-signal', signal='Closed', path=path1),
EventPattern('dbus-signal', signal='Closed', path=path2),
- EventPattern('dbus-signal', signal='ChannelClosed', args=[path1]),
EventPattern('dbus-signal', signal='ChannelClosed', args=[path2])])
if __name__ == '__main__':
diff --git a/tests/twisted/muc/scrollback.py b/tests/twisted/muc/scrollback.py
index 607d3c6f8..a1f75c62f 100644
--- a/tests/twisted/muc/scrollback.py
+++ b/tests/twisted/muc/scrollback.py
@@ -7,12 +7,9 @@ MUC's bare JID.
Also acts as a scrollback messages in general!
"""
-import dbus
-
from servicetest import assertEquals, assertContains
from gabbletest import exec_test, elem
-import constants as cs
import ns
from mucutil import join_muc_and_check
@@ -23,7 +20,7 @@ def test(q, bus, conn, stream):
bob_jid = room + '/bob'
marco_jid = room + '/marco'
- room_handle, chan, test_handle, bob_handle = \
+ chan, test_handle, bob_handle = \
join_muc_and_check(q, bus, conn, stream, room)
# Here are a few scrollback messages. One from us; one from bob; and one
@@ -74,8 +71,7 @@ def test(q, bus, conn, stream):
marco = badger(m3)
assertEquals([our_jid, bob_jid, marco_jid],
- conn.InspectHandles(cs.HT_CONTACT,
- [ me, bob, marco ]))
+ conn.inspect_contacts_sync([ me, bob, marco ]))
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/muc/send-error.py b/tests/twisted/muc/send-error.py
index 33f376bf5..4f59fbd18 100644
--- a/tests/twisted/muc/send-error.py
+++ b/tests/twisted/muc/send-error.py
@@ -2,7 +2,6 @@
Test incoming error messages in MUC channels.
"""
-import warnings
import dbus
from gabbletest import exec_test
@@ -14,7 +13,7 @@ from mucutil import join_muc_and_check
def test(q, bus, conn, stream):
muc = 'chat@conf.localhost'
- _, text_chan, test_handle, bob_handle = \
+ text_chan, test_handle, bob_handle = \
join_muc_and_check(q, bus, conn, stream, muc)
# Suppose we don't have permission to speak in this MUC. Send a message to
@@ -69,9 +68,8 @@ def send_message_and_expect_error(q, stream,
sent_token = text_chan.Messages.SendMessage(greeting, dbus.UInt32(0))
- stream_message, _, _ = q.expect_many(
+ stream_message, _ = q.expect_many(
EventPattern('stream-message'),
- EventPattern('dbus-signal', signal='Sent'),
EventPattern('dbus-signal', signal='MessageSent'),
)
@@ -92,36 +90,7 @@ def send_message_and_expect_error(q, stream,
stream.send(elem)
- # check that we got a failed delivery report and a SendError
- send_error, received, message_received = q.expect_many(
- EventPattern('dbus-signal', signal='SendError'),
- EventPattern('dbus-signal', signal='Received'),
- EventPattern('dbus-signal', signal='MessageReceived'),
- )
-
- err, timestamp, type, text = send_error.args
- assertEquals(send_error_value, err)
- # there's no way to tell when the original message was sent from the error stanza
- assertEquals(0, timestamp)
- # Gabble can't determine the type of the original message; see muc/test-muc.py
- # assert type == 0, send_error.args
- assertEquals(content, text)
-
- # The Text.Received signal should be a "you're not tall enough" stub
- id, timestamp, sender, type, flags, text = received.args
-
- assertEquals(0, sender)
- assertEquals(type, cs.MT_DELIVERY_REPORT)
-
- if flags == 0:
- warnings.warn("ignoring tp-glib bug #61254")
- else:
- assertEquals(cs.MessageFlag.NON_TEXT_CONTENT, flags)
-
- if error_message is None:
- assertEquals('', text)
- else:
- assertEquals(error_message, text)
+ message_received = q.expect('dbus-signal', signal='MessageReceived')
# Check that the Messages.MessageReceived signal was a failed delivery report
assertLength(1, message_received.args)
diff --git a/tests/twisted/muc/subject.py b/tests/twisted/muc/subject.py
index e83c0fc16..c323331ec 100644
--- a/tests/twisted/muc/subject.py
+++ b/tests/twisted/muc/subject.py
@@ -7,8 +7,7 @@ import dbus
from twisted.words.xish import domish
from gabbletest import exec_test, make_result_iq, make_muc_presence
-from servicetest import (EventPattern, assertEquals, assertLength,
- assertContains, call_async)
+from servicetest import (EventPattern, assertEquals, call_async)
import constants as cs
import ns
@@ -46,7 +45,7 @@ def test_subject(q, bus, conn, stream, change_subject, send_first,
moderator):
room = 'test@conf.localhost'
- room_handle, chan, path, props, disco = join_muc(q, bus, conn, stream,
+ chan, path, props, disco = join_muc(q, bus, conn, stream,
room,
also_capture=[EventPattern('stream-iq', iq_type='get',
query_name='query', query_ns=ns.DISCO_INFO, to=room)],
diff --git a/tests/twisted/muc/test-ensure.py b/tests/twisted/muc/test-ensure.py
index e03ae3567..858385256 100644
--- a/tests/twisted/muc/test-ensure.py
+++ b/tests/twisted/muc/test-ensure.py
@@ -3,7 +3,7 @@ Test that EnsureChannel works for MUCs, particularly in the case when there
are several pending requests for the same MUC.
"""
-from gabbletest import make_result_iq, exec_test, make_muc_presence
+from gabbletest import exec_test, make_muc_presence
from servicetest import (call_async, EventPattern, assertContains,
assertEquals)
import constants as cs
@@ -12,31 +12,27 @@ def test(q, bus, conn, stream):
# Need to call this asynchronously as it involves Gabble sending us a
# query.
jids = ['chat@conf.localhost', 'chien@conf.localhost']
- call_async(q, conn, 'RequestHandles', 2, jids)
- event = q.expect('dbus-return', method='RequestHandles')
- room_handles = event.value[0]
+ test_create_ensure(q, conn, bus, stream, jids[0])
+ test_ensure_ensure(q, conn, bus, stream, jids[1])
- test_create_ensure(q, conn, bus, stream, jids[0], room_handles[0])
- test_ensure_ensure(q, conn, bus, stream, jids[1], room_handles[1])
-
-def test_create_ensure(q, conn, bus, stream, room_jid, room_handle):
+def test_create_ensure(q, conn, bus, stream, room_jid):
# Call both Create and Ensure for the same channel.
call_async(q, conn.Requests, 'CreateChannel',
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
- cs.TARGET_HANDLE: room_handle,
+ cs.TARGET_ID: room_jid,
})
call_async(q, conn.Requests, 'EnsureChannel',
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
- cs.TARGET_HANDLE: room_handle,
+ cs.TARGET_ID: room_jid,
})
mc, _ = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged'),
+ EventPattern('dbus-signal', signal='MembersChangedDetailed'),
EventPattern('stream-presence', to=('%s/test' % room_jid)))
- msg, added, removed, local_pending, remote_pending, actor, reason = mc.args
+ added, removed, local_pending, remote_pending, details = mc.args
assert added == [], mc.args
assert removed == [], mc.args
@@ -49,15 +45,15 @@ def test_create_ensure(q, conn, bus, stream, room_jid, room_handle):
# Send presence for own membership of room.
stream.send(make_muc_presence('none', 'participant', room_jid, 'test'))
- mc = q.expect('dbus-signal', signal='MembersChanged')
- msg, added, removed, local_pending, remote_pending, actor, reason = mc.args
+ mc = q.expect('dbus-signal', signal='MembersChangedDetailed')
+ added, removed, local_pending, remote_pending, details = mc.args
assert len(added) == 2, mc.args
assert removed == [], mc.args
assert local_pending == [], mc.args
assert remote_pending == [], mc.args
- members = conn.InspectHandles(1, added)
+ members = conn.inspect_contacts_sync(added)
members.sort()
assert members == ['%s/bob' % room_jid, '%s/test' % room_jid], members
@@ -84,23 +80,23 @@ def test_create_ensure(q, conn, bus, stream, room_jid, room_handle):
c_props[cs.DELIVERY_REPORTING_SUPPORT])
-def test_ensure_ensure(q, conn, bus, stream, room_jid, room_handle):
+def test_ensure_ensure(q, conn, bus, stream, room_jid):
# Call Ensure twice for the same channel.
call_async(q, conn.Requests, 'EnsureChannel',
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
- cs.TARGET_HANDLE: room_handle,
+ cs.TARGET_ID: room_jid,
})
call_async(q, conn.Requests, 'EnsureChannel',
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
- cs.TARGET_HANDLE: room_handle,
+ cs.TARGET_ID: room_jid,
})
mc, _ = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged'),
+ EventPattern('dbus-signal', signal='MembersChangedDetailed'),
EventPattern('stream-presence', to=('%s/test' % room_jid)))
- msg, added, removed, local_pending, remote_pending, actor, reason = mc.args
+ added, removed, local_pending, remote_pending, details = mc.args
assert added == [], mc.args
assert removed == [], mc.args
@@ -113,15 +109,15 @@ def test_ensure_ensure(q, conn, bus, stream, room_jid, room_handle):
# Send presence for own membership of room.
stream.send(make_muc_presence('none', 'participant', room_jid, 'test'))
- mc = q.expect('dbus-signal', signal='MembersChanged')
- msg, added, removed, local_pending, remote_pending, actor, reason = mc.args
+ mc = q.expect('dbus-signal', signal='MembersChangedDetailed')
+ added, removed, local_pending, remote_pending, details = mc.args
assert len(added) == 2, mc.args
assert removed == [], mc.args
assert local_pending == [], mc.args
assert remote_pending == [], mc.args
- members = conn.InspectHandles(1, added)
+ members = conn.inspect_contacts_sync(added)
members.sort()
assert members == ['%s/bob' % room_jid, '%s/test' % room_jid], members
diff --git a/tests/twisted/muc/test-muc-alias.py b/tests/twisted/muc/test-muc-alias.py
index edfd78b96..a07af1c06 100644
--- a/tests/twisted/muc/test-muc-alias.py
+++ b/tests/twisted/muc/test-muc-alias.py
@@ -2,7 +2,7 @@
Test that our alias is used to create MUC JIDs.
"""
-from gabbletest import exec_test, make_muc_presence, request_muc_handle, \
+from gabbletest import exec_test, make_muc_presence, \
expect_and_handle_get_vcard, expect_and_handle_set_vcard
from servicetest import call_async, EventPattern
@@ -11,7 +11,7 @@ import constants as cs
def test(q, bus, conn, stream):
expect_and_handle_get_vcard(q, stream)
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
conn.Aliasing.SetAliases({self_handle: 'lala'})
expect_and_handle_set_vcard(q, stream)
@@ -20,15 +20,24 @@ def test(q, bus, conn, stream):
args=[[(self_handle, u'lala')]])
room_jid = 'chat@conf.localhost'
- room_handle = request_muc_handle(q, conn, stream, room_jid)
- call_async(q, conn, 'RequestChannel', cs.CHANNEL_TYPE_TEXT, cs.HT_ROOM,
- room_handle, True)
+ # muc stream tube
+ call_async(q, conn.Requests, 'CreateChannel', {
+ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
+ cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
+ cs.TARGET_ID: room_jid})
gfc, _, _ = q.expect_many(
EventPattern('dbus-signal', signal='GroupFlagsChanged'),
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [], [], [], [2], 0, 0]),
+ EventPattern('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e:
+ e.args[0] == [] and # added
+ e.args[1] == [] and # removed
+ e.args[2] == [] and # local pending
+ len(e.args[3]) == 1 and # remote pending
+ e.args[4].get('actor', 0) == 0 and
+ e.args[4].get('change-reason', 0) == 0 and
+ e.args[4]['contact-ids'][e.args[3][0]] == 'chat@conf.localhost/lala'),
EventPattern('stream-presence', to='%s/lala' % room_jid))
assert gfc.args[1] == 0
@@ -38,12 +47,18 @@ def test(q, bus, conn, stream):
# Send presence for own membership of room.
stream.send(make_muc_presence('none', 'participant', room_jid, 'lala'))
- event = q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [2, 3], [], [], [], 0, 0])
- assert conn.InspectHandles(1, [2]) == ['chat@conf.localhost/lala']
- assert conn.InspectHandles(1, [3]) == ['chat@conf.localhost/bob']
+ event = q.expect('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e:
+ len(e.args[0]) == 2 and # added
+ e.args[1] == [] and # removed
+ e.args[2] == [] and # local pending
+ e.args[3] == [] and # remote pending
+ e.args[4].get('actor', 0) == 0 and
+ e.args[4].get('change-reason', 0) == 0 and
+ set([e.args[4]['contact-ids'][h] for h in e.args[0]]) ==
+ set(['chat@conf.localhost/lala', 'chat@conf.localhost/bob']))
- event = q.expect('dbus-return', method='RequestChannel')
+ event = q.expect('dbus-return', method='CreateChannel')
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/muc/test-muc-invitation.py b/tests/twisted/muc/test-muc-invitation.py
index e30c68dc2..6cc8efc44 100644
--- a/tests/twisted/muc/test-muc-invitation.py
+++ b/tests/twisted/muc/test-muc-invitation.py
@@ -2,12 +2,10 @@
Test MUC invitations.
"""
-import dbus
-
from twisted.words.xish import domish, xpath
from gabbletest import exec_test, make_muc_presence
-from servicetest import call_async, EventPattern
+from servicetest import call_async, EventPattern, wrap_channel, assertEquals
import constants as cs
def test(q, bus, conn, stream):
@@ -23,34 +21,32 @@ def test(q, bus, conn, stream):
stream.send(message)
- event = q.expect('dbus-signal', signal='NewChannel')
- assert event.args[1] == cs.CHANNEL_TYPE_TEXT
-
- assert event.args[2] == 2 # handle type
- assert event.args[3] == 1 # handle
- room_handle = 1
+ event = q.expect('dbus-signal', signal='NewChannels')
+ path, props = event.args[0][0]
+ assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE])
+ assertEquals(cs.HT_ROOM, props[cs.TARGET_HANDLE_TYPE])
+ assertEquals(1, props[cs.TARGET_HANDLE])
- text_chan = bus.get_object(conn.bus_name, event.args[0])
- group_iface = dbus.Interface(text_chan, cs.CHANNEL_IFACE_GROUP)
+ text_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
- members = group_iface.GetMembers()
- local_pending = group_iface.GetLocalPendingMembers()
- remote_pending = group_iface.GetRemotePendingMembers()
+ members = text_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'Members')
+ local_pending = text_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'LocalPendingMembers')
+ remote_pending = text_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'RemotePendingMembers')
assert len(members) == 1
- assert conn.InspectHandles(1, members)[0] == 'bob@localhost'
+ assert conn.inspect_contact_sync(members[0]) == 'bob@localhost'
bob_handle = members[0]
assert len(local_pending) == 1
# FIXME: the username-part-is-nickname assumption
- assert conn.InspectHandles(1, local_pending)[0] == \
+ assert conn.inspect_contact_sync(local_pending[0][0]) == \
'chat@conf.localhost/test'
assert len(remote_pending) == 0
- room_self_handle = group_iface.GetSelfHandle()
- assert room_self_handle == local_pending[0]
+ room_self_handle = text_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP,
+ "SelfHandle")
+ assert room_self_handle == local_pending[0][0]
- channel_props = text_chan.GetAll(
- cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE)
+ channel_props = text_chan.Properties.GetAll(cs.CHANNEL)
assert channel_props['TargetID'] == 'chat@conf.localhost', channel_props
assert channel_props['Requested'] == False
assert channel_props['InitiatorID'] == 'bob@localhost'
@@ -62,11 +58,11 @@ def test(q, bus, conn, stream):
conn.SimplePresence.SetPresence('available', 'success')
# accept the invitation
- call_async(q, group_iface, 'AddMembers', [room_self_handle], 'Oh, OK then')
+ call_async(q, text_chan.Group, 'AddMembers', [room_self_handle], 'Oh, OK then')
event, event2, _ = q.expect_many(
EventPattern('stream-presence', to='chat@conf.localhost/test'),
- EventPattern('dbus-signal', signal='MembersChanged'),
+ EventPattern('dbus-signal', signal='MembersChangedDetailed'),
EventPattern('dbus-return', method='AddMembers')
)
@@ -81,8 +77,12 @@ def test(q, bus, conn, stream):
# We are added as remote pending while joining the room. The inviter (Bob)
# is removed for now. It will be re-added with his channel specific handle
# once we have joined.
- assert event2.args == ['', [], [bob_handle], [],
- [room_self_handle], 0, cs.GC_REASON_INVITED]
+ added, removed, local_pending, remote_pending, details = event2.args
+ assertEquals([], added)
+ assertEquals([bob_handle], removed)
+ assertEquals([], local_pending)
+ assertEquals([room_self_handle], remote_pending)
+ assertEquals(cs.GC_REASON_INVITED, details['change-reason'])
# Send presence for Bob's membership of room.
stream.send(make_muc_presence('owner', 'moderator', 'chat@conf.localhost', 'bob'))
@@ -90,14 +90,19 @@ def test(q, bus, conn, stream):
# Send presence for own membership of room.
stream.send(make_muc_presence('owner', 'moderator', 'chat@conf.localhost', 'test'))
- event = q.expect('dbus-signal', signal='MembersChanged')
+ event = q.expect('dbus-signal', signal='MembersChangedDetailed')
+
+ room_bob_handle = conn.get_contact_handle_sync('chat@conf.localhost/bob')
- room_bob_handle = conn.RequestHandles(cs.HT_CONTACT, ['chat@conf.localhost/bob'])[0]
- assert event.args == ['', [room_self_handle, room_bob_handle], [], [], [], 0, 0]
+ added, removed, local_pending, remote_pending, details = event.args
+ assertEquals([room_self_handle, room_bob_handle], added)
+ assertEquals([], removed)
+ assertEquals([], local_pending)
+ assertEquals([], remote_pending)
# Test sending an invitation
- alice_handle = conn.RequestHandles(1, ['alice@localhost'])[0]
- call_async(q, group_iface, 'AddMembers', [alice_handle],
+ alice_handle = conn.get_contact_handle_sync('alice@localhost')
+ call_async(q, text_chan.Group, 'AddMembers', [alice_handle],
'I want to test invitations')
event = q.expect('stream-message', to='chat@conf.localhost')
diff --git a/tests/twisted/muc/test-muc-ownership.py b/tests/twisted/muc/test-muc-ownership.py
index f0f2d504f..9ac2c84cd 100644
--- a/tests/twisted/muc/test-muc-ownership.py
+++ b/tests/twisted/muc/test-muc-ownership.py
@@ -1,15 +1,13 @@
"""
Test support for the HANDLE_OWNERS_NOT_AVAILABLE group flag, and calling
-GetHandleOwners on MUC members.
+HandleOwners on MUC members.
By default, MUC channels should have the flag set. The flag should be unset
when presence is received that includes the MUC JID's owner JID.
"""
-import dbus
-
-from gabbletest import make_result_iq, exec_test, make_muc_presence
+from gabbletest import exec_test, make_muc_presence
from servicetest import (
call_async, EventPattern, assertEquals, assertFlagsSet, assertFlagsUnset,
wrap_channel,
@@ -17,18 +15,20 @@ from servicetest import (
import constants as cs
def test(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
- room_handle = conn.RequestHandles(cs.HT_ROOM, ['chat@conf.localhost'])[0]
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
- call_async(q, conn, 'RequestChannel', cs.CHANNEL_TYPE_TEXT, cs.HT_ROOM,
- room_handle, True)
+ call_async(q, conn.Requests, 'CreateChannel',
+ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
+ cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
+ cs.TARGET_ID: 'chat@conf.localhost'
+ })
gfc, _, _, _ = q.expect_many(
# Initial group flags
EventPattern('dbus-signal', signal='GroupFlagsChanged',
predicate=lambda e: e.args[0] != 0),
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [], [], [], [2], 0, 0]),
+ EventPattern('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e: e.args[3] == [2]),
# Removing CAN_ADD
EventPattern('dbus-signal', signal='GroupFlagsChanged',
args = [0, cs.GF_CAN_ADD], predicate=lambda e: e.args[0] == 0),
@@ -60,11 +60,11 @@ def test(q, bus, conn, stream):
event = q.expect('dbus-signal', signal='HandleOwnersChanged')
owners = event.args[0]
- event = q.expect('dbus-signal', signal='MembersChanged')
- added = event.args[1]
+ event = q.expect('dbus-signal', signal='MembersChangedDetailed')
+ added = event.args[0]
[test, bob, brian, che, che_owner, chris, chris_owner] = \
- conn.RequestHandles(cs.HT_CONTACT,
+ conn.get_contact_handles_sync(
[ 'chat@conf.localhost/test', 'chat@conf.localhost/bob',
'chat@conf.localhost/brian', 'chat@conf.localhost/che',
'che@foo.com', 'chat@conf.localhost/chris', 'chris@foo.com',
@@ -79,13 +79,14 @@ def test(q, bus, conn, stream):
assertEquals(expected_members, sorted(added))
assertEquals(expected_owners, owners)
- event = q.expect('dbus-return', method='RequestChannel')
+ event = q.expect('dbus-return', method='CreateChannel')
chan = wrap_channel(bus.get_object(conn.bus_name, event.value[0]), 'Text')
- # Exercise GetHandleOwners
- assertEquals([che_owner, chris_owner],
- chan.Group.GetHandleOwners([che, chris]))
+ # Exercise HandleOwners
+ owners = chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'HandleOwners')
+ assertEquals(che_owner, owners[che])
+ assertEquals(chris_owner, owners[chris])
# Exercise D-Bus properties
all = chan.Properties.GetAll(cs.CHANNEL_IFACE_GROUP)
@@ -97,7 +98,7 @@ def test(q, bus, conn, stream):
assert all[u'HandleOwners'] == expected_owners, all
flags = all[u'GroupFlags']
- assertFlagsSet(cs.GF_PROPERTIES | cs.GF_CHANNEL_SPECIFIC_HANDLES, flags)
+ assertFlagsSet(cs.GF_CHANNEL_SPECIFIC_HANDLES, flags)
assertFlagsUnset(cs.GF_HANDLE_OWNERS_NOT_AVAILABLE, flags)
if __name__ == '__main__':
diff --git a/tests/twisted/muc/test-muc.py b/tests/twisted/muc/test-muc.py
index a254d8ee8..8daedb251 100644
--- a/tests/twisted/muc/test-muc.py
+++ b/tests/twisted/muc/test-muc.py
@@ -19,26 +19,24 @@ from mucutil import join_muc_and_check
def test(q, bus, conn, stream):
room = 'chat@conf.localhost'
- room_handle, chan, test_handle, bob_handle = \
+ chan, test_handle, bob_handle = \
join_muc_and_check(q, bus, conn, stream, room)
# Exercise basic Channel Properties from spec 0.17.7
channel_props = chan.Properties.GetAll(cs.CHANNEL)
- assertEquals(room_handle, channel_props.get('TargetHandle'))
assertEquals(cs.HT_ROOM, channel_props.get('TargetHandleType'))
assertEquals(cs.CHANNEL_TYPE_TEXT, channel_props.get('ChannelType'))
interfaces = channel_props.get('Interfaces')
assertContains(cs.CHANNEL_IFACE_GROUP, interfaces)
assertContains(cs.CHANNEL_IFACE_PASSWORD, interfaces)
- assertDoesNotContain(cs.TP_AWKWARD_PROPERTIES, interfaces)
assertContains(cs.CHANNEL_IFACE_CHAT_STATE, interfaces)
assertContains(cs.CHANNEL_IFACE_MESSAGES, interfaces)
assert channel_props['TargetID'] == 'chat@conf.localhost', channel_props
assert channel_props['Requested'] == True
assert channel_props['InitiatorID'] == 'test@localhost'
- assert channel_props['InitiatorHandle'] == conn.GetSelfHandle()
+ assert channel_props['InitiatorHandle'] == conn.Properties.Get(cs.CONN, "SelfHandle")
# Exercise Group Properties from spec 0.17.6 (in a basic way)
group_props = chan.Properties.GetAll(cs.CHANNEL_IFACE_GROUP)
@@ -56,20 +54,7 @@ def test(q, bus, conn, stream):
body = message.addElement('body', content='hello')
stream.send(message)
- received, message_received = q.expect_many(
- EventPattern('dbus-signal', signal='Received'),
- EventPattern('dbus-signal', signal='MessageReceived'),
- )
-
- # Check Channel.Type.Text.Received:
- # sender: bob
- assert received.args[2] == bob_handle
- # message type: normal
- assert received.args[3] == 0
- # flags: none
- assert received.args[4] == 0
- # body
- assert received.args[5] == 'hello'
+ message_received = q.expect('dbus-signal', signal='MessageReceived')
# Check Channel.Interface.Messages.MessageReceived:
message = message_received.args[0]
@@ -117,9 +102,8 @@ def test(q, bus, conn, stream):
assert sent_token
- stream_message, sent, message_sent = q.expect_many(
+ stream_message, message_sent = q.expect_many(
EventPattern('stream-message'),
- EventPattern('dbus-signal', signal='Sent'),
EventPattern('dbus-signal', signal='MessageSent'),
)
@@ -138,9 +122,6 @@ def test(q, bus, conn, stream):
assertEquals(cs.MSG_SENDING_FLAGS_REPORT_DELIVERY, flags)
assertEquals(sent_token, token)
- assert sent.args[1] == 1, sent.args # Action
- assert sent.args[2] == u'peers through a gap in the curtains', sent.args
-
assert message_sent.args[2] == sent_token
elem = stream_message.stanza
@@ -161,10 +142,7 @@ def test(q, bus, conn, stream):
stream.send(elem)
# Check that we got the corresponding delivery report
- report, old_received = q.expect_many(
- EventPattern('dbus-signal', signal='MessageReceived'),
- EventPattern('dbus-signal', signal='Received'),
- )
+ report = q.expect('dbus-signal', signal='MessageReceived')
assert len(report.args) == 1, report.args
parts = report.args[0]
@@ -191,27 +169,17 @@ def test(q, bus, conn, stream):
assert key in echo[i], (i, key, echo)
assert echo[i][key] == greeting[i][key], (i, key, echo, greeting)
- # The Text.Received signal should be a "you're not tall enough" stub
- id, timestamp, sender, type, flags, text = old_received.args
- assert sender == 0, old_received.args
- assert type == 4, old_received.args # Message_Type_Delivery_Report
- assert flags == 2, old_received.args # Non_Text_Content
- assert text == '', old_received.args
-
-
# Send a normal message using the Channel.Type.Text API
- chan.Text.Send(0, 'goodbye')
+ chan.send_msg_sync('goodbye')
- event, sent, message_sent = q.expect_many(
+ event, message_sent = q.expect_many(
EventPattern('stream-message'),
- EventPattern('dbus-signal', signal='Sent'),
EventPattern('dbus-signal', signal='MessageSent'),
)
sent_message, flags, _ = message_sent.args
assert len(sent_message) == 2, sent_message
header = sent_message[0]
- assert 'message-type' not in header, header # Normal
body = sent_message[1]
assert body['content-type'] == 'text/plain', body
assert body['content'] == u'goodbye', body
@@ -221,9 +189,6 @@ def test(q, bus, conn, stream):
# Gabble's within its rights to pretend that the caller asked.
assert flags in [0, cs.MSG_SENDING_FLAGS_REPORT_DELIVERY], flags
- assert sent.args[1] == 0, sent.args # Normal
- assert sent.args[2] == u'goodbye', sent.args
-
sent_token = message_sent.args[2]
elem = event.stanza
@@ -265,7 +230,8 @@ def test(q, bus, conn, stream):
assert x_muc_nodes is None, elem.toXml()
# test that leaving the channel results in an unavailable message
- chan.Group.RemoveMembers([chan.Group.GetSelfHandle()], 'booo')
+ chan.Group.RemoveMembers([chan.Properties.Get(cs.CHANNEL_IFACE_GROUP,
+ "SelfHandle")], 'booo')
event = q.expect('stream-presence', to='chat@conf.localhost/test')
elem = event.stanza
diff --git a/tests/twisted/mucutil.py b/tests/twisted/mucutil.py
index 103b68b79..8bb830b9e 100644
--- a/tests/twisted/mucutil.py
+++ b/tests/twisted/mucutil.py
@@ -5,10 +5,10 @@ Utility functions for tests that need to interact with MUCs.
import dbus
-from twisted.words.xish import domish, xpath
+from twisted.words.xish import xpath
from servicetest import call_async, wrap_channel, EventPattern, assertLength
-from gabbletest import make_muc_presence, request_muc_handle
+from gabbletest import make_muc_presence
import constants as cs
import ns
@@ -56,11 +56,10 @@ def try_to_join_muc(q, bus, conn, stream, muc, request=None):
def join_muc(q, bus, conn, stream, muc, request=None,
also_capture=[], role='participant', affiliation='none'):
"""
- Joins 'muc', returning the muc's handle, a proxy object for the channel,
+ Joins 'muc', returning a proxy object for the channel,
its path and its immutable properties just after the CreateChannel event
has fired. The room contains one other member.
"""
- muc_handle = request_muc_handle(q, conn, stream, muc)
try_to_join_muc(q, bus, conn, stream, muc, request=request)
# Send presence for other member of room.
@@ -74,23 +73,22 @@ def join_muc(q, bus, conn, stream, muc, request=None,
*also_capture)
path, props = captured[0].value
chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text',
- ['Messages', 'Subject.DRAFT', 'RoomConfig1', 'ChatState'])
+ ['Subject.DRAFT'])
- return (muc_handle, chan, path, props) + tuple(captured[1:])
+
+ return (chan, path, props) + tuple(captured[1:])
def join_muc_and_check(q, bus, conn, stream, muc, request=None):
"""
Like join_muc(), but also checks the NewChannels and NewChannel signals and
the Members property, and returns both members' handles.
"""
- muc_handle, chan, path, props = \
+ chan, path, props = \
join_muc(q, bus, conn, stream, muc, request=request)
q.expect('dbus-signal', signal='NewChannels', args=[[(path, props)]])
- q.expect('dbus-signal', signal='NewChannel',
- args=[path, cs.CHANNEL_TYPE_TEXT, cs.HT_ROOM, muc_handle, True])
- test_handle, bob_handle = conn.RequestHandles(cs.HT_CONTACT,
+ test_handle, bob_handle = conn.get_contact_handles_sync(
['%s/test' % muc, '%s/bob' % muc])
members = chan.Get(cs.CHANNEL_IFACE_GROUP, 'Members',
@@ -98,4 +96,4 @@ def join_muc_and_check(q, bus, conn, stream, muc, request=None):
assert set(members) == set([test_handle, bob_handle]), \
(members, (test_handle, bob_handle))
- return (muc_handle, chan, test_handle, bob_handle)
+ return (chan, test_handle, bob_handle)
diff --git a/tests/twisted/olpc/change-notifications.py b/tests/twisted/olpc/change-notifications.py
index 648ef5df7..3b637dffa 100644
--- a/tests/twisted/olpc/change-notifications.py
+++ b/tests/twisted/olpc/change-notifications.py
@@ -19,7 +19,7 @@ def test(q, bus, conn, stream):
handles = {}
- handles['alice'] = conn.RequestHandles(1, ['alice@localhost'])[0]
+ handles['alice'] = conn.get_contact_handle_sync('alice@localhost')
# Alice, one our friends changed her properties
send_buddy_changed_properties_msg(stream, 'alice@localhost',
diff --git a/tests/twisted/olpc/current-activity.py b/tests/twisted/olpc/current-activity.py
index 0906f4a1e..382110217 100644
--- a/tests/twisted/olpc/current-activity.py
+++ b/tests/twisted/olpc/current-activity.py
@@ -24,7 +24,7 @@ def test(q, bus, conn, stream):
handles = {}
# Alice is one of our friend so we receive her PEP notifications
- handles['alice'] = conn.RequestHandles(1, ['alice@localhost'])[0]
+ handles['alice'] = conn.get_contact_handle_sync('alice@localhost')
# Try to get Alice's currrent-activity
call_async(q, buddy_info_iface, "GetCurrentActivity", handles['alice'])
diff --git a/tests/twisted/olpc/olpc-muc-invitation.py b/tests/twisted/olpc/olpc-muc-invitation.py
index 2c9ee92c3..8307e2972 100644
--- a/tests/twisted/olpc/olpc-muc-invitation.py
+++ b/tests/twisted/olpc/olpc-muc-invitation.py
@@ -7,13 +7,13 @@ import dbus
from twisted.words.xish import domish, xpath
from gabbletest import exec_test, make_muc_presence
-from servicetest import call_async, EventPattern
+from servicetest import call_async, EventPattern, wrap_channel
import constants as cs
import ns
def test(q, bus, conn, stream):
handles = {}
- handles['bob'] = conn.RequestHandles(1, ['bob@localhost'])[0]
+ handles['bob'] = conn.get_contact_handle_sync('bob@localhost')
buddy_iface = dbus.Interface(conn, 'org.laptop.Telepathy.BuddyInfo')
act_prop_iface = dbus.Interface(conn, 'org.laptop.Telepathy.ActivityProperties')
@@ -79,22 +79,24 @@ def test(q, bus, conn, stream):
assert event.args[2] == 2 # handle type
assert event.args[3] == handles['chat'] # handle
- text_chan = bus.get_object(conn.bus_name, event.args[0])
- group_iface = dbus.Interface(text_chan, cs.CHANNEL_IFACE_GROUP)
+ text_chan = wrap_channel(bus.get_object(conn.bus_name, event.args[0]),
+ 'Text')
+ group_iface = text_chan.Group
members = group_iface.GetAllMembers()[0]
local_pending = group_iface.GetAllMembers()[1]
remote_pending = group_iface.GetAllMembers()[2]
assert len(members) == 1
- assert conn.InspectHandles(1, members)[0] == 'bob@localhost'
+ assert conn.inspect_contact_sync(members[0]) == 'bob@localhost'
assert len(local_pending) == 1
# FIXME: the username-part-is-nickname assumption
- assert conn.InspectHandles(1, local_pending)[0] == \
+ assert conn.inspect_contact_sync(local_pending[0]) == \
'chat@conf.localhost/test'
assert len(remote_pending) == 0
- handles['chat_self'] = group_iface.GetSelfHandle()
+ handles['chat_self'] = text_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP,
+ "SelfHandle")
assert handles['chat_self'] == local_pending[0]
# by now, we should have picked up the extra activity properties
@@ -148,8 +150,7 @@ def test(q, bus, conn, stream):
q.expect('dbus-return', method='SetProperties')
# Test sending an invitation
- handles['alice'] = conn.RequestHandles(1,
- ['alice@localhost'])[0]
+ handles['alice'] = conn.get_contact_handle_sync('alice@localhost')
call_async(q, group_iface, 'AddMembers', [handles['alice']],
'I want to test invitations')
diff --git a/tests/twisted/olpc/olpc-muc-prop-change.py b/tests/twisted/olpc/olpc-muc-prop-change.py
index 8a20303a2..d18788ccd 100644
--- a/tests/twisted/olpc/olpc-muc-prop-change.py
+++ b/tests/twisted/olpc/olpc-muc-prop-change.py
@@ -7,7 +7,7 @@ import dbus
from twisted.words.xish import domish, xpath
from gabbletest import exec_test, acknowledge_iq, make_muc_presence
-from servicetest import call_async, EventPattern
+from servicetest import call_async, EventPattern, wrap_channel
import constants as cs
import ns
@@ -21,7 +21,7 @@ def test(q, bus, conn, stream):
buddy_iface = dbus.Interface(conn, 'org.laptop.Telepathy.BuddyInfo')
act_prop_iface = dbus.Interface(conn, 'org.laptop.Telepathy.ActivityProperties')
- bob_handle = conn.RequestHandles(1, ['bob@localhost'])[0]
+ bob_handle = conn.get_contact_handle_sync('bob@localhost')
# Bob invites us to a chatroom, pre-seeding properties
message = domish.Element(('jabber:client', 'message'))
@@ -61,24 +61,25 @@ def test(q, bus, conn, stream):
assert event.args[3] == 1 # handle
room_handle = 1
- text_chan = bus.get_object(conn.bus_name, event.args[0])
- chan_iface = dbus.Interface(text_chan, cs.CHANNEL)
- group_iface = dbus.Interface(text_chan, cs.CHANNEL_IFACE_GROUP)
+ text_chan = wrap_channel(bus.get_object(conn.bus_name, event.args[0]),
+ 'Text')
+ group_iface = text_chan.Group
members = group_iface.GetAllMembers()[0]
local_pending = group_iface.GetAllMembers()[1]
remote_pending = group_iface.GetAllMembers()[2]
assert len(members) == 1
- assert conn.InspectHandles(1, members)[0] == 'bob@localhost'
+ assert conn.inspect_contact_sync(members[0]) == 'bob@localhost'
bob_handle = members[0]
assert len(local_pending) == 1
# FIXME: the username-part-is-nickname assumption
- assert conn.InspectHandles(1, local_pending)[0] == \
+ assert conn.inspect_contact_sync(local_pending[0]) == \
'chat@conf.localhost/test'
assert len(remote_pending) == 0
- room_self_handle = group_iface.GetSelfHandle()
+ room_self_handle = text_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP,
+ "SelfHandle")
assert room_self_handle == local_pending[0]
# by now, we should have picked up the extra activity properties
@@ -359,7 +360,7 @@ def test(q, bus, conn, stream):
q.expect('dbus-return', method='SetProperties')
- chan_iface.Close()
+ text_chan.Close()
# we must echo the MUC presence so the room will actually close
event = q.expect('stream-presence', to='chat@conf.localhost/test',
diff --git a/tests/twisted/pep-support.py b/tests/twisted/pep-support.py
index 10e5c94e8..257ea55fb 100644
--- a/tests/twisted/pep-support.py
+++ b/tests/twisted/pep-support.py
@@ -1,7 +1,4 @@
-import dbus
-
-from gabbletest import exec_test, GoogleXmlStream, acknowledge_iq, BaseXmlStream,\
- sync_stream
+from gabbletest import exec_test, GoogleXmlStream, acknowledge_iq, BaseXmlStream
from servicetest import call_async, EventPattern
from twisted.words.protocols.jabber.client import IQ
diff --git a/tests/twisted/plugin-channel-managers.py b/tests/twisted/plugin-channel-managers.py
index 320dd7ac7..03668d733 100644
--- a/tests/twisted/plugin-channel-managers.py
+++ b/tests/twisted/plugin-channel-managers.py
@@ -2,14 +2,12 @@
Test Gabble's implementation of channel managers from plugins.
"""
-from servicetest import (
- sync_dbus, call_async, EventPattern, assertEquals, assertContains,
- )
-from gabbletest import exec_test, send_error_reply, acknowledge_iq, sync_stream
+from servicetest import assertContains
+from gabbletest import exec_test
import constants as cs
from config import PLUGINS_ENABLED
-TEST_PLUGIN_IFACE = "org.freedesktop.Telepathy.Gabble.Plugin.Test"
+TEST_PLUGIN_IFACE = cs.PREFIX + ".Gabble.Plugin.Test"
if not PLUGINS_ENABLED:
print "NOTE: built without --enable-plugins, not testing plugins"
diff --git a/tests/twisted/power-save.py b/tests/twisted/power-save.py
index 862c709c9..28861d5d5 100644
--- a/tests/twisted/power-save.py
+++ b/tests/twisted/power-save.py
@@ -2,21 +2,15 @@
Test entering and leaving power saving mode.
"""
-import config
-
import constants as cs
from gabbletest import exec_test, GoogleXmlStream, make_result_iq, \
send_error_reply, disconnect_conn, make_presence, sync_stream, elem, \
acknowledge_iq
-from servicetest import call_async, Event, assertEquals, EventPattern, \
- assertContains, assertDoesNotContain, sync_dbus
+from servicetest import call_async, assertEquals, EventPattern, \
+ assertContains, sync_dbus
import ns
-import dbus
-import dbus.service
-
-from twisted.internet import reactor
from twisted.words.xish import domish
def expect_command(q, name):
@@ -123,7 +117,7 @@ def test_local_queueing(q, bus, conn, stream):
event = q.expect('dbus-signal', signal='AliasesChanged')
# .. and finally the message that flushed the stanza queue
- q.expect('dbus-signal', signal='NewChannel')
+ q.expect('dbus-signal', signal='NewChannels')
sync_stream(q, stream)
diff --git a/tests/twisted/presence/decloak.py b/tests/twisted/presence/decloak.py
index 235116c25..541762d20 100644
--- a/tests/twisted/presence/decloak.py
+++ b/tests/twisted/presence/decloak.py
@@ -21,7 +21,7 @@ def test(q, bus, conn, stream, should_decloak=False):
worker(q, bus, conn, stream, should_decloak)
# Trivial test for SendDirectedPresence()
- bob_handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
+ bob_handle = conn.get_contact_handle_sync('bob@foo.com')
conn.SendDirectedPresence(bob_handle, False,
dbus_interface=cs.CONN_IFACE_GABBLE_DECLOAK)
q.expect('stream-presence', to='bob@foo.com')
@@ -31,7 +31,7 @@ def worker(q, bus, conn, stream, should_decloak):
'DecloakAutomatically', dbus_interface=cs.PROPERTIES_IFACE)
assertEquals(should_decloak, decloak_automatically)
- amy_handle = conn.RequestHandles(1, ['amy@foo.com'])[0]
+ amy_handle = conn.get_contact_handle_sync('amy@foo.com')
# Amy directs presence to us
diff --git a/tests/twisted/presence/error.py b/tests/twisted/presence/error.py
index 53f3703bc..33339e65a 100644
--- a/tests/twisted/presence/error.py
+++ b/tests/twisted/presence/error.py
@@ -13,7 +13,7 @@ def test(q, bus, conn, stream):
'thehawk@unreachable.example.net',
]
gregory, hawk = jids
- gregory_handle, hawk_handle = conn.RequestHandles(cs.HT_CONTACT, jids)
+ gregory_handle, hawk_handle = conn.get_contact_handles_sync(jids)
event = q.expect('stream-iq', query_ns=ns.ROSTER)
event.stanza['type'] = 'result'
diff --git a/tests/twisted/presence/initial-contact-presence.py b/tests/twisted/presence/initial-contact-presence.py
index 881316c73..c76309f17 100644
--- a/tests/twisted/presence/initial-contact-presence.py
+++ b/tests/twisted/presence/initial-contact-presence.py
@@ -10,6 +10,7 @@ This serves as a regression test for
from gabbletest import exec_test, make_presence, sync_stream, elem
from servicetest import assertEquals, EventPattern, sync_dbus
+from presence_helper import get_contacts_presences_sync
import constants as cs
import ns
@@ -29,16 +30,17 @@ def make_roster_item(jid, subscription):
def test(q, bus, conn, stream):
event = q.expect('stream-iq', query_ns=ns.ROSTER)
- amy, bob, che, dre, eve = conn.RequestHandles(cs.HT_CONTACT,
+ amy, bob, che, dre, eve = conn.get_contact_handles_sync(
['amy@foo.com', 'bob@foo.com', 'che@foo.com', 'dre@foo.com',
'eve@foo.com'])
+
assertEquals({amy: UNKNOWN,
bob: UNKNOWN,
che: UNKNOWN,
dre: UNKNOWN,
eve: UNKNOWN,
},
- conn.SimplePresence.GetPresences([amy, bob, che, dre, eve]))
+ get_contacts_presences_sync(conn, [amy, bob, che, dre, eve]))
# Before the server sends Gabble the roster, it relays an 'unavailable'
# presence for one of the contacts we're subscribed to. This seems to
@@ -94,7 +96,7 @@ def test(q, bus, conn, stream):
dre: OFFLINE,
eve: AVAILABLE,
},
- conn.SimplePresence.GetPresences([amy, bob, che, dre, eve]))
+ get_contacts_presences_sync(conn, [amy, bob, che, dre, eve]))
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/presence/presence.py b/tests/twisted/presence/presence.py
index 49974691b..8d35e284a 100644
--- a/tests/twisted/presence/presence.py
+++ b/tests/twisted/presence/presence.py
@@ -1,20 +1,18 @@
"""
A simple smoke-test for C.I.SimplePresence
-
-FIXME: test C.I.Presence too
"""
from twisted.words.xish import domish
from gabbletest import exec_test, make_presence
-from servicetest import EventPattern
+from servicetest import EventPattern, assertEquals
import ns
import constants as cs
def test(q, bus, conn, stream):
event = q.expect('stream-iq', query_ns=ns.ROSTER)
- amy_handle = conn.RequestHandles(1, ['amy@foo.com'])[0]
+ amy_handle = conn.get_contact_handle_sync('amy@foo.com')
event.stanza['type'] = 'result'
@@ -31,9 +29,18 @@ def test(q, bus, conn, stream):
stream.send(make_presence(
'amy@foo.com', show='chat', status='I may have been drinking'))
- q.expect('dbus-signal', signal='PresencesChanged',
+ e = q.expect('dbus-signal', signal='PresencesChanged',
args=[{amy_handle:
(cs.PRESENCE_AVAILABLE, 'chat', 'I may have been drinking')}])
+ amy_handle, asv = conn.Contacts.GetContactByID('amy@foo.com',
+ [cs.CONN_IFACE_SIMPLE_PRESENCE])
+ assertEquals(e.args[0][amy_handle], asv.get(cs.ATTR_PRESENCE))
+
+ bob_handle, asv = conn.Contacts.GetContactByID('bob@foo.com',
+ [cs.CONN_IFACE_SIMPLE_PRESENCE])
+ assertEquals((cs.PRESENCE_UNKNOWN, 'unknown', ''),
+ asv.get(cs.ATTR_PRESENCE))
+
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/presence/set-idempotence.py b/tests/twisted/presence/set-idempotence.py
index dc11ceb79..02f519ef3 100644
--- a/tests/twisted/presence/set-idempotence.py
+++ b/tests/twisted/presence/set-idempotence.py
@@ -24,7 +24,7 @@ def run_test(q, bus, conn, stream):
assert simple_signal.args == [{1L: (3L, u'away', u'gone')}]
assert conn.Contacts.GetContactAttributes([1], [cs.CONN_IFACE_SIMPLE_PRESENCE], False) == { 1L:
{ cs.CONN_IFACE_SIMPLE_PRESENCE + "/presence": (3L, u'away', u'gone'),
- 'org.freedesktop.Telepathy.Connection/contact-id':
+ cs.ATTR_CONTACT_ID:
'test@localhost'}}
children = list(presence.stanza.elements())
@@ -38,7 +38,7 @@ def run_test(q, bus, conn, stream):
conn.SimplePresence.SetPresence('away', 'gone')
assert conn.Contacts.GetContactAttributes([1], [cs.CONN_IFACE_SIMPLE_PRESENCE], False) == { 1L:
{ cs.CONN_IFACE_SIMPLE_PRESENCE + "/presence": (3L, u'away', u'gone'),
- 'org.freedesktop.Telepathy.Connection/contact-id':
+ cs.ATTR_CONTACT_ID:
'test@localhost'}}
# Set presence a third time. This call is not redundant, and should
@@ -55,7 +55,7 @@ def run_test(q, bus, conn, stream):
assert str(children[0]) == 'yo'
assert conn.Contacts.GetContactAttributes([1], [cs.CONN_IFACE_SIMPLE_PRESENCE], False) == { 1L:
{ cs.CONN_IFACE_SIMPLE_PRESENCE + "/presence": (2L, u'available', u'yo'),
- 'org.freedesktop.Telepathy.Connection/contact-id':
+ cs.ATTR_CONTACT_ID:
'test@localhost'}}
# call SetPresence with an empty message, as this used to cause a
@@ -68,7 +68,7 @@ def run_test(q, bus, conn, stream):
assert simple_signal.args == [{1L: (2L, u'available', u'')}]
assert conn.Contacts.GetContactAttributes([1], [cs.CONN_IFACE_SIMPLE_PRESENCE], False) == { 1L:
{ cs.CONN_IFACE_SIMPLE_PRESENCE + "/presence": (2L, u'available', u''),
- 'org.freedesktop.Telepathy.Connection/contact-id':
+ cs.ATTR_CONTACT_ID:
'test@localhost'}}
if __name__ == '__main__':
diff --git a/tests/twisted/presence/shared-status.py b/tests/twisted/presence/shared-status.py
index 17945e3e9..b2e02b8cc 100644
--- a/tests/twisted/presence/shared-status.py
+++ b/tests/twisted/presence/shared-status.py
@@ -17,6 +17,7 @@ import constants as cs
import dbus
from twisted.words.xish import xpath, domish
from invisible_helper import SharedStatusStream
+from presence_helper import get_contacts_presences_sync
presence_types = {'available' : cs.PRESENCE_AVAILABLE,
'away' : cs.PRESENCE_AWAY,
@@ -37,8 +38,8 @@ def _show_to_shared_status_show(show):
return shared_show, shared_invisible
def _test_remote_status(q, bus, conn, stream, msg, show, list_attrs):
- self = conn.GetSelfHandle()
- presence = conn.SimplePresence.GetPresences([self])[self]
+ self = conn.Properties.Get(cs.CONN, "SelfHandle")
+ presence = get_contacts_presences_sync(conn, [self])[self]
is_away = presence[0] in (cs.PRESENCE_AWAY, cs.PRESENCE_EXTENDED_AWAY)
if is_away:
@@ -78,8 +79,8 @@ def _test_local_status(q, conn, stream, msg, show, expected_show=None):
expected_show = expected_show or show
away = expected_show in ('away', 'xa')
- self = conn.GetSelfHandle()
- prev_presence = conn.SimplePresence.GetPresences([self])[self]
+ self = conn.Properties.Get(cs.CONN, "SelfHandle")
+ prev_presence = get_contacts_presences_sync(conn, [self])[self]
was_away = prev_presence[0] in (cs.PRESENCE_AWAY,
cs.PRESENCE_EXTENDED_AWAY)
was_invisible = (prev_presence[0] == cs.PRESENCE_HIDDEN)
diff --git a/tests/twisted/presence_helper.py b/tests/twisted/presence_helper.py
new file mode 100644
index 000000000..768963376
--- /dev/null
+++ b/tests/twisted/presence_helper.py
@@ -0,0 +1,8 @@
+import constants as cs
+
+def get_contacts_presences_sync(conn, contacts):
+ h2asv = conn.Contacts.GetContactAttributes(contacts, [cs.CONN_IFACE_SIMPLE_PRESENCE], False)
+ presences = {}
+ for h in contacts:
+ presences[h] = h2asv[h][cs.ATTR_PRESENCE]
+ return presences
diff --git a/tests/twisted/pubsub.py b/tests/twisted/pubsub.py
index 298106d95..16850ab93 100644
--- a/tests/twisted/pubsub.py
+++ b/tests/twisted/pubsub.py
@@ -1,7 +1,6 @@
"""Send malformed pubsub notifications to be sure that Gabble isn't confused about those"""
from gabbletest import exec_test, elem, sync_stream
-import constants as cs
import ns
def make_pubsub_event(from_, node, *contents):
diff --git a/tests/twisted/roster/authorize.py b/tests/twisted/roster/authorize.py
index 8d52435fc..906950ebd 100644
--- a/tests/twisted/roster/authorize.py
+++ b/tests/twisted/roster/authorize.py
@@ -4,16 +4,15 @@ Test receiving and authorizing publish requests, including "pre-authorization"
"""
from gabbletest import (exec_test, sync_stream, acknowledge_iq)
-from rostertest import (expect_contact_list_signals,
- check_contact_list_signals, send_roster_push)
-from servicetest import (assertEquals, assertLength, call_async, EventPattern,
+from rostertest import send_roster_push
+from servicetest import (assertEquals, call_async, EventPattern,
sync_dbus)
import constants as cs
import ns
from twisted.words.xish import domish
-def test(q, bus, conn, stream, modern=True, remove=False):
+def test(q, bus, conn, stream, remove=False):
call_async(q, conn.ContactList, 'GetContactListAttributes', [], False)
q.expect('dbus-error', method='GetContactListAttributes',
@@ -27,20 +26,17 @@ def test(q, bus, conn, stream, modern=True, remove=False):
event.stanza['type'] = 'result'
stream.send(event.stanza)
- holly, dave, arnold, kristine, cat = conn.RequestHandles(cs.HT_CONTACT,
+ holly, dave, arnold, kristine, cat = conn.get_contact_handles_sync(
['holly@example.com', 'dave@example.com', 'arnold@example.com',
'kristine@example.com', 'cat@example.com'])
- # slight implementation detail: TpBaseContactList emits ContactsChanged
+ # slight implementation detail: TpBaseContactList emits ContactsChangedWithID
# before it announces its channels
- s = q.expect('dbus-signal', signal='ContactsChanged',
+ s = q.expect('dbus-signal', signal='ContactsChangedWithID',
interface=cs.CONN_IFACE_CONTACT_LIST, path=conn.object_path)
assertEquals([{
holly: (cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_YES, ''),
- }, []], s.args)
-
- pairs = expect_contact_list_signals(q, bus, conn,
- ['publish', 'subscribe', 'stored'])
+ }, { holly: 'holly@example.com' }, {}], s.args)
# this is emitted last, so clients can tell when the initial state dump
# has finished
@@ -59,23 +55,10 @@ def test(q, bus, conn, stream, modern=True, remove=False):
}
},), r.value)
- # check that the channels were as we expected too
- publish = check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'publish', ['holly@example.com'])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'subscribe', ['holly@example.com'])
- stored = check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'stored', ['holly@example.com'])
- assertLength(0, pairs) # i.e. we've checked all of them
-
# publication authorized for Dave, Holly (the former is pre-authorization,
# the latter is a no-op)
- if modern:
- call_async(q, conn.ContactList, 'AuthorizePublication', [dave, holly])
- event = q.expect('dbus-return', method='AuthorizePublication')
- else:
- call_async(q, publish.Group, 'AddMembers', [dave, holly], '')
- event = q.expect('dbus-return', method='AddMembers')
+ call_async(q, conn.ContactList, 'AuthorizePublication', [dave, holly])
+ event = q.expect('dbus-return', method='AuthorizePublication')
# Receive authorization requests from the contacts
@@ -86,10 +69,10 @@ def test(q, bus, conn, stream, modern=True, remove=False):
stream.send(presence)
q.expect_many(
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{dave: (cs.SUBSCRIPTION_STATE_NO,
cs.SUBSCRIPTION_STATE_ASK,
- '')}, []]),
+ '')}, { dave: 'dave@example.com' }, {}]),
EventPattern('stream-presence', presence_type='subscribed',
to='dave@example.com'),
)
@@ -98,34 +81,30 @@ def test(q, bus, conn, stream, modern=True, remove=False):
send_roster_push(stream, 'dave@example.com', 'from')
q.expect_many(
EventPattern('stream-iq', iq_type='result', iq_id='push'),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{dave: (cs.SUBSCRIPTION_STATE_NO,
- cs.SUBSCRIPTION_STATE_YES, '')}, []]),
+ cs.SUBSCRIPTION_STATE_YES, '')}, { dave: 'dave@example.com' }, {}]),
)
# The request from Kristine needs authorization (below)
presence['from'] = 'kristine@example.com'
stream.send(presence)
- q.expect('dbus-signal', signal='ContactsChanged',
+ q.expect('dbus-signal', signal='ContactsChangedWithID',
args=[{kristine: (cs.SUBSCRIPTION_STATE_NO,
- cs.SUBSCRIPTION_STATE_ASK, '')}, []])
+ cs.SUBSCRIPTION_STATE_ASK, '')}, { kristine: 'kristine@example.com' }, {}])
# This request from Arnold is dealt with below
presence['from'] = 'arnold@example.com'
stream.send(presence)
- q.expect('dbus-signal', signal='ContactsChanged',
+ q.expect('dbus-signal', signal='ContactsChangedWithID',
args=[{arnold: (cs.SUBSCRIPTION_STATE_NO,
- cs.SUBSCRIPTION_STATE_ASK, '')}, []])
+ cs.SUBSCRIPTION_STATE_ASK, '')}, { arnold: 'arnold@example.com' }, {}])
- if modern:
- returning_method = 'AuthorizePublication'
- call_async(q, conn.ContactList, 'AuthorizePublication',
- [kristine, holly])
- else:
- returning_method = 'AddMembers'
- call_async(q, publish.Group, 'AddMembers', [kristine, holly], '')
+ returning_method = 'AuthorizePublication'
+ call_async(q, conn.ContactList, 'AuthorizePublication',
+ [kristine, holly])
q.expect_many(
EventPattern('dbus-return', method=returning_method),
@@ -137,10 +116,10 @@ def test(q, bus, conn, stream, modern=True, remove=False):
# does not change.
send_roster_push(stream, 'kristine@example.com', 'from')
q.expect_many(
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{kristine: (cs.SUBSCRIPTION_STATE_NO,
cs.SUBSCRIPTION_STATE_YES,
- '')}, []]),
+ '')}, { kristine: 'kristine@example.com' }, {}]),
EventPattern('stream-iq', iq_type='result', iq_id='push'),
)
@@ -150,9 +129,9 @@ def test(q, bus, conn, stream, modern=True, remove=False):
stream.send(presence)
q.expect_many(
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{arnold: (cs.SUBSCRIPTION_STATE_NO,
- cs.SUBSCRIPTION_STATE_REMOVED_REMOTELY, '')}, []]),
+ cs.SUBSCRIPTION_STATE_REMOVED_REMOTELY, '')}, { arnold: 'arnold@example.com' }, {}]),
EventPattern('stream-presence', presence_type='unsubscribed',
to='arnold@example.com'),
)
@@ -174,8 +153,8 @@ def test(q, bus, conn, stream, modern=True, remove=False):
# in his removal.
q.expect_many(
EventPattern('dbus-return', method=returning_method),
- EventPattern('dbus-signal', signal='ContactsChanged',
- args=[{}, [arnold]]),
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
+ args=[{}, {}, {arnold: 'arnold@example.com' }]),
)
# Rejecting an authorization request also works
@@ -184,32 +163,24 @@ def test(q, bus, conn, stream, modern=True, remove=False):
presence['from'] = 'cat@example.com'
stream.send(presence)
- q.expect('dbus-signal', signal='ContactsChanged',
+ q.expect('dbus-signal', signal='ContactsChangedWithID',
args=[{cat: (cs.SUBSCRIPTION_STATE_NO,
cs.SUBSCRIPTION_STATE_ASK,
- '')}, []])
-
- if modern:
- if remove:
- returning_method = 'RemoveContacts'
- call_async(q, conn.ContactList, 'RemoveContacts', [cat])
- else:
- returning_method = 'Unpublish'
- call_async(q, conn.ContactList, 'Unpublish', [cat])
- else:
- returning_method = 'RemoveMembers'
+ '')}, { cat: 'cat@example.com' }, {}])
- if remove:
- call_async(q, stored.Group, 'RemoveMembers', [cat], '')
- else:
- call_async(q, publish.Group, 'RemoveMembers', [cat], '')
+ if remove:
+ returning_method = 'RemoveContacts'
+ call_async(q, conn.ContactList, 'RemoveContacts', [cat])
+ else:
+ returning_method = 'Unpublish'
+ call_async(q, conn.ContactList, 'Unpublish', [cat])
# As above, the only reason the Cat is on our contact list is the pending
# publish request, so Unpublish really results in removal.
q.expect_many(
EventPattern('dbus-return', method=returning_method),
- EventPattern('dbus-signal', signal='ContactsChanged',
- args=[{}, [cat]]),
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
+ args=[{}, {}, { cat: 'cat@example.com' }]),
)
# Redundant API calls (removing an absent contact, etc.) cause no network
@@ -237,20 +208,12 @@ def test(q, bus, conn, stream, modern=True, remove=False):
# There's one more case: revoking the publish permission of someone who is
# genuinely on the roster.
- if modern:
- if remove:
- returning_method = 'RemoveContacts'
- call_async(q, conn.ContactList, 'RemoveContacts', [holly])
- else:
- returning_method = 'Unpublish'
- call_async(q, conn.ContactList, 'Unpublish', [holly])
+ if remove:
+ returning_method = 'RemoveContacts'
+ call_async(q, conn.ContactList, 'RemoveContacts', [holly])
else:
- returning_method = 'RemoveMembers'
-
- if remove:
- call_async(q, stored.Group, 'RemoveMembers', [holly], '')
- else:
- call_async(q, publish.Group, 'RemoveMembers', [holly], '')
+ returning_method = 'Unpublish'
+ call_async(q, conn.ContactList, 'Unpublish', [holly])
if remove:
iq = q.expect('stream-iq', iq_type='set', query_ns=ns.ROSTER,
@@ -258,16 +221,15 @@ def test(q, bus, conn, stream, modern=True, remove=False):
acknowledge_iq(stream, iq.stanza)
- if modern:
- q.expect('dbus-return', method='RemoveContacts')
+ q.expect('dbus-return', method='RemoveContacts')
# FIXME: when we depend on a new enough tp-glib, expect RemoveMembers
# to return here too
send_roster_push(stream, 'holly@example.com', 'remove')
q.expect_many(
EventPattern('stream-iq', iq_type='result', iq_id='push'),
- EventPattern('dbus-signal', signal='ContactsChanged',
- args=[{}, [holly]]),
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
+ args=[{}, {}, { holly: 'holly@example.com' }]),
)
else:
q.expect_many(
@@ -279,26 +241,18 @@ def test(q, bus, conn, stream, modern=True, remove=False):
send_roster_push(stream, 'holly@example.com', 'to')
q.expect_many(
EventPattern('stream-iq', iq_type='result', iq_id='push'),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{holly:
(cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_NO, ''),
- }, []]),
+ }, { holly: 'holly@example.com' }, {}]),
)
-def test_ancient(q, bus, conn, stream):
- test(q, bus, conn, stream, modern=False)
-
-def test_ancient_remove(q, bus, conn, stream):
- test(q, bus, conn, stream, modern=False, remove=True)
-
def test_modern(q, bus, conn, stream):
- test(q, bus, conn, stream, modern=True)
+ test(q, bus, conn, stream)
def test_modern_remove(q, bus, conn, stream):
- test(q, bus, conn, stream, modern=True, remove=True)
+ test(q, bus, conn, stream, remove=True)
if __name__ == '__main__':
- exec_test(test_ancient)
- exec_test(test_ancient_remove)
exec_test(test_modern)
exec_test(test_modern_remove)
diff --git a/tests/twisted/roster/edit-before-roster.py b/tests/twisted/roster/edit-before-roster.py
index cc0da227c..44dd72f1d 100644
--- a/tests/twisted/roster/edit-before-roster.py
+++ b/tests/twisted/roster/edit-before-roster.py
@@ -30,7 +30,7 @@ def test(q, bus, conn, stream):
item.addElement('group', content='men')
# Before we get the roster, try to change something. It won't work.
- amy, bob, che = conn.RequestHandles(cs.HT_CONTACT,
+ amy, bob, che = conn.get_contact_handles_sync(
['amy@foo.com', 'bob@foo.com', 'che@foo.com'])
call_async(q, conn.ContactGroups, 'AddToGroup', 'Amy & Bob', [amy, bob])
diff --git a/tests/twisted/roster/ensure.py b/tests/twisted/roster/ensure.py
deleted file mode 100644
index 514991eca..000000000
--- a/tests/twisted/roster/ensure.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-Test ensuring roster channels
-"""
-
-from gabbletest import exec_test
-from servicetest import call_async
-import constants as cs
-import ns
-
-def test(q, bus, conn, stream):
- roster_event = q.expect('stream-iq', query_ns=ns.ROSTER)
- roster_event.stanza['type'] = 'result'
-
- call_async(q, conn, "RequestHandles", cs.HT_GROUP, ['test'])
-
- event = q.expect('dbus-return', method='RequestHandles')
- test_handle = event.value[0][0]
-
- # send an empty roster
- stream.send(roster_event.stanza)
-
- call_async(q, conn.Requests, 'EnsureChannel',
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST,
- cs.TARGET_HANDLE_TYPE: cs.HT_GROUP,
- cs.TARGET_HANDLE: test_handle,
- })
- call_async(q, conn.Requests, 'EnsureChannel',
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST,
- cs.TARGET_HANDLE_TYPE: cs.HT_GROUP,
- cs.TARGET_HANDLE: test_handle,
- })
-
- ret = q.expect('dbus-return', method='EnsureChannel')
- ret2 = q.expect('dbus-return', method='EnsureChannel')
-
- # We don't test the NewChannels signal here - depending on exact timing,
- # it might happen between the two EnsureChannel calls, or after the second
- # one.
-
- yours, path, props = ret.value
- yours2, path2, props2 = ret2.value
-
- assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_CONTACT_LIST, props
- assert props[cs.TARGET_HANDLE_TYPE] == cs.HT_GROUP, props
- assert props[cs.TARGET_HANDLE] == test_handle, props
- assert props[cs.TARGET_ID] == 'test', props
-
- assert yours != yours2, (yours, yours2)
- assert path == path2, (path, path2)
- assert props == props2, (props, props2)
-
-if __name__ == '__main__':
- exec_test(test)
diff --git a/tests/twisted/roster/groups-12791.py b/tests/twisted/roster/groups-12791.py
index 5f80b057b..0bfaf9401 100644
--- a/tests/twisted/roster/groups-12791.py
+++ b/tests/twisted/roster/groups-12791.py
@@ -2,26 +2,12 @@
Test broken groups on the roster (regression test for fd.o #12791)
"""
-import dbus
-
from gabbletest import exec_test
-from rostertest import expect_contact_list_signals, check_contact_list_signals
-from servicetest import assertLength
+from servicetest import assertLength, assertSameSets, EventPattern
+from rostertest import check_contact_roster, contacts_changed_predicate, groups_created_predicate
import constants as cs
import ns
-def _expect_group_channel(q, bus, conn, name, contacts):
- event = q.expect('dbus-signal', signal='NewChannel')
- path, type, handle_type, handle, suppress_handler = event.args
- assert type == cs.CHANNEL_TYPE_CONTACT_LIST, type
- assert handle_type == cs.HT_GROUP, handle_type
- inspected = conn.InspectHandles(handle_type, [handle])[0]
- assert inspected == name, (inspected, name)
- chan = bus.get_object(conn.bus_name, path)
- group_iface = dbus.Interface(chan, cs.CHANNEL_IFACE_GROUP)
- inspected = conn.InspectHandles(cs.HT_CONTACT, group_iface.GetMembers())
- assert inspected == contacts, (inspected, contacts)
-
def test(q, bus, conn, stream):
event = q.expect('stream-iq', query_ns=ns.ROSTER)
event.stanza['type'] = 'result'
@@ -61,24 +47,28 @@ def test(q, bus, conn, stream):
stream.send(event.stanza)
- pairs = expect_contact_list_signals(q, bus, conn,
- ['publish', 'subscribe', 'stored'],
- ['men', 'women', 'affected-by-fdo-12791'])
+ contacts = [
+ ('amy@foo.com', cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_YES, ''),
+ ('bob@foo.com', cs.SUBSCRIPTION_STATE_NO, cs.SUBSCRIPTION_STATE_YES, ''),
+ ('che@foo.com', cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_NO, ''),
+ ]
+
+ q.expect_many(
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
+ predicate=lambda e: contacts_changed_predicate(e, conn, contacts)),
+ EventPattern('dbus-signal', signal='GroupsCreated',
+ predicate=lambda e: groups_created_predicate(e, ['women', 'men', 'affected-by-fdo-12791'])),
+ )
+
+ contacts = conn.ContactList.GetContactListAttributes([cs.CONN_IFACE_CONTACT_GROUPS], False)
+ assertLength(3, contacts)
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'publish', ['amy@foo.com', 'bob@foo.com'])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'subscribe', ['amy@foo.com', 'che@foo.com'])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'stored', ['amy@foo.com', 'bob@foo.com', 'che@foo.com'])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_GROUP,
- 'men', ['bob@foo.com', 'che@foo.com'])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_GROUP,
- 'women', ['amy@foo.com'])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_GROUP,
- 'affected-by-fdo-12791', [])
+ check_contact_roster(conn, 'amy@foo.com', ['women'])
+ check_contact_roster(conn, 'bob@foo.com', ['men'])
+ check_contact_roster(conn, 'che@foo.com', ['men'])
- assertLength(0, pairs) # i.e. we've checked all of them
+ groups = conn.Properties.Get(cs.CONN_IFACE_CONTACT_GROUPS, 'Groups')
+ assertSameSets(['men', 'women', 'affected-by-fdo-12791'], groups)
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/roster/groups.py b/tests/twisted/roster/groups.py
index d9fd67df2..3225151a6 100644
--- a/tests/twisted/roster/groups.py
+++ b/tests/twisted/roster/groups.py
@@ -3,9 +3,10 @@ Test basic roster group functionality.
"""
from gabbletest import exec_test, acknowledge_iq, sync_stream
-from rostertest import expect_contact_list_signals, check_contact_list_signals
-from servicetest import (assertLength, EventPattern, assertEquals, call_async,
+from servicetest import (EventPattern, assertEquals, call_async,
sync_dbus, assertContains, assertDoesNotContain)
+from rostertest import (groups_changed_predicate, groups_created_predicate,
+ check_contact_roster)
import constants as cs
import ns
@@ -53,35 +54,38 @@ def test(q, bus, conn, stream):
stream.send(event.stanza)
- # slight implementation detail: TpBaseContactList emits ContactsChanged
- # etc. before it announces its channels, and it emits one CGC per group.
- s1, s2 = q.expect_many(
- EventPattern('dbus-signal', signal='GroupsChanged',
- interface=cs.CONN_IFACE_CONTACT_GROUPS, path=conn.object_path,
- predicate=lambda e: 'women' in e.args[1]),
- EventPattern('dbus-signal', signal='GroupsChanged',
- interface=cs.CONN_IFACE_CONTACT_GROUPS, path=conn.object_path,
- predicate=lambda e: 'men' in e.args[1]),
- )
-
- amy, bob, che = conn.RequestHandles(cs.HT_CONTACT,
+ # Avoid relying on the implementation detail of exactly when
+ # TpBaseContactList emits ContactsChanged, relative to when it
+ # announces its channels. Prior to 0.20.3, 0.21.1 it would
+ # announce the channels, emit GroupsChanged, then announce the channels
+ # again... which was a bug, but it turned out this test relied on it.
+ #
+ # We do still rely on the implementation detail that we emit GroupsChanged
+ # once per group with all of its members, not once per contact with all
+ # of their groups. On a typical contact list, there are more contacts
+ # than groups, so that'll work out smaller.
+
+ q.expect_many(
+ EventPattern('dbus-signal', signal='GroupsCreated',
+ interface=cs.CONN_IFACE_CONTACT_GROUPS,
+ path=conn.object_path,
+ predicate=lambda e: groups_created_predicate(e, ['men', 'women'])),
+ EventPattern('dbus-signal', signal='GroupsChanged',
+ interface=cs.CONN_IFACE_CONTACT_GROUPS,
+ path=conn.object_path,
+ predicate=lambda e: groups_changed_predicate(e, conn, ['amy@foo.com'], ['women'], [])),
+ EventPattern('dbus-signal', signal='GroupsChanged',
+ interface=cs.CONN_IFACE_CONTACT_GROUPS,
+ path=conn.object_path,
+ predicate=lambda e: groups_changed_predicate(e, conn, ['bob@foo.com', 'che@foo.com'], ['men'], [])),
+ )
+
+ amy, bob, che = conn.get_contact_handles_sync(
['amy@foo.com', 'bob@foo.com', 'che@foo.com'])
- assertEquals([[amy], ['women'], []], s1.args)
- assertEquals([[bob, che], ['men'], []], s2.args)
-
- pairs = expect_contact_list_signals(q, bus, conn, [], ['men', 'women'])
-
q.expect('dbus-signal', signal='ContactListStateChanged',
args=[cs.CONTACT_LIST_STATE_SUCCESS])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_GROUP,
- 'men', ['bob@foo.com', 'che@foo.com'])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_GROUP,
- 'women', ['amy@foo.com'])
-
- assertLength(0, pairs) # i.e. we've checked all of them
-
# change Amy's groups
call_async(q, conn.ContactGroups, 'SetContactGroups', amy,
['ladies', 'people starting with A'])
@@ -159,13 +163,8 @@ def test(q, bus, conn, stream):
sync_dbus(bus, q, conn)
sync_stream(q, stream)
- assertEquals({
- cs.CONN_IFACE_CONTACT_GROUPS + '/groups':
- ['ladies', 'people starting with A'],
- cs.CONN + '/contact-id':
- 'amy@foo.com' },
- conn.Contacts.GetContactAttributes([amy],
- [cs.CONN_IFACE_CONTACT_GROUPS], False)[amy])
+
+ check_contact_roster(conn, 'amy@foo.com', ['ladies', 'people starting with A'])
# sanity check: after all that, we expect Amy to be in group 'ladies' only
sync_dbus(bus, q, conn)
diff --git a/tests/twisted/roster/initial-aliases.py b/tests/twisted/roster/initial-aliases.py
index d1aeb42ab..0ad823462 100644
--- a/tests/twisted/roster/initial-aliases.py
+++ b/tests/twisted/roster/initial-aliases.py
@@ -8,7 +8,6 @@ from servicetest import (
from gabbletest import (
exec_test, make_result_iq
)
-import constants as cs
import ns
def add_contact(iq, jid, alias):
@@ -45,8 +44,8 @@ def test(q, bus, conn, stream):
event = q.expect('dbus-signal', signal='AliasesChanged')
added = event.args[0]
- bob_handle, alice_handle = conn.RequestHandles(cs.HT_CONTACT,
- [bob_jid, alice_jid])
+ bob_handle, alice_handle = conn.get_contact_handles_sync(
+ [bob_jid, alice_jid])
assertLength(2, added)
assertContains((bob_handle, bob_alias), added)
diff --git a/tests/twisted/roster/push-from-contact.py b/tests/twisted/roster/push-from-contact.py
index 36f583245..cf696d95a 100644
--- a/tests/twisted/roster/push-from-contact.py
+++ b/tests/twisted/roster/push-from-contact.py
@@ -4,9 +4,7 @@ Ensure that Gabble correctly ignores roster pushes from contacts.
from servicetest import EventPattern
from gabbletest import exec_test, acknowledge_iq
-from rostertest import (
- make_roster_push, expect_contact_list_signals, check_contact_list_signals,
-)
+from rostertest import make_roster_push
import ns
import constants as cs
@@ -17,10 +15,7 @@ def test(q, bus, conn, stream):
event = q.expect('stream-iq', query_ns=ns.ROSTER)
acknowledge_iq(stream, event.stanza)
- pairs = expect_contact_list_signals(q, bus, conn,
- ['stored'])
- stored = check_contact_list_signals(q, bus, conn, pairs.pop(0),
- cs.HT_LIST, 'stored', [])
+ q.expect('dbus-signal', signal='ContactListStateChanged', args=[cs.CONTACT_LIST_STATE_SUCCESS])
# Some malicious peer sends us a roster push to try to trick us into
# showing them on our roster. Gabble should know better than to trust it.
@@ -29,12 +24,11 @@ def test(q, bus, conn, stream):
stream.send(iq)
q.forbid_events(
- [ EventPattern('dbus-signal', signal='MembersChanged',
- path=stored.object_path),
- EventPattern('dbus-signal', signal='ContactsChanged'),
+ [
+ EventPattern('dbus-signal', signal='ContactsChangedWithID'),
])
- e = q.expect('stream-iq', iq_type='error')
+ q.expect('stream-iq', iq_type='error')
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/roster/push-without-id.py b/tests/twisted/roster/push-without-id.py
index ed373d327..acbf83232 100644
--- a/tests/twisted/roster/push-without-id.py
+++ b/tests/twisted/roster/push-without-id.py
@@ -6,9 +6,7 @@ we should interop with them. Think of it of like No_Reply in D-Bus...
from servicetest import EventPattern, sync_dbus
from gabbletest import exec_test, acknowledge_iq, sync_stream
-from rostertest import (
- make_roster_push, expect_contact_list_signals, check_contact_list_signals,
-)
+from rostertest import make_roster_push
import ns
import constants as cs
@@ -19,24 +17,18 @@ def test(q, bus, conn, stream):
event = q.expect('stream-iq', query_ns=ns.ROSTER)
acknowledge_iq(stream, event.stanza)
- pairs = expect_contact_list_signals(q, bus, conn,
- ['stored'])
- stored = check_contact_list_signals(q, bus, conn, pairs.pop(0),
- cs.HT_LIST, 'stored', [])
+ q.expect('dbus-signal', signal='ContactListStateChanged', args=[cs.CONTACT_LIST_STATE_SUCCESS])
# The server sends us a roster push without an id=''. WTF!
iq = make_roster_push(stream, jid, 'both')
del iq['id']
stream.send(iq)
- h = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ h = conn.get_contact_handle_sync(jid)
q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [h], [], [], [], 0, 0], path=stored.object_path),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{ h: (cs.SUBSCRIPTION_STATE_YES,
- cs.SUBSCRIPTION_STATE_YES, ''), },
- []],
+ cs.SUBSCRIPTION_STATE_YES, ''), }, {h: jid}, {}],
),
)
@@ -52,9 +44,7 @@ def test(q, bus, conn, stream):
stream.send(iq)
q.forbid_events(
- [ EventPattern('dbus-signal', signal='MembersChanged',
- path=stored.object_path),
- EventPattern('dbus-signal', signal='ContactsChanged'),
+ [ EventPattern('dbus-signal', signal='ContactsChangedWithID'),
])
# Make sure Gabble's got the evil push...
sync_stream(q, stream)
diff --git a/tests/twisted/roster/removed-from-rp-subscribe.py b/tests/twisted/roster/removed-from-rp-subscribe.py
index 8589567b3..86e3113eb 100644
--- a/tests/twisted/roster/removed-from-rp-subscribe.py
+++ b/tests/twisted/roster/removed-from-rp-subscribe.py
@@ -4,34 +4,23 @@ Regression tests for rescinding outstanding subscription requests.
from twisted.words.protocols.jabber.client import IQ
-from servicetest import EventPattern, assertEquals, assertLength, call_async
+from servicetest import EventPattern, assertEquals, call_async
from gabbletest import exec_test, acknowledge_iq
-from rostertest import expect_contact_list_signals, check_contact_list_signals
import constants as cs
import ns
jid = 'marco@barisione.lit'
-def test(q, bus, conn, stream, remove, local, modern):
+def test(q, bus, conn, stream, remove, local):
# Gabble asks for the roster; the server sends back an empty roster.
event = q.expect('stream-iq', query_ns=ns.ROSTER)
event.stanza['type'] = 'result'
stream.send(event.stanza)
- pairs = expect_contact_list_signals(q, bus, conn,
- ['publish', 'subscribe', 'stored'])
+ q.expect('dbus-signal', signal='ContactListStateChanged', args=[cs.CONTACT_LIST_STATE_SUCCESS])
- check_contact_list_signals(q, bus, conn, pairs.pop(0),
- cs.HT_LIST, 'publish', [])
- subscribe = check_contact_list_signals(q, bus, conn, pairs.pop(0),
- cs.HT_LIST, 'subscribe', [])
- stored = check_contact_list_signals(q, bus, conn, pairs.pop(0),
- cs.HT_LIST, 'stored', [])
-
- assertLength(0, pairs) # i.e. we've checked all of them
-
- self_handle = conn.GetSelfHandle()
- h = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
+ h = conn.get_contact_handle_sync(jid)
# Another client logged into our account (Gajim, say) wants to subscribe to
# Marco's presence. First, per RFC 3921 it 'SHOULD perform a "roster set"
@@ -55,12 +44,10 @@ def test(q, bus, conn, stream, remove, local, modern):
# In response, Gabble should add Marco to stored:
q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [h], [], [], [], 0, 0], path=stored.object_path),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{ h: (cs.SUBSCRIPTION_STATE_NO,
cs.SUBSCRIPTION_STATE_NO, ''), },
- []],
+ { h :jid }, {}],
),
)
@@ -77,13 +64,10 @@ def test(q, bus, conn, stream, remove, local, modern):
# In response, Gabble should add Marco to subscribe:remote-pending:
q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [], [], [h], self_handle, 0],
- path=subscribe.object_path),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{ h: (cs.SUBSCRIPTION_STATE_ASK,
cs.SUBSCRIPTION_STATE_NO, ''),
- }, []],
+ }, { h:jid }, {}],
),
)
@@ -93,10 +77,7 @@ def test(q, bus, conn, stream, remove, local, modern):
# ...removes him from the roster...
if local:
# ...by telling Gabble to remove him from stored.
- if modern:
- call_async(q, conn.ContactList, 'RemoveContacts', [h])
- else:
- call_async(q, stored.Group, 'RemoveMembers', [h], '')
+ call_async(q, conn.ContactList, 'RemoveContacts', [h])
event = q.expect('stream-iq', iq_type='set', query_ns=ns.ROSTER)
item = event.query.firstChildElement()
@@ -122,18 +103,12 @@ def test(q, bus, conn, stream, remove, local, modern):
# In response, Gabble should announce that Marco has been removed from
# subscribe:remote-pending and stored:members:
q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [h], [], [], 0, 0],
- path=subscribe.object_path),
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [h], [], [], 0, 0],
- path=stored.object_path),
- EventPattern('dbus-signal', signal='ContactsChanged',
- args=[{}, [h]],
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
+ args=[{}, {}, { h: jid }],
),
)
- if local and modern:
+ if local:
acknowledge_iq(stream, event.stanza)
q.expect('dbus-return', method='RemoveContacts')
# FIXME: when we depend on a new enough tp-glib we can expect
@@ -142,17 +117,13 @@ def test(q, bus, conn, stream, remove, local, modern):
# ...rescinds the subscription request...
if local:
# ...by telling Gabble to remove him from 'subscribe'.
- if modern:
- call_async(q, conn.ContactList, 'Unsubscribe', [h])
- else:
- subscribe.Group.RemoveMembers([h], '')
+ call_async(q, conn.ContactList, 'Unsubscribe', [h])
events = [EventPattern('stream-presence', to=jid,
presence_type='unsubscribe')]
- if modern:
- events.append(EventPattern('dbus-return',
- method='Unsubscribe'))
+ events.append(EventPattern('dbus-return',
+ method='Unsubscribe'))
event = q.expect_many(*events)[0]
else:
@@ -172,47 +143,28 @@ def test(q, bus, conn, stream, remove, local, modern):
# type='unsubscribed'/> ack before doing so: empirical tests reveal
# that it's never delivered.
q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [h], [], [], 0, 0],
- path=subscribe.object_path),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{ h:
(cs.SUBSCRIPTION_STATE_NO, cs.SUBSCRIPTION_STATE_NO,
''),
- }, []],
+ }, { h: jid}, {}],
),
)
def test_remove_local(q, bus, conn, stream):
- test(q, bus, conn, stream, remove=True, local=True, modern=True)
+ test(q, bus, conn, stream, remove=True, local=True)
def test_unsubscribe_local(q, bus, conn, stream):
- test(q, bus, conn, stream, remove=False, local=True, modern=True)
+ test(q, bus, conn, stream, remove=False, local=True)
def test_remove_remote(q, bus, conn, stream):
- test(q, bus, conn, stream, remove=True, local=False, modern=True)
+ test(q, bus, conn, stream, remove=True, local=False)
def test_unsubscribe_remote(q, bus, conn, stream):
- test(q, bus, conn, stream, remove=False, local=False, modern=True)
-
-def test_remove_local_old(q, bus, conn, stream):
- test(q, bus, conn, stream, remove=True, local=True, modern=False)
-
-def test_unsubscribe_local_old(q, bus, conn, stream):
- test(q, bus, conn, stream, remove=False, local=True, modern=False)
-
-def test_remove_remote_old(q, bus, conn, stream):
- test(q, bus, conn, stream, remove=True, local=False, modern=False)
-
-def test_unsubscribe_remote_old(q, bus, conn, stream):
- test(q, bus, conn, stream, remove=False, local=False, modern=False)
+ test(q, bus, conn, stream, remove=False, local=False)
if __name__ == '__main__':
exec_test(test_remove_local)
exec_test(test_unsubscribe_local)
exec_test(test_remove_remote)
exec_test(test_unsubscribe_remote)
- exec_test(test_remove_local_old)
- exec_test(test_unsubscribe_local_old)
- exec_test(test_remove_remote_old)
- exec_test(test_unsubscribe_remote_old)
diff --git a/tests/twisted/roster/request-group-after-roster.py b/tests/twisted/roster/request-group-after-roster.py
deleted file mode 100644
index 2d5691957..000000000
--- a/tests/twisted/roster/request-group-after-roster.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-Regression test for a bug where CreateChannel times out when requesting a group
-channel after the roster has been received.
-"""
-
-from gabbletest import exec_test, sync_stream
-from servicetest import sync_dbus, call_async
-import constants as cs
-import ns
-
-def test(q, bus, conn, stream):
- roster_event = q.expect('stream-iq', query_ns=ns.ROSTER)
- roster_event.stanza['type'] = 'result'
-
- call_async(q, conn, "RequestHandles", cs.HT_GROUP, ['test'])
-
- event = q.expect('dbus-return', method='RequestHandles')
- test_handle = event.value[0][0]
-
- # send an empty roster
- stream.send(roster_event.stanza)
-
- sync_stream(q, stream)
- sync_dbus(bus, q, conn)
-
- call_async(q, conn.Requests, 'CreateChannel',
- { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST,
- cs.TARGET_HANDLE_TYPE: cs.HT_GROUP,
- cs.TARGET_HANDLE: test_handle,
- })
-
- event = q.expect('dbus-return', method='CreateChannel')
- ret_path, ret_props = event.value
-
- event = q.expect('dbus-signal', signal='NewChannels')
- path, props = event.args[0][0]
- assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_CONTACT_LIST, props
- assert props[cs.TARGET_HANDLE_TYPE] == cs.HT_GROUP, props
- assert props[cs.TARGET_HANDLE] == test_handle, props
- assert props[cs.TARGET_ID] == 'test', props
-
- assert ret_path == path, (ret_path, path)
- assert ret_props == props, (ret_props, props)
-
-if __name__ == '__main__':
- exec_test(test)
diff --git a/tests/twisted/roster/request-group-before-roster.py b/tests/twisted/roster/request-group-before-roster.py
deleted file mode 100644
index 0a736b22a..000000000
--- a/tests/twisted/roster/request-group-before-roster.py
+++ /dev/null
@@ -1,48 +0,0 @@
-"""
-Regression test for a bug where RequestChannel times out when requesting a
-group channel if the roster hasn't been received at the time of the call.
-"""
-
-from gabbletest import exec_test, sync_stream
-from servicetest import sync_dbus, call_async
-import constants as cs
-import ns
-
-def test(q, bus, conn, stream):
- roster_event = q.expect('stream-iq', query_ns=ns.ROSTER)
- roster_event.stanza['type'] = 'result'
-
- call_async(q, conn, "RequestHandles", cs.HT_GROUP, ['test'])
-
- event = q.expect('dbus-return', method='RequestHandles')
- test_handle = event.value[0][0]
-
- call_async(q, conn, 'RequestChannel', cs.CHANNEL_TYPE_CONTACT_LIST,
- cs.HT_GROUP, test_handle, True)
-
- # A previous incarnation of this test --- written with the intention that
- # RequestChannel would be called before the roster was received, to expose
- # a bug in Gabble triggered by that ordering --- was racy: if the D-Bus
- # daemon happened to be particularly busy, the call to RequestChannel
- # reached Gabble after the roster stanza. (The race was discovered when
- # that reversed order triggered a newly-introduced instance of the
- # opposite bug to the one the test was targetting!) So we sync the XMPP
- # stream and D-Bus queue here.
- sync_stream(q, stream)
- sync_dbus(bus, q, conn)
-
- # send an empty roster
- stream.send(roster_event.stanza)
-
- event = q.expect('dbus-return', method='RequestChannel')
- path = event.value[0]
-
- while True:
- event = q.expect('dbus-signal', signal='NewChannel')
- assert event.args[0] == path, (event.args, path)
- _, type, handle_type, handle, suppress_handler = event.args
- if handle_type == cs.HT_GROUP and handle == test_handle:
- break
-
-if __name__ == '__main__':
- exec_test(test)
diff --git a/tests/twisted/roster/test-google-roster.py b/tests/twisted/roster/test-google-roster.py
index 257661b6e..cff985dc1 100644
--- a/tests/twisted/roster/test-google-roster.py
+++ b/tests/twisted/roster/test-google-roster.py
@@ -7,7 +7,7 @@ from gabbletest import (
acknowledge_iq, exec_test, sync_stream, make_result_iq, GoogleXmlStream,
)
from rostertest import (
- expect_contact_list_signals, check_contact_list_signals,
+ check_contact_roster, contacts_changed_predicate, blocked_contacts_changed_predicate,
)
from servicetest import (
call_async, sync_dbus, EventPattern,
@@ -43,18 +43,6 @@ def add_roster_item(query, contact, state, ask, attrs={}):
return item
-def is_stored(event):
- return event.path.endswith('/stored')
-
-def is_subscribe(event):
- return event.path.endswith('/subscribe')
-
-def is_publish(event):
- return event.path.endswith('/publish')
-
-def is_deny(event):
- return event.path.endswith('/deny')
-
def test_inital_roster(q, bus, conn, stream):
"""
This part of the test checks that Gabble correctly alters on which lists
@@ -104,44 +92,36 @@ def test_inital_roster(q, bus, conn, stream):
# <https://bugs.launchpad.net/ubuntu/+source/telepathy-gabble/+bug/398293>,
# where Gabble was incorrectly hiding valid contacts.
- mutually_subscribed_contacts = ['lp-bug-398293@gmail.com',
- 'blocked-but-subscribed@boards.ca',
- 'music-is-math@boards.ca']
- rp_contacts = ['this-is-a-jid@badger.com']
+ contacts = [
+ ('lp-bug-398293@gmail.com', cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_YES, ''),
+ ('blocked-but-subscribed@boards.ca', cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_YES, ''),
+ ('music-is-math@boards.ca', cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_YES, ''),
+ ('this-is-a-jid@badger.com', cs.SUBSCRIPTION_STATE_ASK, cs.SUBSCRIPTION_STATE_NO, '')
+ ]
+
blocked_contacts = ['blocked-but-subscribed@boards.ca',
'blocked-and-no-sub@boards.ca',
'music-is-math@boards.ca']
- pairs = expect_contact_list_signals(q, bus, conn,
- ['publish', 'subscribe', 'stored', 'deny'])
-
- publish = check_contact_list_signals(q, bus, conn, pairs.pop(0),
- cs.HT_LIST, 'publish', mutually_subscribed_contacts)
- subscribe = check_contact_list_signals(q, bus, conn, pairs.pop(0),
- cs.HT_LIST, 'subscribe', mutually_subscribed_contacts,
- rp_contacts=rp_contacts)
- stored = check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'stored', mutually_subscribed_contacts + rp_contacts)
- deny = check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'deny', blocked_contacts)
-
- assertLength(0, pairs) # i.e. we've checked all of them
-
- return (publish, subscribe, stored, deny)
+ q.expect_many(
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
+ predicate=lambda e: contacts_changed_predicate(e, conn, contacts)),
+ EventPattern('dbus-signal', signal='BlockedContactsChanged',
+ predicate=lambda e: blocked_contacts_changed_predicate(e, blocked_contacts, [])),
+ )
-def test_flickering(q, bus, conn, stream, subscribe):
+def test_flickering(q, bus, conn, stream):
"""
Google's server is buggy; when asking to subscribe to somebody, the
subscription state transitions "flicker" sometimes. Here, we test that
Gabble is suppressing the flickers.
"""
- self_handle = conn.GetSelfHandle()
contact = 'bob@foo.com'
- handle = conn.RequestHandles(cs.HT_CONTACT, ['bob@foo.com'])[0]
+ handle = conn.get_contact_handle_sync('bob@foo.com')
# request subscription
- call_async(q, subscribe.Group, 'AddMembers', [handle], "")
+ call_async(q, conn.ContactList, 'RequestSubscription', [handle], '')
event = q.expect('stream-iq', iq_type='set', query_ns=ns.ROSTER)
item = event.query.firstChildElement()
@@ -177,26 +157,16 @@ def test_flickering(q, bus, conn, stream, subscribe):
# Gabble should report this update to the UI.
q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [handle], [], [], [], 0, cs.GC_REASON_NONE],
- predicate=is_stored),
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [], [], [handle], self_handle, cs.GC_REASON_NONE],
- predicate=is_subscribe),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{handle:
(cs.SUBSCRIPTION_STATE_ASK, cs.SUBSCRIPTION_STATE_NO, ''),
- }, []]),
+ }, {handle: contact}, {}]),
)
# Gabble shouldn't report any changes to subscribe or stored's members in
# response to the next two roster updates.
change_events = [
- EventPattern('dbus-signal', signal='MembersChanged',
- predicate=is_subscribe),
- EventPattern('dbus-signal', signal='MembersChanged',
- predicate=is_stored),
- EventPattern('dbus-signal', signal='ContactsChanged'),
+ EventPattern('dbus-signal', signal='ContactsChangedWithID'),
]
q.forbid_events(change_events)
@@ -235,15 +205,10 @@ def test_flickering(q, bus, conn, stream, subscribe):
stream.send(presence)
# Gabble should report this update to the UI.
- q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [handle], [], [], [], handle, cs.GC_REASON_NONE],
- predicate=is_subscribe),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ q.expect('dbus-signal', signal='ContactsChangedWithID',
args=[{handle:
(cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_NO, ''),
- }, []]),
- )
+ }, {handle: contact}, {}])
# Gabble shouldn't report any changes to subscribe or stored's members in
# response to the next two roster updates.
@@ -265,7 +230,7 @@ def test_flickering(q, bus, conn, stream, subscribe):
sync_dbus(bus, q, conn)
q.unforbid_events(change_events)
-def test_local_pending(q, bus, conn, stream, subscribe):
+def test_local_pending(q, bus, conn, stream):
"""
When somebody asks to subscribe to us, Google sends the subscription
request and then a roster update saying there is no subscription.
@@ -274,7 +239,7 @@ def test_local_pending(q, bus, conn, stream, subscribe):
"""
contact = 'alice@foo.com'
- handle = conn.RequestHandles(cs.HT_CONTACT, [contact])[0]
+ handle = conn.get_contact_handle_sync(contact)
# Alice asks to subscribes to us
presence = domish.Element(('jabber:client', 'presence'))
@@ -282,19 +247,25 @@ def test_local_pending(q, bus, conn, stream, subscribe):
presence['type'] = 'subscribe'
stream.send(presence)
- q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [], [handle], [], handle, cs.GC_REASON_NONE],
- predicate=is_publish),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ q.expect('dbus-signal', signal='ContactsChangedWithID',
args=[{handle: (cs.SUBSCRIPTION_STATE_NO,
- cs.SUBSCRIPTION_STATE_ASK, '')}, []]),
- )
+ cs.SUBSCRIPTION_STATE_ASK, '')}, {handle: contact}, {}])
+
+ def alice_state_changed(e):
+ # check that Alice's publish and subscribe state isn't changed
+ changes, ids, removal = e.args
+
+ subscription = changes.get(handle)
+ if subscription is None:
+ return False
+
+ subscribe, publish, request = subscription
+ return subscribe != cs.SUBSCRIPTION_STATE_NO and publish != cs.SUBSCRIPTION_STATE_ASK
# Now we send the spurious roster update with subscribe="none" and verify
# that nothing happens to her publish state in reaction to that
- change_event = EventPattern('dbus-signal', signal='MembersChanged',
- predicate=is_publish)
+ change_event = EventPattern('dbus-signal', signal='ContactsChangedWithID',
+ predicate=alice_state_changed)
q.forbid_events([change_event])
iq = make_set_roster_iq(stream, 'test@localhost/Resource', contact,
@@ -312,14 +283,9 @@ def test_local_pending(q, bus, conn, stream, subscribe):
presence['type'] = 'unsubscribe'
stream.send(presence)
- q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [handle], [], [], handle, cs.GC_REASON_NONE],
- predicate=is_publish),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ q.expect('dbus-signal', signal='ContactsChangedWithID',
args=[{handle: (cs.SUBSCRIPTION_STATE_NO,
- cs.SUBSCRIPTION_STATE_REMOVED_REMOTELY, '')}, []]),
- )
+ cs.SUBSCRIPTION_STATE_REMOVED_REMOTELY, '')}, {handle: contact}, {}])
# Now we send a roster roster update with subscribe="none" again (which
# doesn't change anything, it just confirms what we already knew) and
@@ -342,7 +308,7 @@ remove_events = [
)
]
-def test_deny_simple(q, bus, conn, stream, stored, deny):
+def test_deny_simple(q, bus, conn, stream):
"""
If we remove a blocked contact from 'stored', they shouldn't actually be
removed from the roster: rather, we should cancel both subscription
@@ -350,10 +316,12 @@ def test_deny_simple(q, bus, conn, stream, stored, deny):
remaining on 'deny'.
"""
contact = 'blocked-but-subscribed@boards.ca'
- handle = conn.RequestHandles(cs.HT_CONTACT, [contact])[0]
- assertContains(handle,
- stored.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members"))
- call_async(q, stored.Group, 'RemoveMembers', [handle], "")
+ handle = conn.get_contact_handle_sync(contact)
+
+ check_contact_roster(conn, contact, [],
+ cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_YES)
+
+ call_async(q, conn.ContactList, 'RemoveContacts', [handle])
q.forbid_events(remove_events)
@@ -362,7 +330,7 @@ def test_deny_simple(q, bus, conn, stream, stored, deny):
presence_type='unsubscribe'),
EventPattern('stream-presence', to=contact,
presence_type='unsubscribed'),
- EventPattern('dbus-return', method='RemoveMembers'),
+ EventPattern('dbus-return', method='RemoveContacts'),
)
# Our server sends roster pushes in response to our unsubscribe and
@@ -374,48 +342,39 @@ def test_deny_simple(q, bus, conn, stream, stored, deny):
# As a result they should drop off all three non-deny lists, but not fall
# off deny:
- q.expect_many(
- EventPattern('dbus-signal', signal='ContactsChanged',
- args=[{}, [handle]]),
- *[ EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [handle], [], [], 0, cs.GC_REASON_NONE],
- predicate=p)
- for p in [is_stored, is_subscribe, is_publish]
- ])
+ q.expect('dbus-signal', signal='ContactsChangedWithID', args=[{}, {}, {handle: contact}])
assertContains(handle,
- deny.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members"))
+ conn.ContactBlocking.RequestBlockedContacts().keys())
q.unforbid_events(remove_events)
-def test_deny_overlap_one(q, bus, conn, stream, subscribe, stored, deny):
+def test_deny_overlap_one(q, bus, conn, stream):
"""
Here's a tricker case: blocking a contact, and then removing them before
the server's responded to the block request.
"""
- self_handle = conn.GetSelfHandle()
# As we saw in test_flickering(), we have a subscription to Bob,
# everything's peachy.
contact = 'bob@foo.com'
- handle = conn.RequestHandles(cs.HT_CONTACT, ['bob@foo.com'])[0]
+ handle = conn.get_contact_handle_sync(contact)
- assertContains(handle,
- stored.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members"))
- assertContains(handle,
- subscribe.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members"))
+ check_contact_roster(conn, contact, [],
+ cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_NO)
q.forbid_events(remove_events)
# But then we have a falling out. In a blind rage, I block Bob:
- call_async(q, deny.Group, 'AddMembers', [handle], "")
+ call_async(q, conn.ContactBlocking, 'BlockContacts', [handle], "")
event = q.expect('stream-iq', query_ns=ns.ROSTER)
item = event.query.firstChildElement()
assertEquals(contact, item['jid'])
assertEquals('B', item[(ns.GOOGLE_ROSTER, 't')])
- # Then — *before the server has replied* — I remove him from stored.
- call_async(q, stored.Group, 'RemoveMembers', [handle], "")
+ # Then — *before the server has replied* — I remove him from the contact
+ # list.
+ call_async(q, conn.ContactList, 'RemoveContacts', [handle])
# subscription='remove' is still forbidden from above. So we sync to ensure
# that Gabble's received RemoveMembers, and if it's going to send us a
@@ -437,8 +396,8 @@ def test_deny_overlap_one(q, bus, conn, stream, subscribe, stored, deny):
q.forbid_events(unsubscribed_events)
q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged', predicate=is_deny,
- args=["", [handle], [], [], [], self_handle, 0]),
+ EventPattern('dbus-signal', signal='BlockedContactsChanged',
+ predicate=lambda e: blocked_contacts_changed_predicate(e, [contact], [])),
EventPattern('stream-presence', to=contact,
presence_type='unsubscribe'),
)
@@ -448,26 +407,17 @@ def test_deny_overlap_one(q, bus, conn, stream, subscribe, stored, deny):
"none", False, attrs={'gr:t': 'B'}))
# As a result, Gabble makes Bob fall off subscribe and stored.
- q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- predicate=is_subscribe,
- args=["", [], [handle], [], [], 0, 0]),
- EventPattern('dbus-signal', signal='MembersChanged',
- predicate=is_stored,
- args=["", [], [handle], [], [], 0, 0]),
- EventPattern('dbus-signal', signal='ContactsChanged',
- args=[{}, [handle]]),
- )
+ q.expect('dbus-signal', signal='ContactsChangedWithID',
+ args=[{}, {}, {handle: contact}])
# And he should definitely still be on deny. That rascal.
assertContains(handle,
- deny.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members"))
+ conn.ContactBlocking.RequestBlockedContacts().keys())
q.unforbid_events(unsubscribed_events)
q.unforbid_events(remove_events)
-def test_deny_overlap_two(q, bus, conn, stream,
- subscribe, publish, stored, deny):
+def test_deny_overlap_two(q, bus, conn, stream):
"""
Here's another tricky case: editing a contact (setting an alias, say), and
then while that edit's in flight, blocking and remove the contact.
@@ -475,14 +425,10 @@ def test_deny_overlap_two(q, bus, conn, stream,
# This contact was on our roster when we started.
contact = 'lp-bug-398293@gmail.com'
- handle = conn.RequestHandles(cs.HT_CONTACT, [contact])[0]
+ handle = conn.get_contact_handle_sync(contact)
- assertContains(handle,
- stored.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members"))
- assertContains(handle,
- subscribe.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members"))
- assertContains(handle,
- publish.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members"))
+ check_contact_roster(conn, contact, [],
+ cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_YES)
# Once again, at no point in this test should anyone be removed outright.
q.forbid_events(remove_events)
@@ -504,8 +450,8 @@ def test_deny_overlap_two(q, bus, conn, stream,
]
q.forbid_events(patterns)
- call_async(q, deny.Group, 'AddMembers', [handle], "")
- call_async(q, stored.Group, 'RemoveMembers', [handle], "")
+ call_async(q, conn.ContactBlocking, 'BlockContacts', [handle], "")
+ call_async(q, conn.ContactList, 'RemoveContacts', [handle])
# Make sure if the edits are sent prematurely, we've got them.
sync_stream(q, stream)
@@ -524,27 +470,27 @@ def test_deny_overlap_two(q, bus, conn, stream,
# And we're done. Clean up.
q.unforbid_events(remove_events)
-def test_deny_unblock_remove(q, bus, conn, stream, stored, deny):
+def test_deny_unblock_remove(q, bus, conn, stream):
"""
Test unblocking a contact, and, while that request is pending, deleting
them.
"""
- self_handle = conn.GetSelfHandle()
# This contact was on our roster, blocked and subscribed, when we started.
contact = 'music-is-math@boards.ca'
- handle = conn.RequestHandles(cs.HT_CONTACT, [contact])[0]
+ handle = conn.get_contact_handle_sync(contact)
+
+ check_contact_roster(conn, contact, [],
+ cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_YES)
# They're blocked, and we have a bidi subscription, so they should be on
# deny and stored. (We already checked this earlier, but we've been messing
# with the roster so let's be sure the preconditions are okay...)
assertContains(handle,
- deny.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members"))
- assertContains(handle,
- stored.Properties.Get(cs.CHANNEL_IFACE_GROUP, "Members"))
+ conn.ContactBlocking.RequestBlockedContacts().keys())
# Unblock them.
- call_async(q, deny.Group, 'RemoveMembers', [handle], "")
+ call_async(q, conn.ContactBlocking, 'UnblockContacts', [handle])
roster_event = q.expect('stream-iq', query_ns=ns.ROSTER)
item = roster_event.query.firstChildElement()
@@ -554,7 +500,7 @@ def test_deny_unblock_remove(q, bus, conn, stream, stored, deny):
# If we now remove them from stored, the edit shouldn't be sent until the
# unblock event has had a reply.
q.forbid_events(remove_events)
- call_async(q, stored.Group, 'RemoveMembers', [handle], "")
+ call_async(q, conn.ContactList, 'RemoveContacts', [handle])
# Make sure if the remove is sent prematurely, we catch it.
sync_stream(q, stream)
@@ -569,9 +515,8 @@ def test_deny_unblock_remove(q, bus, conn, stream, stored, deny):
# removed from deny, and send a remove.
_, roster_event = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [handle], [], [], self_handle, cs.GC_REASON_NONE],
- predicate=is_deny),
+ EventPattern('dbus-signal', signal='BlockedContactsChanged',
+ predicate=lambda e: blocked_contacts_changed_predicate(e, [], [contact])),
remove_events[0],
)
item = roster_event.query.firstChildElement()
@@ -581,11 +526,7 @@ def test_deny_unblock_remove(q, bus, conn, stream, stored, deny):
'remove', False, attrs={}))
acknowledge_iq(stream, roster_event.stanza)
- q.expect('dbus-signal', signal='MembersChanged',
- args=['', [], [handle], [], [], 0, cs.GC_REASON_NONE],
- predicate=is_stored)
-
-def test_contact_blocking(q, bus, conn, stream, stored, deny):
+def test_contact_blocking(q, bus, conn, stream):
"""test ContactBlocking API"""
assertContains(cs.CONN_IFACE_CONTACT_BLOCKING,
conn.Properties.Get(cs.CONN, "Interfaces"))
@@ -596,16 +537,15 @@ def test_contact_blocking(q, bus, conn, stream, stored, deny):
assertLength(3, blocked)
def test(q, bus, conn, stream):
- publish, subscribe, stored, deny = test_inital_roster(q, bus, conn, stream)
-
- test_flickering(q, bus, conn, stream, subscribe)
- test_local_pending(q, bus, conn, stream, subscribe)
- test_deny_simple(q, bus, conn, stream, stored, deny)
- test_deny_overlap_one(q, bus, conn, stream, subscribe, stored, deny)
- test_deny_overlap_two(q, bus, conn, stream,
- subscribe, publish, stored, deny)
- test_deny_unblock_remove(q, bus, conn, stream, stored, deny)
- test_contact_blocking(q, bus, conn, stream, stored, deny)
+ test_inital_roster(q, bus, conn, stream)
+
+ test_flickering(q, bus, conn, stream)
+ test_local_pending(q, bus, conn, stream)
+ test_deny_simple(q, bus, conn, stream)
+ test_deny_overlap_one(q, bus, conn, stream)
+ test_deny_overlap_two(q, bus, conn, stream)
+ test_deny_unblock_remove(q, bus, conn, stream)
+ test_contact_blocking(q, bus, conn, stream)
if __name__ == '__main__':
exec_test(test, protocol=GoogleXmlStream)
diff --git a/tests/twisted/roster/test-roster-item-deletion.py b/tests/twisted/roster/test-roster-item-deletion.py
index 027446809..9e008f30d 100644
--- a/tests/twisted/roster/test-roster-item-deletion.py
+++ b/tests/twisted/roster/test-roster-item-deletion.py
@@ -3,25 +3,18 @@ Regression test for http://bugs.freedesktop.org/show_bug.cgi?id=19524
"""
from gabbletest import exec_test, acknowledge_iq
-from rostertest import (expect_contact_list_signals,
- check_contact_list_signals, send_roster_push)
-from servicetest import (assertLength, assertEquals, EventPattern, call_async)
+from rostertest import (send_roster_push, check_contact_roster)
+from servicetest import (assertEquals, EventPattern, call_async)
import constants as cs
import ns
-def test_ancient(q, bus, conn, stream):
- test(q, bus, conn, stream, False)
-
def test_modern(q, bus, conn, stream):
- test(q, bus, conn, stream, True)
-
-def test_ancient_queued(q, bus, conn, stream):
- test(q, bus, conn, stream, False, True)
+ test(q, bus, conn, stream)
def test_modern_queued(q, bus, conn, stream):
- test(q, bus, conn, stream, True, True)
+ test(q, bus, conn, stream, True)
-def test(q, bus, conn, stream, modern=True, queued=False):
+def test(q, bus, conn, stream, queued=False):
event = q.expect('stream-iq', query_ns=ns.ROSTER)
event.stanza['type'] = 'result'
@@ -29,28 +22,18 @@ def test(q, bus, conn, stream, modern=True, queued=False):
item['jid'] = 'quux@foo.com'
item['subscription'] = 'none'
- quux_handle = conn.RequestHandles(cs.HT_CONTACT, ['quux@foo.com'])[0]
+ quux_handle = conn.get_contact_handle_sync('quux@foo.com')
stream.send(event.stanza)
# slight implementation detail: TpBaseContactList emits ContactsChanged
# before it announces its channels
- q.expect('dbus-signal', signal='ContactsChanged',
+ q.expect('dbus-signal', signal='ContactsChangedWithID',
interface=cs.CONN_IFACE_CONTACT_LIST, path=conn.object_path,
args=[{quux_handle:
- (cs.SUBSCRIPTION_STATE_NO, cs.SUBSCRIPTION_STATE_NO, '')}, []])
-
- pairs = expect_contact_list_signals(q, bus, conn,
- ['publish', 'subscribe', 'stored'])
-
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'publish', [])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'subscribe', [])
- stored = check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'stored', ['quux@foo.com'])
+ (cs.SUBSCRIPTION_STATE_NO, cs.SUBSCRIPTION_STATE_NO, '')}, {quux_handle: 'quux@foo.com'}, {}])
- assertLength(0, pairs) # i.e. we've checked all of them
+ check_contact_roster(conn, 'quux@foo.com', [], cs.SUBSCRIPTION_STATE_NO, cs.SUBSCRIPTION_STATE_NO)
if queued:
conn.Aliasing.SetAliases({quux_handle: 'Quux'})
@@ -64,10 +47,7 @@ def test(q, bus, conn, stream, modern=True, queued=False):
iq_type='set', query_ns=ns.ROSTER),
]
- if modern:
- call_async(q, conn.ContactList, 'RemoveContacts', [quux_handle])
- else:
- call_async(q, stored.Group, 'RemoveMembers', [quux_handle], '')
+ call_async(q, conn.ContactList, 'RemoveContacts', [quux_handle])
if queued:
# finish off the previous thing we were doing, so removal can proceed
@@ -81,24 +61,18 @@ def test(q, bus, conn, stream, modern=True, queued=False):
send_roster_push(stream, 'quux@foo.com', 'remove')
q.expect_many(
- EventPattern('dbus-signal', interface=cs.CHANNEL_IFACE_GROUP,
- path=stored.object_path, signal='MembersChanged',
- args=['', [], [quux_handle], [], [], 0, 0]),
EventPattern('dbus-signal', interface=cs.CONN_IFACE_CONTACT_LIST,
- path=conn.object_path, signal='ContactsChanged',
- args=[{}, [quux_handle]]),
+ path=conn.object_path, signal='ContactsChangedWithID',
+ args=[{}, {}, {quux_handle: 'quux@foo.com'}]),
EventPattern('stream-iq', iq_id='push', iq_type='result'),
)
acknowledge_iq(stream, event.stanza)
- if modern:
- q.expect('dbus-return', method='RemoveContacts')
+ q.expect('dbus-return', method='RemoveContacts')
# FIXME: when we depend on a new enough tp-glib, RemoveMembers should
# return at this point too
if __name__ == '__main__':
- exec_test(test_ancient)
exec_test(test_modern)
- exec_test(test_ancient_queued)
exec_test(test_modern_queued)
diff --git a/tests/twisted/roster/test-roster-subscribe.py b/tests/twisted/roster/test-roster-subscribe.py
index 23979d385..43eb2ddff 100644
--- a/tests/twisted/roster/test-roster-subscribe.py
+++ b/tests/twisted/roster/test-roster-subscribe.py
@@ -5,91 +5,47 @@ Test subscribing to a contact's presence.
from twisted.words.xish import domish
-from servicetest import (EventPattern, assertLength, assertEquals,
- call_async, wrap_channel, sync_dbus)
+from servicetest import (EventPattern, assertEquals, call_async, sync_dbus)
from gabbletest import (acknowledge_iq, exec_test, sync_stream)
from rostertest import send_roster_push
import constants as cs
import ns
-def test_ancient(q, bus, conn, stream):
- test(q, bus, conn, stream, False)
-
def test_modern(q, bus, conn, stream):
- test(q, bus, conn, stream, True)
-
-def test_ancient_remove(q, bus, conn, stream):
- test(q, bus, conn, stream, False, True)
+ test(q, bus, conn, stream)
def test_modern_remove(q, bus, conn, stream):
- test(q, bus, conn, stream, True, True)
-
-def test_ancient_reject(q, bus, conn, stream):
- test(q, bus, conn, stream, False, 'reject')
+ test(q, bus, conn, stream, True)
def test_modern_reject(q, bus, conn, stream):
- test(q, bus, conn, stream, True, 'reject')
-
-def test_ancient_reject_remove(q, bus, conn, stream):
- test(q, bus, conn, stream, False, True, 'reject')
+ test(q, bus, conn, stream, False, 'reject')
def test_modern_reject_remove(q, bus, conn, stream):
- test(q, bus, conn, stream, True, True, 'reject')
-
-def test_ancient_revoke(q, bus, conn, stream):
- test(q, bus, conn, stream, False, 'revoke')
+ test(q, bus, conn, stream, True, 'reject')
def test_modern_revoke(q, bus, conn, stream):
- test(q, bus, conn, stream, True, 'revoke')
-
-def test_ancient_revoke_remove(q, bus, conn, stream):
- test(q, bus, conn, stream, False, True, 'revoke')
+ test(q, bus, conn, stream, 'revoke')
def test_modern_revoke_remove(q, bus, conn, stream):
- test(q, bus, conn, stream, True, True, 'revoke')
+ test(q, bus, conn, stream, True, 'revoke')
-def test(q, bus, conn, stream, modern=True, remove=False, remote='accept'):
+def test(q, bus, conn, stream, remove=False, remote='accept'):
event = q.expect('stream-iq', query_ns=ns.ROSTER)
# send back empty roster
event.stanza['type'] = 'result'
stream.send(event.stanza)
- while True:
- event = q.expect('dbus-signal', signal='NewChannel')
- path, type, handle_type, handle, suppress_handler = event.args
-
- if type != cs.CHANNEL_TYPE_CONTACT_LIST:
- continue
-
- chan_name = conn.InspectHandles(handle_type, [handle])[0]
-
- if chan_name == 'subscribe':
- break
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'ContactList')
- assertLength(0, chan.Group.GetMembers())
-
- stored_path = conn.Requests.EnsureChannel({
- cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_CONTACT_LIST,
- cs.TARGET_HANDLE_TYPE: cs.HT_LIST,
- cs.TARGET_ID: 'stored',
- })[1]
- stored = wrap_channel(bus.get_object(conn.bus_name, stored_path),
- 'ContactList')
+ q.expect('dbus-signal', signal='ContactListStateChanged', args=[cs.CONTACT_LIST_STATE_SUCCESS])
# request subscription
- alice, bob = conn.RequestHandles(cs.HT_CONTACT,
+ alice, bob = conn.get_contact_handles_sync(
['alice@foo.com', 'bob@foo.com'])
# Repeated subscription requests are *not* idempotent: the second request
# should nag the contact again.
for first_time in True, False, False:
- if modern:
- call_async(q, conn.ContactList, 'RequestSubscription', [bob],
- 'plz add kthx')
- else:
- call_async(q, chan.Group, 'AddMembers', [bob],
- 'plz add kthx')
+ call_async(q, conn.ContactList, 'RequestSubscription', [bob],
+ 'plz add kthx')
if first_time:
event = q.expect('stream-iq', iq_type='set', query_ns=ns.ROSTER)
@@ -101,9 +57,8 @@ def test(q, bus, conn, stream, modern=True, remove=False, remote='accept'):
EventPattern('stream-presence', presence_type='subscribe'),
]
- if modern:
- expectations.append(EventPattern('dbus-return',
- method='RequestSubscription'))
+ expectations.append(EventPattern('dbus-return',
+ method='RequestSubscription'))
event = q.expect_many(*expectations)[0]
assertEquals('plz add kthx', event.presence_status)
@@ -127,15 +82,16 @@ def test(q, bus, conn, stream, modern=True, remove=False, remote='accept'):
stream.send(presence)
q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [bob], [], [], bob,
- cs.GC_REASON_PERMISSION_DENIED]),
+ EventPattern('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e: e.args[0] == [] and e.args[1] == [bob] and
+ e.args[2] == [] and e.args[3] == [] and
+ e.args[4]['change-reason'] == cs.GC_REASON_PERMISSION_DENIED),
#EventPattern('stream-presence'),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{bob:
(cs.SUBSCRIPTION_STATE_REMOVED_REMOTELY,
cs.SUBSCRIPTION_STATE_NO, ''),
- }, []]),
+ }, {bob: 'bob@foo.com'}, {}]),
)
send_roster_push(stream, 'bob@foo.com', 'to')
@@ -148,13 +104,14 @@ def test(q, bus, conn, stream, modern=True, remove=False, remote='accept'):
stream.send(presence)
q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [bob], [], [], [], bob, 0]),
+ EventPattern('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e: e.args[0] == [bob] and e.args[1] == [] and
+ e.args[2] == [] and e.args[3] == []),
EventPattern('stream-presence'),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{bob:
(cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_NO, ''),
- }, []]),
+ }, {bob: 'bob@foo.com'}, {}]),
)
send_roster_push(stream, 'bob@foo.com', 'to')
@@ -188,15 +145,16 @@ def test(q, bus, conn, stream, modern=True, remove=False, remote='accept'):
stream.send(presence)
q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=['', [], [bob], [], [], bob,
- cs.GC_REASON_PERMISSION_DENIED]),
+ EventPattern('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e: e.args[0] == [] and e.args[1] == [bob] and
+ e.args[2] == [] and e.args[3] == [] and
+ e.args[4]['change-reason'] == cs.GC_REASON_PERMISSION_DENIED),
EventPattern('stream-presence'),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{bob:
(cs.SUBSCRIPTION_STATE_REMOVED_REMOTELY,
cs.SUBSCRIPTION_STATE_NO, ''),
- }, []]),
+ }, {bob: 'bob@foo.com'}, {}]),
)
# Else, Bob isn't actually as interesting as we thought. Never mind,
@@ -206,26 +164,12 @@ def test(q, bus, conn, stream, modern=True, remove=False, remote='accept'):
# (Unsubscribing from pending-subscribe is tested in
# roster/removed-from-rp-subscribe.py so we don't test it here.)
- # If Bob removed us, we have to use modern APIs from now on, because from
- # the point of view of the old Group interface, removed remotely and
- # removed locally are synonymous.
- if remote in ('reject', 'revoke'):
- modern = True
-
- if modern:
- if remove:
- returning_method = 'RemoveContacts'
- call_async(q, conn.ContactList, 'RemoveContacts', [bob])
- else:
- returning_method = 'Unsubscribe'
- call_async(q, conn.ContactList, 'Unsubscribe', [bob])
+ if remove:
+ returning_method = 'RemoveContacts'
+ call_async(q, conn.ContactList, 'RemoveContacts', [bob])
else:
- returning_method = 'RemoveMembers'
-
- if remove:
- call_async(q, stored.Group, 'RemoveMembers', [bob], '')
- else:
- call_async(q, chan.Group, 'RemoveMembers', [bob], '')
+ returning_method = 'Unsubscribe'
+ call_async(q, conn.ContactList, 'Unsubscribe', [bob])
if remove:
iq = q.expect('stream-iq', iq_type='set', query_ns=ns.ROSTER,
@@ -233,16 +177,15 @@ def test(q, bus, conn, stream, modern=True, remove=False, remote='accept'):
acknowledge_iq(stream, iq.stanza)
- if modern:
- q.expect('dbus-return', method='RemoveContacts')
+ q.expect('dbus-return', method='RemoveContacts')
# FIXME: when we depend on a new enough tp-glib, expect RemoveMembers
# to return here too
send_roster_push(stream, 'bob@foo.com', 'remove')
q.expect_many(
EventPattern('stream-iq', iq_type='result', iq_id='push'),
- EventPattern('dbus-signal', signal='ContactsChanged',
- args=[{}, [bob]]),
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
+ args=[{}, {}, {bob: 'bob@foo.com'}]),
)
else:
q.expect_many(
@@ -254,22 +197,16 @@ def test(q, bus, conn, stream, modern=True, remove=False, remote='accept'):
send_roster_push(stream, 'bob@foo.com', 'none')
q.expect_many(
EventPattern('stream-iq', iq_type='result', iq_id='push'),
- EventPattern('dbus-signal', signal='ContactsChanged',
+ EventPattern('dbus-signal', signal='ContactsChangedWithID',
args=[{bob:
(cs.SUBSCRIPTION_STATE_NO, cs.SUBSCRIPTION_STATE_NO, ''),
- }, []]),
+ }, {bob: 'bob@foo.com'}, {}]),
)
if __name__ == '__main__':
- exec_test(test_ancient)
exec_test(test_modern)
- exec_test(test_ancient_remove)
exec_test(test_modern_remove)
- exec_test(test_ancient_revoke)
exec_test(test_modern_revoke)
- exec_test(test_ancient_revoke_remove)
exec_test(test_modern_revoke_remove)
- exec_test(test_ancient_reject)
exec_test(test_modern_reject)
- exec_test(test_ancient_reject_remove)
exec_test(test_modern_reject_remove)
diff --git a/tests/twisted/roster/test-roster.py b/tests/twisted/roster/test-roster.py
index 04fee09d8..407eb2bfa 100644
--- a/tests/twisted/roster/test-roster.py
+++ b/tests/twisted/roster/test-roster.py
@@ -3,8 +3,8 @@ Test basic roster functionality.
"""
from gabbletest import exec_test
-from rostertest import expect_contact_list_signals, check_contact_list_signals
-from servicetest import (assertEquals, assertLength, call_async)
+from rostertest import check_contact_roster, contacts_changed_predicate
+from servicetest import (assertEquals, call_async)
import constants as cs
import ns
@@ -37,23 +37,21 @@ def test(q, bus, conn, stream):
# roster query twice. This used to crash Gabble.
stream.send(event.stanza)
+ contacts = [
+ ('amy@foo.com', cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_YES, ''),
+ ('bob@foo.com', cs.SUBSCRIPTION_STATE_NO, cs.SUBSCRIPTION_STATE_YES, ''),
+ ('che@foo.com', cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_NO, ''),
+ ]
+
# slight implementation detail: TpBaseContactList emits ContactsChanged
# before it announces its channels
- s = q.expect('dbus-signal', signal='ContactsChanged',
- interface=cs.CONN_IFACE_CONTACT_LIST, path=conn.object_path)
+ q.expect('dbus-signal', signal='ContactsChangedWithID',
+ interface=cs.CONN_IFACE_CONTACT_LIST, path=conn.object_path,
+ predicate=lambda e: contacts_changed_predicate(e, conn, contacts))
- amy, bob, che = conn.RequestHandles(cs.HT_CONTACT,
+ amy, bob, che = conn.get_contact_handles_sync(
['amy@foo.com', 'bob@foo.com', 'che@foo.com'])
- assertEquals([{
- amy: (cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_YES, ''),
- bob: (cs.SUBSCRIPTION_STATE_NO, cs.SUBSCRIPTION_STATE_YES, ''),
- che: (cs.SUBSCRIPTION_STATE_YES, cs.SUBSCRIPTION_STATE_NO, ''),
- }, []], s.args)
-
- pairs = expect_contact_list_signals(q, bus, conn,
- ['publish', 'subscribe', 'stored'])
-
# this is emitted last, so clients can tell when the initial state dump
# has finished
q.expect('dbus-signal', signal='ContactListStateChanged',
@@ -82,14 +80,5 @@ def test(q, bus, conn, stream):
},
},), r.value)
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'publish', ['amy@foo.com', 'bob@foo.com'])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'subscribe', ['amy@foo.com', 'che@foo.com'])
- check_contact_list_signals(q, bus, conn, pairs.pop(0), cs.HT_LIST,
- 'stored', ['amy@foo.com', 'bob@foo.com', 'che@foo.com'])
-
- assertLength(0, pairs) # i.e. we've checked all of them
-
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/roster/test-save-alias-to-roster.py b/tests/twisted/roster/test-save-alias-to-roster.py
index 2164915d5..0f67da0ae 100644
--- a/tests/twisted/roster/test-save-alias-to-roster.py
+++ b/tests/twisted/roster/test-save-alias-to-roster.py
@@ -3,15 +3,13 @@
Test that updating an alias saves it to the roster.
"""
-import dbus
-
from servicetest import EventPattern, call_async, assertEquals
from gabbletest import (
acknowledge_iq, exec_test, make_result_iq, sync_stream, elem
)
import constants as cs
import ns
-from rostertest import expect_contact_list_signals, send_roster_push
+from rostertest import send_roster_push
from pubsub import make_pubsub_event
def send_pep_nick_reply(stream, stanza, nickname):
@@ -52,22 +50,16 @@ def test(q, bus, conn, stream):
acknowledge_iq(stream, event.stanza)
acknowledge_iq(stream, event2.stanza)
- signals = expect_contact_list_signals(q, bus, conn, lists=['subscribe'])
- old_signal, new_signal = signals[0]
- path = old_signal.args[0]
+ q.expect('dbus-signal', signal='ContactListStateChanged', args=[cs.CONTACT_LIST_STATE_SUCCESS])
# request subscription
- chan = bus.get_object(conn.bus_name, path)
- group_iface = dbus.Interface(chan, cs.CHANNEL_IFACE_GROUP)
- assert group_iface.GetMembers() == []
- handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
- call_async(q, group_iface, 'AddMembers', [handle], '')
+ handle = conn.get_contact_handle_sync('bob@foo.com')
+ call_async(q, conn.ContactList, 'RequestSubscription', [handle], '')
event = q.expect('stream-iq', iq_type='set', query_ns=ns.ROSTER)
- item = event.query.firstChildElement()
acknowledge_iq(stream, event.stanza)
- q.expect('dbus-return', method='AddMembers')
+ q.expect('dbus-return', method='RequestSubscription')
call_async(q, conn.Aliasing, 'RequestAliases', [handle])
@@ -88,7 +80,7 @@ def test(q, bus, conn, stream):
# the current semantics where the alias is always meant to be something you
# could show, even if it's just their JID), so let's forbid that.
jid = 'parts@labor.lit'
- handle = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ handle = conn.get_contact_handle_sync(jid)
q.forbid_events([EventPattern('dbus-signal', signal='AliasesChanged',
args=[[(handle, '')]])])
@@ -96,10 +88,11 @@ def test(q, bus, conn, stream):
# I don't really have very strong opinions on whether Gabble should be
# signalling that this contact's alias has *changed* per se, so am not
# explicitly expecting that.
- q.expect('dbus-signal', signal='MembersChanged')
+ q.expect('dbus-signal', signal='MembersChangedDetailed')
# But if we ask for it, Gabble should probably send a PEP query.
- assertEquals(jid, conn.Aliasing.GetAliases([handle])[handle])
+ h2asv = conn.Contacts.GetContactAttributes([handle], [cs.CONN_IFACE_ALIASING], False)
+ assertEquals(jid, h2asv[handle][cs.ATTR_ALIAS])
event = q.expect('stream-iq', iq_type='get', query_ns=ns.PUBSUB, to=jid)
nick = 'Constant Future'
@@ -110,7 +103,7 @@ def test(q, bus, conn, stream):
# because we've cached that they have no alias. Gabble shouldn't make
# unsolicited PEP or vCard queries to them.
jid = 'friendly@faith.plate'
- handle = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ handle = conn.get_contact_handle_sync(jid)
q.forbid_events([
EventPattern('stream-iq', query_ns=ns.PUBSUB, to=jid),
@@ -148,7 +141,7 @@ def test(q, bus, conn, stream):
# Here's a contact we haven't seen before, pushed to our roster with a
# nickname already there.
jid = 'glados@aperture.lit'
- handle = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ handle = conn.get_contact_handle_sync(jid)
nick = 'Potato'
send_roster_push(stream, jid, 'both', name=nick)
diff --git a/tests/twisted/rostertest.py b/tests/twisted/rostertest.py
index 3d31ad454..c3fb03c3b 100644
--- a/tests/twisted/rostertest.py
+++ b/tests/twisted/rostertest.py
@@ -1,8 +1,6 @@
from twisted.words.protocols.jabber.client import IQ
-from gabbletest import (wrap_channel,)
-from servicetest import (assertEquals, assertLength, EventPattern,
- assertContains)
+from servicetest import (assertEquals, assertSameSets)
import constants as cs
import ns
@@ -29,129 +27,57 @@ def send_roster_push(stream, jid, subscription, ask_subscribe=False, name=None):
ask_subscribe=ask_subscribe, name=name)
stream.send(iq)
-def get_contact_list_event_patterns(q, bus, conn, expected_handle_type, name):
- expected_handle = conn.RequestHandles(expected_handle_type, [name])[0]
+# check that @contact on @conn is in groups @groups with @subscribe and
+# @publish as subscription states
+def check_contact_roster(conn, contact, groups=None, subscribe=None, publish=None):
+ h = conn.get_contact_handle_sync(contact)
+ attrs = conn.Contacts.GetContactAttributes([h],
+ [cs.CONN_IFACE_CONTACT_LIST, cs.CONN_IFACE_CONTACT_GROUPS], True)[h]
- def new_channel_predicate(e):
- path, type, handle_type, handle, suppress_handler = e.args
- if type != cs.CHANNEL_TYPE_CONTACT_LIST:
- return False
- if handle_type != expected_handle_type:
- return False
- if handle != expected_handle:
- return False
- return True
- new_channel_repr = ('NewChannel(., ContactList, %u, "%s", .)'
- % (expected_handle_type, name))
- new_channel_predicate.__repr__ = lambda: new_channel_repr
-
- def new_channels_predicate(e):
- info, = e.args
- if len(info) != 1:
- return False
- path, props = info[0]
- if props.get(cs.CHANNEL_TYPE) != cs.CHANNEL_TYPE_CONTACT_LIST:
- return False
- if props.get(cs.TARGET_HANDLE_TYPE) != expected_handle_type:
- return False
- if props.get(cs.TARGET_HANDLE) != expected_handle:
+ if groups is not None:
+ assertSameSets(groups, attrs[cs.ATTR_GROUPS])
+ if subscribe is not None:
+ assertEquals(subscribe, attrs[cs.ATTR_SUBSCRIBE])
+ if publish is not None:
+ assertEquals(publish, attrs[cs.ATTR_PUBLISH])
+
+# function to pass as 'ContactsChangedWithID' dbus-signal even predicate
+# checking if the (contact-id, subscribe-state, publish-state, message) tuples
+# from @contacts are the arguments of the signal.
+def contacts_changed_predicate(e, conn, contacts):
+ changes, ids, removals = e.args
+
+ if len(changes) != len(contacts):
+ return False
+
+ for c in contacts:
+ i, subscribe, publish, msg = c
+
+ h = conn.get_contact_handle_sync(i)
+
+ if changes[h] != (subscribe, publish, msg):
return False
- return True
- new_channels_repr = ('NewChannels(... ct=ContactList, ht=%u, name="%s"... )'
- % (expected_handle_type, name))
- new_channels_predicate.__repr__ = lambda: new_channels_repr
-
- return (
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=new_channel_predicate),
- EventPattern('dbus-signal', signal='NewChannels',
- predicate=new_channels_predicate)
- )
-
-def expect_contact_list_signals(q, bus, conn, lists, groups=[]):
- assert lists or groups
-
- eps = []
-
- for name in lists:
- eps.extend(get_contact_list_event_patterns(q, bus, conn,
- cs.HT_LIST, name))
-
- for name in groups:
- eps.extend(get_contact_list_event_patterns(q, bus, conn,
- cs.HT_GROUP, name))
-
- events = q.expect_many(*eps)
- ret = []
-
- for name in lists:
- old_signal = events.pop(0)
- new_signal = events.pop(0)
- ret.append((old_signal, new_signal))
-
- for name in groups:
- old_signal = events.pop(0)
- new_signal = events.pop(0)
- ret.append((old_signal, new_signal))
-
- assert len(events) == 0
- return ret
-
-def check_contact_list_signals(q, bus, conn, signals,
- ht, name, contacts, lp_contacts=[], rp_contacts=[]):
- """
- Looks at NewChannel and NewChannels signals for the contact list with ID
- 'name' and checks that its members, lp members and rp members are exactly
- 'contacts', 'lp_contacts' and 'rp_contacts'.
- Returns a proxy for the channel.
- """
- old_signal, new_signal = signals
-
- path, type, handle_type, handle, suppress_handler = old_signal.args
-
- assertEquals(cs.CHANNEL_TYPE_CONTACT_LIST, type)
- assertEquals(name, conn.InspectHandles(handle_type, [handle])[0])
-
- chan = wrap_channel(bus.get_object(conn.bus_name, path),
- cs.CHANNEL_TYPE_CONTACT_LIST)
- members = chan.Group.GetMembers()
-
- assertEquals(sorted(contacts),
- sorted(conn.InspectHandles(cs.HT_CONTACT, members)))
-
- lp_handles = conn.RequestHandles(cs.HT_CONTACT, lp_contacts)
- rp_handles = conn.RequestHandles(cs.HT_CONTACT, rp_contacts)
-
- # NB. comma: we're unpacking args. Thython!
- info, = new_signal.args
- assertLength(1, info) # one channel
- path_, emitted_props = info[0]
-
- assertEquals(path_, path)
-
- assertEquals(cs.CHANNEL_TYPE_CONTACT_LIST, emitted_props[cs.CHANNEL_TYPE])
- assertEquals(ht, emitted_props[cs.TARGET_HANDLE_TYPE])
- assertEquals(handle, emitted_props[cs.TARGET_HANDLE])
-
- channel_props = chan.Properties.GetAll(cs.CHANNEL)
- assertEquals(handle, channel_props.get('TargetHandle'))
- assertEquals(ht, channel_props.get('TargetHandleType'))
- assertEquals(cs.CHANNEL_TYPE_CONTACT_LIST, channel_props.get('ChannelType'))
- assertContains(cs.CHANNEL_IFACE_GROUP, channel_props.get('Interfaces'))
- assertEquals(name, channel_props['TargetID'])
- assertEquals(False, channel_props['Requested'])
- assertEquals('', channel_props['InitiatorID'])
- assertEquals(0, channel_props['InitiatorHandle'])
-
- group_props = chan.Properties.GetAll(cs.CHANNEL_IFACE_GROUP)
- assertContains('HandleOwners', group_props)
- assertContains('Members', group_props)
- assertEquals(members, group_props['Members'])
- assertContains('LocalPendingMembers', group_props)
- actual_lp_handles = [x[0] for x in group_props['LocalPendingMembers']]
- assertEquals(sorted(lp_handles), sorted(actual_lp_handles))
- assertContains('RemotePendingMembers', group_props)
- assertEquals(sorted(rp_handles), sorted(group_props['RemotePendingMembers']))
- assertContains('GroupFlags', group_props)
-
- return chan
+
+ return True
+
+# function to pass as a 'BlockedContactsChanged' dbus-signal even predicate
+# checking if the @blocked and @unblocked contacts match those from the
+# signal
+def blocked_contacts_changed_predicate(e, blocked, unblocked):
+ b, u = e.args
+
+ return set(b.values()) == set(blocked) and set(u.values()) == set(unblocked)
+
+# function to pass as a 'GroupsCreated' dbus-signal even predicate
+# checking if the created @groups match those from the signal
+def groups_created_predicate(e, groups):
+ return set(e.args[0]) == set(groups)
+
+# function to pass as a 'GroupsChanged' dbus-signal even predicate
+# checking if @contacts have been added/removed to/from the @added/@removed
+# groups
+def groups_changed_predicate(e, conn, contacts, added, removed):
+ c, a, r = e.args
+ handles = conn.get_contact_handles_sync(contacts)
+
+ return set(handles) == set(c) and set(added) == set(a) and set(removed) == set(r)
diff --git a/tests/twisted/run-test.sh.in b/tests/twisted/run-test.sh.in
index e0b146c75..5392397a7 100644
--- a/tests/twisted/run-test.sh.in
+++ b/tests/twisted/run-test.sh.in
@@ -11,7 +11,7 @@ if test "x$GABBLE_TEST_UNINSTALLED" = x; then
test_build="@gabbletestsdir@"
config_file="@gabbletestsdir@/twisted/tools/servicedir/tmp-session-bus.conf"
- PYTHONPATH="@gabbletestsdir@/twisted"
+ PYTHONPATH="@gabbletestsdir@/twisted:@gabbletestsdir@/twisted/jingle"
export PYTHONPATH
GABBLE_TWISTED_PATH="@gabbletestsdir@/twisted"
@@ -31,6 +31,8 @@ else
config_file="${test_build}/twisted/tools/servicedir-uninstalled/tmp-session-bus.conf"
PYTHONPATH="${test_src}/twisted:${test_build}/twisted"
+ PYTHONPATH="$PYTHONPATH:${test_src}/twisted/jingle"
+ PYTHONPATH="$PYTHONPATH:${test_build}/twisted/jingle"
export PYTHONPATH
GABBLE_TWISTED_PATH="${test_src}/twisted"
@@ -51,19 +53,19 @@ for i in $list ; do
--config-file="${config_file}" \
-- \
@TEST_PYTHON@ -u "${test_src}/twisted/$i"
- e=$?
- case "$e" in
- (0)
- echo "PASS: $i"
- ;;
- (77)
- echo "SKIP: $i"
- ;;
- (*)
- any_failed=1
- echo "FAIL: $i ($e)"
- ;;
- esac
+ e=$?
+ case "$e" in
+ (0)
+ echo "PASS: $i"
+ ;;
+ (77)
+ echo "SKIP: $i"
+ ;;
+ (*)
+ any_failed=1
+ echo "FAIL: $i ($e)"
+ ;;
+ esac
done
exit $any_failed
diff --git a/tests/twisted/sasl/abort.py b/tests/twisted/sasl/abort.py
index 1cb03f311..9b00678fc 100644
--- a/tests/twisted/sasl/abort.py
+++ b/tests/twisted/sasl/abort.py
@@ -2,9 +2,7 @@
Test the server sasl aborting at different stages
"""
-import dbus
-
-from servicetest import EventPattern, assertEquals
+from servicetest import EventPattern
from gabbletest import exec_test, call_async
import constants as cs
from saslutil import SaslEventAuthenticator, connect_and_get_sasl_channel, \
diff --git a/tests/twisted/sasl/close.py b/tests/twisted/sasl/close.py
index b50a7aee7..079d8d048 100644
--- a/tests/twisted/sasl/close.py
+++ b/tests/twisted/sasl/close.py
@@ -1,7 +1,5 @@
"""Test the SASL channel being undispatchable."""
-import dbus
-
from servicetest import EventPattern
from gabbletest import exec_test
import constants as cs
diff --git a/tests/twisted/sasl/complex.py b/tests/twisted/sasl/complex.py
index c290cd83d..ac550db7d 100644
--- a/tests/twisted/sasl/complex.py
+++ b/tests/twisted/sasl/complex.py
@@ -3,7 +3,7 @@ Test the server sasl channel with the PLAIN mechanism
"""
import dbus
-from servicetest import EventPattern, assertEquals, assertSameSets, call_async
+from servicetest import EventPattern, assertSameSets, call_async
from gabbletest import exec_test
import constants as cs
from saslutil import SaslEventAuthenticator, connect_and_get_sasl_channel
@@ -108,7 +108,7 @@ def test_complex_success(q, bus, conn, stream, with_extra_data=True,
args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
chan.Close()
# ... and check that the Connection is still OK
- conn.GetSelfHandle()
+ conn.Properties.Get(cs.CONN, "SelfHandle")
def test_complex_success_data(q, bus, conn, stream):
test_complex_success(q, bus, conn, stream, True)
diff --git a/tests/twisted/sasl/jabber_auth.py b/tests/twisted/sasl/jabber_auth.py
index 6857f06a7..d4e47eae7 100644
--- a/tests/twisted/sasl/jabber_auth.py
+++ b/tests/twisted/sasl/jabber_auth.py
@@ -2,20 +2,14 @@
Test the server sasl channel with Jabber auth pseudomechanisms
"""
-from twisted.words.xish import domish
-from twisted.words.protocols.jabber import xmlstream
from twisted.words.protocols.jabber.client import IQ
-import hashlib
-
-import dbus
-
-from servicetest import (EventPattern, assertEquals, assertSameSets,
+from servicetest import (assertEquals, assertSameSets,
assertContains)
from gabbletest import exec_test, JabberXmlStream, JabberAuthenticator
import constants as cs
import ns
-from saslutil import expect_sasl_channel, abort_auth
+from saslutil import expect_sasl_channel
JID = "test@localhost"
PASSWORD = "pass"
diff --git a/tests/twisted/sasl/plain.py b/tests/twisted/sasl/plain.py
index 2a3a24eee..7bdd6ca3b 100644
--- a/tests/twisted/sasl/plain.py
+++ b/tests/twisted/sasl/plain.py
@@ -2,13 +2,6 @@
Test the server sasl channel with the PLAIN mechanism
"""
-from twisted.words.xish import domish
-from twisted.words.protocols.jabber import xmlstream
-
-from base64 import b64decode
-
-import dbus
-
from servicetest import EventPattern, assertEquals, assertContains, call_async
from gabbletest import exec_test
import constants as cs
diff --git a/tests/twisted/sasl/saslutil.py b/tests/twisted/sasl/saslutil.py
index 7d146146c..fcbd8f9e5 100644
--- a/tests/twisted/sasl/saslutil.py
+++ b/tests/twisted/sasl/saslutil.py
@@ -89,22 +89,14 @@ def connect_and_get_sasl_channel(q, bus, conn):
return expect_sasl_channel(q, bus, conn)
def expect_sasl_channel(q, bus, conn):
- old_signal, new_signal = q.expect_many(
- EventPattern('dbus-signal', signal='NewChannel',
- predicate=lambda e:
- e.args[1] == cs.CHANNEL_TYPE_SERVER_AUTHENTICATION),
- EventPattern('dbus-signal', signal='NewChannels',
- predicate=lambda e:
- e.args[0][0][1].get(cs.CHANNEL_TYPE) ==
- cs.CHANNEL_TYPE_SERVER_AUTHENTICATION),
- )
-
- path, type, handle_type, handle, suppress_handler = old_signal.args
+ new_signal = q.expect('dbus-signal', signal='NewChannels',
+ predicate=lambda e: e.args[0][0][1].get(cs.CHANNEL_TYPE) ==
+ cs.CHANNEL_TYPE_SERVER_AUTHENTICATION)
+
+ path, props = new_signal.args[0][0]
chan = SaslChannelWrapper(bus.get_object(conn.bus_name, path))
assertLength(1, new_signal.args[0])
- assertEquals(path, new_signal.args[0][0][0])
- props = new_signal.args[0][0][1]
assertEquals(cs.CHANNEL_IFACE_SASL_AUTH, props.get(cs.AUTH_METHOD))
return chan, props
diff --git a/tests/twisted/sasl/telepathy-password.py b/tests/twisted/sasl/telepathy-password.py
index 533dae7ef..65a3cd48f 100644
--- a/tests/twisted/sasl/telepathy-password.py
+++ b/tests/twisted/sasl/telepathy-password.py
@@ -42,7 +42,7 @@ def test_close_straight_after_accept(q, bus, conn, stream):
interface=cs.CHANNEL_IFACE_SASL_AUTH,
args=[cs.SASL_STATUS_SUCCEEDED, '', {}])
- e = q.expect('dbus-signal', signal='StatusChanged',
+ q.expect('dbus-signal', signal='StatusChanged',
args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
if __name__ == '__main__':
diff --git a/tests/twisted/servicetest.py b/tests/twisted/servicetest.py
index 31c00f476..885bfe205 100644
--- a/tests/twisted/servicetest.py
+++ b/tests/twisted/servicetest.py
@@ -1,6 +1,23 @@
+# Copyright (C) 2009 Nokia Corporation
+# Copyright (C) 2009-2013 Collabora Ltd.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+# 02110-1301 USA
"""
-Infrastructure code for testing connection managers.
+Infrastructure code for testing Telepathy services.
"""
from twisted.internet import glib2reactor
@@ -13,14 +30,17 @@ import os
import pprint
import unittest
-import dbus.glib
+import dbus
+import dbus.lowlevel
+from dbus.mainloop.glib import DBusGMainLoop
+DBusGMainLoop(set_as_default=True)
from twisted.internet import reactor
import constants as cs
-tp_name_prefix = 'org.freedesktop.Telepathy'
-tp_path_prefix = '/org/freedesktop/Telepathy'
+tp_name_prefix = cs.PREFIX
+tp_path_prefix = cs.PATH_PREFIX
class DictionarySupersetOf (object):
"""Utility class for expecting "a dictionary with at least these keys"."""
@@ -177,7 +197,14 @@ class BaseEventQueue:
t = time.time()
while True:
- event = self.wait([pattern.subqueue])
+ try:
+ event = self.wait([pattern.subqueue])
+ except TimeoutError:
+ self.log('timeout')
+ self.log('still expecting:')
+ self.log(' - %r' % pattern)
+ raise
+
self._check_forbidden(event)
if pattern.match(event):
@@ -289,6 +316,11 @@ class IteratingEventQueue(BaseEventQueue):
def __init__(self, timeout=None):
BaseEventQueue.__init__(self, timeout)
+ self._dbus_method_impls = []
+ self._buses = []
+ # a message filter which will claim we handled everything
+ self._dbus_dev_null = \
+ lambda bus, message: dbus.lowlevel.HANDLER_RESULT_HANDLED
def wait(self, queues=None):
stop = [False]
@@ -313,6 +345,127 @@ class IteratingEventQueue(BaseEventQueue):
else:
raise TimeoutError
+ def add_dbus_method_impl(self, cb, bus=None, **kwargs):
+ if bus is None:
+ bus = self._buses[0]
+
+ self._dbus_method_impls.append(
+ (EventPattern('dbus-method-call', **kwargs), cb))
+
+ def dbus_emit(self, path, iface, name, *a, **k):
+ bus = k.pop('bus', self._buses[0])
+ assert 'signature' in k, k
+ message = dbus.lowlevel.SignalMessage(path, iface, name)
+ message.append(*a, **k)
+ bus.send_message(message)
+
+ def dbus_return(self, in_reply_to, *a, **k):
+ bus = k.pop('bus', self._buses[0])
+ assert 'signature' in k, k
+ reply = dbus.lowlevel.MethodReturnMessage(in_reply_to)
+ reply.append(*a, **k)
+ bus.send_message(reply)
+
+ def dbus_raise(self, in_reply_to, name, message=None, bus=None):
+ if bus is None:
+ bus = self._buses[0]
+
+ reply = dbus.lowlevel.ErrorMessage(in_reply_to, name, message)
+ bus.send_message(reply)
+
+ def attach_to_bus(self, bus):
+ if not self._buses:
+ # first-time setup
+ self._dbus_filter_bound_method = self._dbus_filter
+
+ self._buses.append(bus)
+
+ # Only subscribe to messages on the first bus connection (assumed to
+ # be the shared session bus connection used by the simulated connection
+ # manager and most of the test suite), not on subsequent bus
+ # connections (assumed to represent extra clients).
+ #
+ # When we receive a method call on the other bus connections, ignore
+ # it - the eavesdropping filter installed on the first bus connection
+ # will see it too.
+ #
+ # This is highly counter-intuitive, but it means our messages are in
+ # a guaranteed order (we don't have races between messages arriving on
+ # various connections).
+ if len(self._buses) > 1:
+ bus.add_message_filter(self._dbus_dev_null)
+ return
+
+ try:
+ # for dbus > 1.5
+ bus.add_match_string("eavesdrop=true,type='signal'")
+ except dbus.DBusException:
+ bus.add_match_string("type='signal'")
+ bus.add_match_string("type='method_call'")
+ else:
+ bus.add_match_string("eavesdrop=true,type='method_call'")
+
+ bus.add_message_filter(self._dbus_filter_bound_method)
+
+ bus.add_signal_receiver(
+ lambda *args, **kw:
+ self.append(
+ Event('dbus-signal',
+ path=unwrap(kw['path']),
+ signal=kw['member'],
+ args=map(unwrap, args),
+ interface=kw['interface'])),
+ None,
+ None,
+ None,
+ path_keyword='path',
+ member_keyword='member',
+ interface_keyword='interface',
+ byte_arrays=True,
+ )
+
+ def cleanup(self):
+ if self._buses:
+ self._buses[0].remove_message_filter(self._dbus_filter_bound_method)
+ for bus in self._buses[1:]:
+ bus.remove_message_filter(self._dbus_dev_null)
+
+ self._buses = []
+ self._dbus_method_impls = []
+
+ def _dbus_filter(self, bus, message):
+ if isinstance(message, dbus.lowlevel.MethodCallMessage):
+
+ destination = message.get_destination()
+ sender = message.get_sender()
+
+ if (destination == 'org.freedesktop.DBus' or
+ sender == self._buses[0].get_unique_name()):
+ # suppress reply and don't make an Event
+ return dbus.lowlevel.HANDLER_RESULT_HANDLED
+
+ e = Event('dbus-method-call', message=message,
+ interface=message.get_interface(), path=message.get_path(),
+ raw_args=message.get_args_list(byte_arrays=True),
+ args=map(unwrap, message.get_args_list(byte_arrays=True)),
+ destination=str(destination),
+ method=message.get_member(),
+ sender=message.get_sender(),
+ handled=False)
+
+ for pair in self._dbus_method_impls:
+ pattern, cb = pair
+ if pattern.match(e):
+ cb(e)
+ e.handled = True
+ break
+
+ self.append(e)
+
+ return dbus.lowlevel.HANDLER_RESULT_HANDLED
+
+ return dbus.lowlevel.HANDLER_RESULT_NOT_YET_HANDLED
+
class TestEventQueue(BaseEventQueue):
def __init__(self, events):
BaseEventQueue.__init__(self)
@@ -423,17 +576,13 @@ def call_async(test, proxy, method, *args, **kw):
kw.update({'reply_handler': reply_func, 'error_handler': error_func})
method_proxy(*args, **kw)
-def sync_dbus(bus, q, conn):
+def sync_dbus(bus, q, proxy):
# Dummy D-Bus method call. We can't use DBus.Peer.Ping() because libdbus
# replies to that message immediately, rather than handing it up to
- # dbus-glib and thence Gabble, which means that Ping()ing Gabble doesn't
- # ensure that it's processed all D-Bus messages prior to our ping.
- #
- # This won't do the right thing unless the proxy has a unique name.
- assert conn.object.bus_name.startswith(':')
- root_object = bus.get_object(conn.object.bus_name, '/', introspect=False)
- call_async(q,
- dbus.Interface(root_object, 'org.freedesktop.Telepathy.Tests'),
+ # dbus-glib and thence the application, which means that Ping()ing the
+ # application doesn't ensure that it's processed all D-Bus messages prior
+ # to our ping.
+ call_async(q, dbus.Interface(proxy, 'org.freedesktop.Telepathy.Tests'),
'DummySyncDBus')
q.expect('dbus-error', method='DummySyncDBus')
@@ -457,8 +606,25 @@ class ProxyWrapper:
return getattr(self.default_interface, name)
+class ConnWrapper(ProxyWrapper):
+ def inspect_contact_sync(self, handle):
+ return self.inspect_contacts_sync([handle])[0]
+
+ def inspect_contacts_sync(self, handles):
+ h2asv = self.Contacts.GetContactAttributes(handles, [], True)
+ ret = []
+ for h in handles:
+ ret.append(h2asv[h][cs.ATTR_CONTACT_ID])
+ return ret
+
+ def get_contact_handle_sync(self, identifier):
+ return self.Contacts.GetContactByID(identifier, [])[0]
+
+ def get_contact_handles_sync(self, ids):
+ return [self.get_contact_handle_sync(i) for i in ids]
+
def wrap_connection(conn):
- return ProxyWrapper(conn, tp_name_prefix + '.Connection',
+ return ConnWrapper(conn, tp_name_prefix + '.Connection',
dict([
(name, tp_name_prefix + '.Connection.Interface.' + name)
for name in ['Aliasing', 'Avatars', 'Capabilities', 'Contacts',
@@ -471,14 +637,32 @@ def wrap_connection(conn):
('MailNotification', cs.CONN_IFACE_MAIL_NOTIFICATION),
('ContactList', cs.CONN_IFACE_CONTACT_LIST),
('ContactGroups', cs.CONN_IFACE_CONTACT_GROUPS),
+ ('ContactBlocking', cs.CONN_IFACE_CONTACT_BLOCKING),
('PowerSaving', cs.CONN_IFACE_POWER_SAVING),
('Addressing', cs.CONN_IFACE_ADDRESSING),
+ ('ClientTypes', cs.CONN_IFACE_CLIENT_TYPES),
]))
+class ChannelWrapper(ProxyWrapper):
+ def send_msg_sync(self, txt):
+ message = [
+ { 'message-type': cs.MT_NORMAL, },
+ { 'content-type': 'text/plain',
+ 'content': txt
+ }]
+ self.Messages.SendMessage(message, 0)
+
def wrap_channel(chan, type_, extra=None):
interfaces = {
type_: tp_name_prefix + '.Channel.Type.' + type_,
- 'Group': tp_name_prefix + '.Channel.Interface.Group',
+ 'Channel': cs.CHANNEL,
+ 'Group': cs.CHANNEL_IFACE_GROUP,
+ 'Hold': cs.CHANNEL_IFACE_HOLD,
+ 'Messages': cs.CHANNEL_IFACE_MESSAGES,
+ 'RoomConfig1': cs.CHANNEL_IFACE_ROOM_CONFIG,
+ 'ChatState': cs.CHANNEL_IFACE_CHAT_STATE,
+ 'Destroyable': cs.CHANNEL_IFACE_DESTROYABLE,
+ 'Password': cs.CHANNEL_IFACE_PASSWORD,
}
if extra:
@@ -486,11 +670,14 @@ def wrap_channel(chan, type_, extra=None):
(name, tp_name_prefix + '.Channel.Interface.' + name)
for name in extra]))
- return ProxyWrapper(chan, tp_name_prefix + '.Channel', interfaces)
+ return ChannelWrapper(chan, tp_name_prefix + '.Channel', interfaces)
def wrap_content(chan, extra=None):
- interfaces = { }
+ interfaces = {
+ 'DTMF': cs.CALL_CONTENT_IFACE_DTMF,
+ 'Media': cs.CALL_CONTENT_IFACE_MEDIA,
+ }
if extra:
interfaces.update(dict([
diff --git a/tests/twisted/sidecar-own-caps.py b/tests/twisted/sidecar-own-caps.py
index 3cbed76fb..b02510b72 100644
--- a/tests/twisted/sidecar-own-caps.py
+++ b/tests/twisted/sidecar-own-caps.py
@@ -5,14 +5,14 @@ Test Gabble's implementation of sidecars own caps, using the test plugin.
from twisted.words.protocols.jabber.client import IQ
from twisted.words.xish import xpath
-from servicetest import call_async, EventPattern, assertEquals, assertContains
+from servicetest import call_async, EventPattern, assertEquals
from gabbletest import exec_test, acknowledge_iq
from caps_helper import compute_caps_hash
import constants as cs
import ns
from config import PLUGINS_ENABLED
-TEST_PLUGIN_IFACE = "org.freedesktop.Telepathy.Gabble.Plugin.Test"
+TEST_PLUGIN_IFACE = cs.PREFIX + ".Gabble.Plugin.Test"
if not PLUGINS_ENABLED:
print "NOTE: built without --enable-plugins, skipping"
@@ -35,7 +35,6 @@ def test(q, bus, conn, stream):
ver = compute_caps_hash(identities, features, {})
iq = IQ(stream, "get")
- id = iq['id']
query = iq.addElement((ns.DISCO_INFO, 'query'))
query['node'] = ns.GABBLE_CAPS + '#' + ver
stream.send(iq)
diff --git a/tests/twisted/sidecars.py b/tests/twisted/sidecars.py
index caeed8dda..61b863dee 100644
--- a/tests/twisted/sidecars.py
+++ b/tests/twisted/sidecars.py
@@ -9,7 +9,7 @@ from gabbletest import exec_test, send_error_reply, acknowledge_iq, sync_stream
import constants as cs
from config import PLUGINS_ENABLED
-TEST_PLUGIN_IFACE = "org.freedesktop.Telepathy.Gabble.Plugin.Test"
+TEST_PLUGIN_IFACE = cs.PREFIX + ".Gabble.Plugin.Test"
if not PLUGINS_ENABLED:
print "NOTE: built without --enable-plugins, not testing plugins"
diff --git a/tests/twisted/test-debug.py b/tests/twisted/test-debug.py
index d9c18183e..d3662a536 100644
--- a/tests/twisted/test-debug.py
+++ b/tests/twisted/test-debug.py
@@ -3,15 +3,11 @@
Test the debug message interface.
"""
-import dbus
-
from servicetest import assertEquals, sync_dbus, call_async, ProxyWrapper
from servicetest import EventPattern
from gabbletest import exec_test
import constants as cs
from config import DEBUGGING
-path = '/org/freedesktop/Telepathy/debug'
-iface = 'org.freedesktop.Telepathy.Debug'
def test(q, bus, conn, stream):
messages = []
@@ -19,7 +15,8 @@ def test(q, bus, conn, stream):
def new_message(timestamp, domain, level, string):
messages.append((timestamp, domain, level, string))
- debug = ProxyWrapper(bus.get_object(conn.bus_name, path), iface)
+ debug = ProxyWrapper(bus.get_object(conn.bus_name, cs.DEBUG_PATH),
+ cs.DEBUG_IFACE)
debug.connect_to_signal('NewDebugMessage', new_message)
if not DEBUGGING:
@@ -34,20 +31,21 @@ def test(q, bus, conn, stream):
# Turn signalling on and generate some messages.
assert len(messages) == 0
- assert debug.Properties.Get(iface, 'Enabled') == False
- debug.Properties.Set(iface, 'Enabled', True)
+ assert debug.Properties.Get(cs.DEBUG_IFACE, 'Enabled') == False
+ debug.Properties.Set(cs.DEBUG_IFACE, 'Enabled', True)
- channel_path = conn.RequestChannel(
- cs.CHANNEL_TYPE_TEXT, cs.HT_CONTACT, conn.GetSelfHandle(), True)
- q.expect_many(
- EventPattern ('dbus-signal', signal='NewChannel'),
- EventPattern ('dbus-signal', signal = 'NewDebugMessage'))
+ channel_path, props = conn.Requests.CreateChannel({
+ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
+ cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
+ cs.TARGET_HANDLE: conn.Properties.Get(cs.CONN, "SelfHandle")
+ })
+ q.expect('dbus-signal', signal = 'NewDebugMessage')
assert len(messages) > 0
# Turn signalling off and check we don't get any more messages.
- debug.Properties.Set(iface, 'Enabled', False)
+ debug.Properties.Set(cs.DEBUG_IFACE, 'Enabled', False)
sync_dbus(bus, q, conn)
snapshot = list(messages)
@@ -55,9 +53,12 @@ def test(q, bus, conn, stream):
channel.Close(dbus_interface=cs.CHANNEL)
q.expect('dbus-signal', signal='Closed')
- conn.RequestChannel(
- cs.CHANNEL_TYPE_TEXT, cs.HT_CONTACT, conn.GetSelfHandle(), True)
- q.expect('dbus-signal', signal='NewChannel')
+ channel_path, props = conn.Requests.CreateChannel({
+ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
+ cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
+ cs.TARGET_HANDLE: conn.Properties.Get(cs.CONN, "SelfHandle")
+ })
+ q.expect('dbus-signal', signal='NewChannels')
assertEquals (snapshot, messages)
diff --git a/tests/twisted/test-fallback-socks5-proxy.py b/tests/twisted/test-fallback-socks5-proxy.py
index d6ae78cb0..275352d43 100644
--- a/tests/twisted/test-fallback-socks5-proxy.py
+++ b/tests/twisted/test-fallback-socks5-proxy.py
@@ -2,7 +2,7 @@
import socket
from gabbletest import (
- exec_test, elem, elem_iq, sync_stream, make_presence, send_error_reply,
+ exec_test, elem, elem_iq, make_presence, send_error_reply,
make_result_iq, sync_stream)
from servicetest import (
EventPattern, call_async, assertEquals, assertLength,
diff --git a/tests/twisted/test-location.py b/tests/twisted/test-location.py
index cb1817321..2a29700ab 100644
--- a/tests/twisted/test-location.py
+++ b/tests/twisted/test-location.py
@@ -17,6 +17,10 @@ import ns
Rich_Presence_Access_Control_Type_Publish_List = 1
+def get_location(conn, contact):
+ h2asv = conn.Contacts.GetContactAttributes([contact], [cs.CONN_IFACE_LOCATION], False)
+ return h2asv[contact].get(cs.ATTR_LOCATION)
+
def test(q, bus, conn, stream):
# we don't yet know we have PEP
assertEquals(0, conn.Get(cs.CONN_IFACE_LOCATION,
@@ -158,8 +162,7 @@ def test(q, bus, conn, stream):
q.expect('dbus-error', method='SetLocation')
# Request Bob's location
- bob_handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
- call_async(q, conn.Location, 'GetLocations', [bob_handle])
+ bob_handle = conn.get_contact_handle_sync('bob@foo.com')
# Gabble should not send a pubsub query. The point of PEP is that we don't
# have to do this.
@@ -167,11 +170,9 @@ def test(q, bus, conn, stream):
query_ns=ns.PUBSUB)
q.forbid_events([ pubsub_get_pattern ])
- # GetLocations returns immediately.
- get_locations = q.expect('dbus-return', method='GetLocations')
- locations = get_locations.value[0]
+ location = get_location(conn, bob_handle)
# Location isn't known yet
- assertLength(0, locations)
+ assertEquals(None, location)
# Sync the XMPP stream to ensure Gabble hasn't sent a query.
sync_stream(q, stream)
@@ -210,11 +211,10 @@ def test(q, bus, conn, stream):
assertEquals(location['timestamp'], date)
# Get location again; Gabble should return the cached location
- locations = conn.Location.GetLocations([bob_handle])
- assertLength(1, locations)
- assertEquals(locations[bob_handle], location)
+ loc = get_location(conn, bob_handle)
+ assertEquals(loc, location)
- charles_handle = conn.RequestHandles(cs.HT_CONTACT, ['charles@foo.com'])[0]
+ charles_handle = conn.get_contact_handle_sync('charles@foo.com')
# check that Contacts interface supports location
attributes = conn.Contacts.GetContactAttributes(
diff --git a/tests/twisted/text/destroy.py b/tests/twisted/text/destroy.py
index f51a4c29c..0504d1d32 100644
--- a/tests/twisted/text/destroy.py
+++ b/tests/twisted/text/destroy.py
@@ -8,38 +8,29 @@ import dbus
from twisted.words.xish import domish
from gabbletest import exec_test
-from servicetest import call_async, EventPattern
+from servicetest import call_async, EventPattern, wrap_channel, assertEquals
import constants as cs
def test(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
jid = 'foo@bar.com'
- call_async(q, conn, 'RequestHandles', 1, [jid])
+ foo_handle = conn.get_contact_handle_sync(jid)
- event = q.expect('dbus-return', method='RequestHandles')
- foo_handle = event.value[0][0]
+ call_async(q, conn.Requests, 'CreateChannel', {
+ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
+ cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
+ cs.TARGET_HANDLE: foo_handle })
- call_async(q, conn, 'RequestChannel',
- cs.CHANNEL_TYPE_TEXT, cs.HT_CONTACT, foo_handle, True)
-
- ret, old_sig, new_sig = q.expect_many(
- EventPattern('dbus-return', method='RequestChannel'),
- EventPattern('dbus-signal', signal='NewChannel'),
+ ret, new_sig = q.expect_many(
+ EventPattern('dbus-return', method='CreateChannel'),
EventPattern('dbus-signal', signal='NewChannels'),
)
- text_chan = bus.get_object(conn.bus_name, ret.value[0])
+ text_chan = wrap_channel(bus.get_object(conn.bus_name, ret.value[0]), 'Text')
chan_iface = dbus.Interface(text_chan, cs.CHANNEL)
- text_iface = dbus.Interface(text_chan, cs.CHANNEL_TYPE_TEXT)
destroyable_iface = dbus.Interface(text_chan, cs.CHANNEL_IFACE_DESTROYABLE)
- assert old_sig.args[0] == ret.value[0]
- assert old_sig.args[1] == cs.CHANNEL_TYPE_TEXT
- assert old_sig.args[2] == cs.HT_CONTACT
- assert old_sig.args[3] == foo_handle
- assert old_sig.args[4] == True # suppress handler
-
assert len(new_sig.args) == 1
assert len(new_sig.args[0]) == 1 # one channel
assert len(new_sig.args[0][0]) == 2 # two struct members
@@ -62,7 +53,7 @@ def test(q, bus, conn, stream):
assert channel_props['InitiatorID'] == 'test@localhost',\
channel_props['InitiatorID']
- text_iface.Send(0, 'hey')
+ text_chan.send_msg_sync('hey')
event = q.expect('stream-message')
@@ -80,23 +71,14 @@ def test(q, bus, conn, stream):
m.addElement('body', content='hello')
stream.send(m)
- event = q.expect('dbus-signal', signal='Received')
-
- hello_message_id = event.args[0]
- hello_message_time = event.args[1]
- assert event.args[2] == foo_handle
- # message type: normal
- assert event.args[3] == 0
- # flags: none
- assert event.args[4] == 0
- # body
- assert event.args[5] == 'hello'
-
- messages = text_chan.ListPendingMessages(False,
- dbus_interface=cs.CHANNEL_TYPE_TEXT)
- assert messages == \
- [(hello_message_id, hello_message_time, foo_handle,
- 0, 0, 'hello')], messages
+ event = q.expect('dbus-signal', signal='MessageReceived')
+
+ msg = event.args[0]
+ assertEquals(foo_handle, msg[0]['message-sender'])
+ assertEquals('hello', msg[1]['content'])
+
+ messages = text_chan.Properties.Get(cs.CHANNEL_IFACE_MESSAGES, 'PendingMessages')
+ assertEquals([msg], messages)
# destroy the channel without acking the message; it does not come back
diff --git a/tests/twisted/text/ensure.py b/tests/twisted/text/ensure.py
index e29906ebc..fcef90a69 100644
--- a/tests/twisted/text/ensure.py
+++ b/tests/twisted/text/ensure.py
@@ -9,13 +9,10 @@ from servicetest import call_async, EventPattern
import constants as cs
def test(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
jids = ['foo@bar.com', 'truc@cafe.fr']
- call_async(q, conn, 'RequestHandles', 1, jids)
-
- event = q.expect('dbus-return', method='RequestHandles')
- handles = event.value[0]
+ handles = conn.get_contact_handles_sync(jids)
properties = conn.GetAll(
cs.CONN_IFACE_REQUESTS, dbus_interface=cs.PROPERTIES_IFACE)
@@ -39,9 +36,8 @@ def test_ensure_ensure(q, conn, self_handle, jid, handle):
# Check that Ensuring a channel that doesn't exist succeeds
call_async(q, conn.Requests, 'EnsureChannel', request_props (handle))
- ret, old_sig, new_sig = q.expect_many(
+ ret, new_sig = q.expect_many(
EventPattern('dbus-return', method='EnsureChannel'),
- EventPattern('dbus-signal', signal='NewChannel'),
EventPattern('dbus-signal', signal='NewChannels'),
)
@@ -54,15 +50,6 @@ def test_ensure_ensure(q, conn, self_handle, jid, handle):
check_props(emitted_props, self_handle, handle, jid)
- assert len(old_sig.args) == 5
- old_path, old_ct, old_ht, old_h, old_sh = old_sig.args
-
- assert old_path == path
- assert old_ct == cs.CHANNEL_TYPE_TEXT
- assert old_ht == cs.HT_CONTACT
- assert old_h == handle
- assert old_sh == True # suppress handler
-
assert len(new_sig.args) == 1
assert len(new_sig.args[0]) == 1 # one channel
assert len(new_sig.args[0][0]) == 2 # two struct members
@@ -98,9 +85,8 @@ def test_request_ensure(q, conn, self_handle, jid, handle):
call_async(q, conn.Requests, 'CreateChannel', request_props(handle))
- ret, old_sig, new_sig = q.expect_many(
+ ret, new_sig = q.expect_many(
EventPattern('dbus-return', method='CreateChannel'),
- EventPattern('dbus-signal', signal='NewChannel'),
EventPattern('dbus-signal', signal='NewChannels'),
)
@@ -109,15 +95,6 @@ def test_request_ensure(q, conn, self_handle, jid, handle):
check_props(emitted_props, self_handle, handle, jid)
- assert len(old_sig.args) == 5
- old_path, old_ct, old_ht, old_h, old_sh = old_sig.args
-
- assert old_path == path
- assert old_ct == cs.CHANNEL_TYPE_TEXT
- assert old_ht == cs.HT_CONTACT
- assert old_h == handle
- assert old_sh == True # suppress handler
-
assert len(new_sig.args) == 1
assert len(new_sig.args[0]) == 1 # one channel
assert len(new_sig.args[0][0]) == 2 # two struct members
diff --git a/tests/twisted/text/facebook-own-message.py b/tests/twisted/text/facebook-own-message.py
index a695b3d92..5aaa14359 100644
--- a/tests/twisted/text/facebook-own-message.py
+++ b/tests/twisted/text/facebook-own-message.py
@@ -51,7 +51,7 @@ def test(q, bus, conn, stream):
echo = header['delivery-echo']
echo_header, echo_body = echo
- assertEquals(conn.GetSelfHandle(), echo_header['message-sender'])
+ assertEquals(conn.Properties.Get(cs.CONN, "SelfHandle"), echo_header['message-sender'])
assertEquals('text/plain', echo_body['content-type'])
assertEquals(text, echo_body['content'])
diff --git a/tests/twisted/text/initiate-requestotron.py b/tests/twisted/text/initiate-requestotron.py
index 9bd2b0ab1..c969eaac1 100644
--- a/tests/twisted/text/initiate-requestotron.py
+++ b/tests/twisted/text/initiate-requestotron.py
@@ -10,10 +10,10 @@ from servicetest import (call_async, EventPattern, assertContains,
import constants as cs
def test(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
jid = 'foo@bar.com'
- foo_handle = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ foo_handle = conn.get_contact_handle_sync(jid)
properties = conn.GetAll(
cs.CONN_IFACE_REQUESTS, dbus_interface=dbus.PROPERTIES_IFACE)
@@ -31,9 +31,8 @@ def test(q, bus, conn, stream):
cs.TARGET_HANDLE: foo_handle,
})
- ret, old_sig, new_sig = q.expect_many(
+ ret, new_sig = q.expect_many(
EventPattern('dbus-return', method='CreateChannel'),
- EventPattern('dbus-signal', signal='NewChannel'),
EventPattern('dbus-signal', signal='NewChannels'),
)
@@ -51,12 +50,6 @@ def test(q, bus, conn, stream):
assertEquals(cs.DELIVERY_REPORTING_SUPPORT_FLAGS_RECEIVE_FAILURES,
emitted_props[cs.DELIVERY_REPORTING_SUPPORT])
- assert old_sig.args[0] == ret.value[0]
- assert old_sig.args[1] == cs.CHANNEL_TYPE_TEXT
- assert old_sig.args[2] == cs.HT_CONTACT
- assert old_sig.args[3] == foo_handle
- assert old_sig.args[4] == True # suppress handler
-
assert len(new_sig.args) == 1
assert len(new_sig.args[0]) == 1 # one channel
assert len(new_sig.args[0][0]) == 2 # two struct members
diff --git a/tests/twisted/text/initiate.py b/tests/twisted/text/initiate.py
index edf493c1a..778dd6a58 100644
--- a/tests/twisted/text/initiate.py
+++ b/tests/twisted/text/initiate.py
@@ -7,35 +7,33 @@ import dbus
from twisted.words.xish import domish
from gabbletest import exec_test
-from servicetest import call_async, EventPattern
+from servicetest import call_async, EventPattern, assertEquals, wrap_channel
import constants as cs
def test(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
jid = 'foo@bar.com'
- call_async(q, conn, 'RequestHandles', cs.HT_CONTACT, [jid])
+ foo_handle = conn.get_contact_handle_sync(jid)
- event = q.expect('dbus-return', method='RequestHandles')
- foo_handle = event.value[0][0]
-
- call_async(q, conn, 'RequestChannel',
- cs.CHANNEL_TYPE_TEXT, cs.HT_CONTACT, foo_handle, True)
+ call_async(q, conn.Requests, 'CreateChannel', {
+ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
+ cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
+ cs.TARGET_HANDLE: foo_handle })
ret, sig = q.expect_many(
- EventPattern('dbus-return', method='RequestChannel'),
- EventPattern('dbus-signal', signal='NewChannel'),
+ EventPattern('dbus-return', method='CreateChannel'),
+ EventPattern('dbus-signal', signal='NewChannels'),
)
- text_chan = bus.get_object(conn.bus_name, ret.value[0])
+ text_chan = wrap_channel(bus.get_object(conn.bus_name, ret.value[0]), 'Text')
- assert sig.args[0] == ret.value[0], \
- (sig.args[0], ret.value[0])
- assert sig.args[1] == cs.CHANNEL_TYPE_TEXT, sig.args[1]
+ path, props = sig.args[0][0]
+ assertEquals(ret.value[0], path)
+ assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE])
# check that handle type == contact handle
- assert sig.args[2] == 1, sig.args[1]
- assert sig.args[3] == foo_handle, (sig.args[3], foo_handle)
- assert sig.args[4] == True # suppress handler
+ assertEquals(cs.HT_CONTACT, props[cs.TARGET_HANDLE_TYPE])
+ assertEquals(foo_handle, props[cs.TARGET_HANDLE])
# Exercise basic Channel Properties from spec 0.17.7
channel_props = text_chan.GetAll(
@@ -58,7 +56,7 @@ def test(q, bus, conn, stream):
assert channel_props['InitiatorID'] == 'test@localhost',\
channel_props['InitiatorID']
- dbus.Interface(text_chan, cs.CHANNEL_TYPE_TEXT).Send(0, 'hey')
+ text_chan.send_msg_sync('hey')
event = q.expect('stream-message')
@@ -76,14 +74,10 @@ def test(q, bus, conn, stream):
m.addElement('body', content='hello')
stream.send(m)
- event = q.expect('dbus-signal', signal='Received')
+ event = q.expect('dbus-signal', signal='MessageReceived')
- # message type: normal
- assert event.args[3] == 0
- # flags: none
- assert event.args[4] == 0
- # body
- assert event.args[5] == 'hello'
+ msg = event.args[0]
+ assertEquals('hello', msg[1]['content'])
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/text/receipts.py b/tests/twisted/text/receipts.py
index 45c7d9f89..2c11af2e3 100644
--- a/tests/twisted/text/receipts.py
+++ b/tests/twisted/text/receipts.py
@@ -172,8 +172,7 @@ def test(q, bus, conn, stream):
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
cs.TARGET_ID: GUYBRUSH,
})[0]
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text',
- ['Messages'])
+ chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
# Let's start out with an empty roster, eh?
e = q.expect('stream-iq', iq_type='get', query_ns=ns.ROSTER)
diff --git a/tests/twisted/text/respawn.py b/tests/twisted/text/respawn.py
index 0ba43571f..bb1b75495 100644
--- a/tests/twisted/text/respawn.py
+++ b/tests/twisted/text/respawn.py
@@ -7,33 +7,27 @@ import dbus
from twisted.words.xish import domish
from gabbletest import exec_test
-from servicetest import call_async, EventPattern, assertEquals
+from servicetest import call_async, EventPattern, assertEquals, wrap_channel
import constants as cs
def test(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
jid = 'foo@bar.com'
- foo_handle = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ foo_handle = conn.get_contact_handle_sync(jid)
- call_async(q, conn, 'RequestChannel',
- cs.CHANNEL_TYPE_TEXT, cs.HT_CONTACT, foo_handle, True)
+ call_async(q, conn.Requests, 'CreateChannel', {
+ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
+ cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
+ cs.TARGET_HANDLE: foo_handle })
- ret, old_sig, new_sig = q.expect_many(
- EventPattern('dbus-return', method='RequestChannel'),
- EventPattern('dbus-signal', signal='NewChannel'),
+ ret, new_sig = q.expect_many(
+ EventPattern('dbus-return', method='CreateChannel'),
EventPattern('dbus-signal', signal='NewChannels'),
)
- text_chan = bus.get_object(conn.bus_name, ret.value[0])
+ text_chan = wrap_channel(bus.get_object(conn.bus_name, ret.value[0]), 'Text')
chan_iface = dbus.Interface(text_chan, cs.CHANNEL)
- text_iface = dbus.Interface(text_chan, cs.CHANNEL_TYPE_TEXT)
-
- assert old_sig.args[0] == ret.value[0]
- assert old_sig.args[1] == cs.CHANNEL_TYPE_TEXT
- assert old_sig.args[2] == cs.HT_CONTACT
- assert old_sig.args[3] == foo_handle
- assert old_sig.args[4] == True # suppress handler
assert len(new_sig.args) == 1
assert len(new_sig.args[0]) == 1 # one channel
@@ -58,7 +52,7 @@ def test(q, bus, conn, stream):
assert channel_props['InitiatorID'] == 'test@localhost',\
channel_props['InitiatorID']
- text_iface.Send(0, 'hey')
+ text_chan.send_msg_sync('hey')
event = q.expect('stream-message')
@@ -76,23 +70,14 @@ def test(q, bus, conn, stream):
m.addElement('body', content='hello')
stream.send(m)
- event = q.expect('dbus-signal', signal='Received')
+ event = q.expect('dbus-signal', signal='MessageReceived')
- hello_message_id = event.args[0]
- hello_message_time = event.args[1]
- assert event.args[2] == foo_handle
- # message type: normal
- assert event.args[3] == 0
- # flags: none
- assert event.args[4] == 0
- # body
- assert event.args[5] == 'hello'
+ msg = event.args[0]
+ assertEquals(foo_handle, msg[0]['message-sender'])
+ assertEquals('hello', msg[1]['content'])
- messages = text_chan.ListPendingMessages(False,
- dbus_interface=cs.CHANNEL_TYPE_TEXT)
- assert messages == \
- [(hello_message_id, hello_message_time, foo_handle,
- 0, 0, 'hello')], messages
+ messages = text_chan.Properties.Get(cs.CHANNEL_IFACE_MESSAGES, 'PendingMessages')
+ assertEquals([msg], messages)
# close the channel without acking the message; it comes back
@@ -107,12 +92,12 @@ def test(q, bus, conn, stream):
assert new.args[0] == text_chan.object_path,\
(new.args[0], text_chan.object_path)
- event = q.expect('dbus-signal', signal='NewChannel')
- assert event.args[0] == text_chan.object_path
- assert event.args[1] == cs.CHANNEL_TYPE_TEXT
- assert event.args[2] == cs.HT_CONTACT
- assert event.args[3] == foo_handle
- assert event.args[4] == False # suppress handler
+ event = q.expect('dbus-signal', signal='NewChannels')
+ path, props = event.args[0][0]
+ assertEquals(text_chan.object_path, path)
+ assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE])
+ assertEquals(cs.HT_CONTACT, props[cs.TARGET_HANDLE_TYPE])
+ assertEquals(foo_handle, props[cs.TARGET_HANDLE])
event = q.expect('dbus-return', method='Close')
@@ -130,20 +115,16 @@ def test(q, bus, conn, stream):
# the message is still there
- messages = text_chan.ListPendingMessages(False,
- dbus_interface=cs.CHANNEL_TYPE_TEXT)
- assertEquals(
- [(hello_message_id, hello_message_time, foo_handle, 0, 8, 'hello')],
- messages)
+ messages = text_chan.Properties.Get(cs.CHANNEL_IFACE_MESSAGES, 'PendingMessages')
+ msg[0]['rescued'] = True
+ assertEquals([msg], messages)
# acknowledge it
- text_chan.AcknowledgePendingMessages([hello_message_id],
- dbus_interface=cs.CHANNEL_TYPE_TEXT)
+ text_chan.Text.AcknowledgePendingMessages([msg[0]['pending-message-id']])
- messages = text_chan.ListPendingMessages(False,
- dbus_interface=cs.CHANNEL_TYPE_TEXT)
- assert messages == []
+ messages = text_chan.Properties.Get(cs.CHANNEL_IFACE_MESSAGES, 'PendingMessages')
+ assertEquals([], messages)
# close the channel again
diff --git a/tests/twisted/text/send-error.py b/tests/twisted/text/send-error.py
index f330c0ae7..40d417f39 100644
--- a/tests/twisted/text/send-error.py
+++ b/tests/twisted/text/send-error.py
@@ -1,30 +1,25 @@
"""
-Test that an incoming <message><error/></> for a contact gives both a SendError
-and a delivery report on a 1-1 text channel to that contact.
+Test that an incoming <message><error/></> for a contact gives
+a delivery report on a 1-1 text channel to that contact.
"""
from twisted.words.xish import domish
from gabbletest import exec_test
-from servicetest import call_async, EventPattern
import constants as cs
import ns
def test_temporary_error(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
jid = 'foo@bar.com'
- call_async(q, conn, 'RequestHandles', 1, [jid])
+ foo_handle = conn.get_contact_handle_sync(jid)
- event = q.expect('dbus-return', method='RequestHandles')
- foo_handle = event.value[0][0]
-
- path = conn.Requests.CreateChannel(
+ conn.Requests.CreateChannel(
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
cs.TARGET_HANDLE: foo_handle,
})[0]
- text_chan = bus.get_object(conn.bus_name, path)
# <message from='foo@bar.com' type='error'>
# <body>what is up, my good sir?</body>
@@ -48,26 +43,10 @@ def test_temporary_error(q, bus, conn, stream):
stream.send(m)
- send_error, received, message_received = q.expect_many(
- EventPattern('dbus-signal', signal='SendError'),
- EventPattern('dbus-signal', signal='Received'),
- EventPattern('dbus-signal', signal='MessageReceived'),
- )
+ message_received = q.expect('dbus-signal', signal='MessageReceived')
expected_send_error = 4 # Too_Long
- assert send_error.args[0] == expected_send_error, send_error.args
- # FIXME: It doesn't look like it's possible to know what the original
- # message type is, given that the type attribute of <message> is 'error'
- # for error reports.
- #assert send_error.args[2] == 0, send_error.args
- assert send_error.args[3] == message_body, send_error.args
-
- assert received.args[2] == foo_handle, (received.args, foo_handle)
- assert received.args[3] == 4, received.args # Channel_Text_Message_Type_Delivery_Report
- assert received.args[4] == 2, received.args # Channel_Text_Message_Flag_Non_Text_Content
- assert received.args[5] == '', received.args
-
delivery_report = message_received.args[0]
assert len(delivery_report) == 1, delivery_report
header = delivery_report[0]
@@ -92,20 +71,16 @@ def test_temporary_error(q, bus, conn, stream):
def test_permanent_error(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
jid = 'wee@ninja.jp'
- call_async(q, conn, 'RequestHandles', 1, [jid])
+ ninja_handle = conn.get_contact_handle_sync(jid)
- event = q.expect('dbus-return', method='RequestHandles')
- ninja_handle = event.value[0][0]
-
- path = conn.Requests.CreateChannel(
+ conn.Requests.CreateChannel(
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
cs.TARGET_HANDLE: ninja_handle,
})[0]
- text_chan = bus.get_object(conn.bus_name, path)
# <message from='wee@ninja.jp' type='error'>
# <body>hello? is there anyone there?</body>
@@ -128,26 +103,10 @@ def test_permanent_error(q, bus, conn, stream):
stream.send(m)
- send_error, received, message_received = q.expect_many(
- EventPattern('dbus-signal', signal='SendError'),
- EventPattern('dbus-signal', signal='Received'),
- EventPattern('dbus-signal', signal='MessageReceived'),
- )
+ message_received = q.expect('dbus-signal', signal='MessageReceived')
expected_send_error = 2 # Invalid_Contact
- assert send_error.args[0] == expected_send_error, send_error.args
- # FIXME: It doesn't look like it's possible to know what the original
- # message type is, given that the type attribute of <message> is 'error'
- # for error reports.
- #assert send_error.args[2] == 0, send_error.args
- assert send_error.args[3] == message_body, send_error.args
-
- assert received.args[2] == ninja_handle, (received.args, ninja_handle)
- assert received.args[3] == 4, received.args # Channel_Text_Message_Type_Delivery_Report
- assert received.args[4] == 2, received.args # Channel_Text_Message_Flag_Non_Text_Content
- assert received.args[5] == '', received.args
-
delivery_report = message_received.args[0]
assert len(delivery_report) == 1, delivery_report
header = delivery_report[0]
diff --git a/tests/twisted/text/send-to-correct-resource.py b/tests/twisted/text/send-to-correct-resource.py
index f29fa51a1..8af7868a8 100644
--- a/tests/twisted/text/send-to-correct-resource.py
+++ b/tests/twisted/text/send-to-correct-resource.py
@@ -24,7 +24,7 @@ def test(q, bus, conn, stream):
chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
# When we start a conversation, Gabble should send to the bare JID.
- chan.Text.Send(0, 'hey, you around?')
+ chan.send_msg_sync('hey, you around?')
q.expect('stream-message', to=contact)
# A particular resource replies.
@@ -34,11 +34,11 @@ def test(q, bus, conn, stream):
m.addElement('body', content="i'm on a beach at Gran Canaria!")
stream.send(m)
- q.expect('dbus-signal', signal='Received')
+ q.expect('dbus-signal', signal='MessageReceived')
# Now that we got a reply from a particular resource, Gabble should reply
# there.
- chan.Text.Send(0, 'nice')
+ chan.send_msg_sync('nice')
q.expect('stream-message', to=contact_a)
# Now another resource messages us
@@ -48,10 +48,10 @@ def test(q, bus, conn, stream):
m.addElement('body', content="I brought my laptop to the Empathy hackfest")
stream.send(m)
- q.expect('dbus-signal', signal='Received')
+ q.expect('dbus-signal', signal='MessageReceived')
# Gabble should have updated the resource it's sending to.
- chan.Text.Send(0, "don't get sand in the keyboard")
+ chan.send_msg_sync("don't get sand in the keyboard")
e = q.expect('stream-message', to=contact_b)
# But actually that resource has gone offline:
@@ -65,10 +65,10 @@ def test(q, bus, conn, stream):
err.addElement((ns.STANZA, 'item-not-found'))
stream.send(m)
- q.expect('dbus-signal', signal='SendError')
+ q.expect('dbus-signal', signal='MessageReceived')
# So as a result, Gabble should send the next message to the bare JID.
- chan.Text.Send(0, "... i guess my warning was too late")
+ chan.send_msg_sync("... i guess my warning was too late")
q.expect('stream-message', to=contact)
if __name__ == '__main__':
diff --git a/tests/twisted/text/test-chat-state.py b/tests/twisted/text/test-chat-state.py
index c129fb7a3..4b0bf8f36 100644
--- a/tests/twisted/text/test-chat-state.py
+++ b/tests/twisted/text/test-chat-state.py
@@ -7,8 +7,7 @@ channels.
from twisted.words.xish import domish
from servicetest import (assertEquals, assertNotEquals,
- assertLength, wrap_channel, EventPattern, call_async,
- sync_dbus)
+ assertLength, wrap_channel, EventPattern, sync_dbus)
from gabbletest import exec_test, make_result_iq, sync_stream, make_presence
import constants as cs
import ns
@@ -38,19 +37,18 @@ def make_message(jid, body=None, state=None):
return m
def test(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
jid = 'foo@bar.com'
full_jid = 'foo@bar.com/Foo'
- foo_handle = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ foo_handle = conn.get_contact_handle_sync(jid)
path = conn.Requests.CreateChannel(
{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
cs.TARGET_HANDLE: foo_handle,
})[0]
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text',
- ['ChatState', 'Destroyable'])
+ chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
presence = make_presence(full_jid, status='hello',
caps={
@@ -143,7 +141,7 @@ def test(q, bus, conn, stream):
# XEP 0085:
# every content message SHOULD contain an <active/> notification.
- chan.Text.Send(0, 'hi.')
+ chan.send_msg_sync('hi.')
stream_message = q.expect('stream-message')
elem = stream_message.stanza
@@ -169,10 +167,9 @@ def test(q, bus, conn, stream):
# get a <gone/> notification, and the channel should respawn.
chan.Close()
- gone, _, _ = q.expect_many(
+ gone, _ = q.expect_many(
EventPattern('stream-message'),
EventPattern('dbus-signal', signal='Closed'),
- EventPattern('dbus-signal', signal='NewChannel'),
)
check_state_notification(gone.stanza, 'gone')
@@ -194,8 +191,7 @@ def test(q, bus, conn, stream):
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
cs.TARGET_HANDLE: foo_handle,
})[0]
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text',
- ['ChatState', 'Destroyable'])
+ chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
# Close it immediately; the peer should again not get a <gone/>
# notification, since we haven't sent any notifications on that channel.
@@ -218,8 +214,7 @@ def test(q, bus, conn, stream):
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
cs.TARGET_ID: jid,
})[0]
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text',
- ['ChatState'])
+ chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
stream.send(make_message(full_jid, body='i am invisible', state='active'))
@@ -239,7 +234,7 @@ def test(q, bus, conn, stream):
assertEquals(cs.CHAT_STATE_COMPOSING, state)
assertEquals(self_handle, handle)
- chan.Text.Send(0, 'very convincing')
+ chan.send_msg_sync('very convincing')
stream_message = q.expect('stream-message', to=full_jid)
check_state_notification(stream_message.stanza, 'active', allow_body=True)
@@ -253,8 +248,7 @@ def test(q, bus, conn, stream):
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
cs.TARGET_ID: jid,
})[0]
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text',
- ['ChatState'])
+ chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
# We shouldn't send any notifications until we actually send a message.
# But ChatStateChanged is still emitted locally
@@ -273,7 +267,7 @@ def test(q, bus, conn, stream):
q.unforbid_events([e])
# When we send a message, say we're active.
- chan.Text.Send(0, 'is anyone there?')
+ chan.send_msg_sync('is anyone there?')
stream_message = q.expect('stream-message', to=jid)
check_state_notification(stream_message.stanza, 'active', allow_body=True)
@@ -323,7 +317,7 @@ def test(q, bus, conn, stream):
# support notifications.
other_jid = jid + '/Library'
stream.send(make_message(other_jid, body='grr, library computers'))
- q.expect('dbus-signal', signal='Received')
+ q.expect('dbus-signal', signal='MessageReceived')
# Okay, we should stop sending typing notifications.
e = EventPattern('stream-message', to=other_jid)
@@ -344,8 +338,7 @@ def test(q, bus, conn, stream):
cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
cs.TARGET_ID: jid,
})[0]
- chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text',
- ['ChatState'])
+ chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
# We shouldn't send any notifications until we actually send a message.
e = EventPattern('stream-message', to=jid)
@@ -357,13 +350,13 @@ def test(q, bus, conn, stream):
q.unforbid_events([e])
# When we send a message, say we're active.
- chan.Text.Send(0, '#n900 #maemo #zomg #woo #yay http://bit.ly/n900')
+ chan.send_msg_sync('#n900 #maemo #zomg #woo #yay http://bit.ly/n900')
stream_message = q.expect('stream-message', to=jid)
check_state_notification(stream_message.stanza, 'active', allow_body=True)
# They reply without a chat state.
stream.send(make_message(full_jid, body="posted."))
- q.expect('dbus-signal', signal='Received')
+ q.expect('dbus-signal', signal='MessageReceived')
# Okay, we shouldn't send any more.
e = EventPattern('stream-message', to=other_jid)
@@ -374,7 +367,7 @@ def test(q, bus, conn, stream):
sync_stream(q, stream)
q.unforbid_events([e])
- chan.Text.Send(0, '@stephenfry simmer down')
+ chan.send_msg_sync('@stephenfry simmer down')
message = q.expect('stream-message')
states = [x for x in message.stanza.elements() if x.uri == ns.CHAT_STATES]
assertLength(0, states)
diff --git a/tests/twisted/text/test-text-delayed.py b/tests/twisted/text/test-text-delayed.py
index 3818e06e2..605b2c148 100644
--- a/tests/twisted/text/test-text-delayed.py
+++ b/tests/twisted/text/test-text-delayed.py
@@ -8,7 +8,7 @@ import datetime
from twisted.words.xish import domish
from gabbletest import exec_test
-from servicetest import EventPattern
+from servicetest import assertEquals
import constants as cs
def test(q, bus, conn, stream):
@@ -23,20 +23,14 @@ def test(q, bus, conn, stream):
stream.send(m)
- event = q.expect('dbus-signal', signal='NewChannel')
- assert event.args[1] == cs.CHANNEL_TYPE_TEXT
- assert event.args[2] == cs.HT_CONTACT
- jid = conn.InspectHandles(cs.HT_CONTACT, [event.args[3]])[0]
- assert jid == 'foo@bar.com'
+ event = q.expect('dbus-signal', signal='NewChannels')
+ path, props = event.args[0][0]
+ assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE])
+ assertEquals(cs.HT_CONTACT, props[cs.TARGET_HANDLE_TYPE])
+ jid = conn.inspect_contact_sync(props[cs.TARGET_HANDLE])
+ assertEquals('foo@bar.com', jid)
- received, message_received = q.expect_many(
- EventPattern('dbus-signal', signal='Received'),
- EventPattern('dbus-signal', signal='MessageReceived'),
- )
-
- assert (str(datetime.datetime.utcfromtimestamp(received.args[1]))
- == '2007-05-17 16:15:01')
- assert received.args[5] == 'hello'
+ message_received = q.expect('dbus-signal', signal='MessageReceived')
message = message_received.args[0]
header = message[0]
diff --git a/tests/twisted/text/test-text-no-body.py b/tests/twisted/text/test-text-no-body.py
index 2c4095f1c..34e54b7bb 100644
--- a/tests/twisted/text/test-text-no-body.py
+++ b/tests/twisted/text/test-text-no-body.py
@@ -7,6 +7,7 @@ new text channel.
from twisted.words.xish import domish
from gabbletest import exec_test
+from servicetest import assertEquals
import constants as cs
import ns
@@ -27,10 +28,11 @@ def test(q, bus, conn, stream):
stream.send(m)
# first message should be from Bob, not Alice
- event = q.expect('dbus-signal', signal='NewChannel')
- assert event.args[1] == cs.CHANNEL_TYPE_TEXT
- jid = conn.InspectHandles(cs.HT_CONTACT, [event.args[3]])[0]
- assert jid == 'bob@foo.com'
+ event = q.expect('dbus-signal', signal='NewChannels')
+ path, props = event.args[0][0]
+ assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE])
+ jid = conn.inspect_contact_sync(props[cs.TARGET_HANDLE])
+ assertEquals('bob@foo.com', jid)
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/text/test-text.py b/tests/twisted/text/test-text.py
index a820e135b..a6c42029f 100644
--- a/tests/twisted/text/test-text.py
+++ b/tests/twisted/text/test-text.py
@@ -8,10 +8,8 @@ import dbus
from twisted.words.xish import domish
from gabbletest import exec_test, elem
-from servicetest import (
- EventPattern, wrap_channel,
- assertEquals, assertNotEquals, assertLength,
- )
+from servicetest import (EventPattern, wrap_channel, assertEquals, assertLength,
+ assertContains)
import constants as cs
def test(q, bus, conn, stream):
@@ -25,52 +23,28 @@ def test(q, bus, conn, stream):
m.addElement('body', content='hello')
stream.send(m)
- event = q.expect('dbus-signal', signal='NewChannel')
- text_chan = wrap_channel(
- bus.get_object(conn.bus_name, event.args[0]), 'Text', ['Messages'])
- assert event.args[1] == cs.CHANNEL_TYPE_TEXT
- assert event.args[2] == cs.HT_CONTACT
- foo_at_bar_dot_com_handle = event.args[3]
- jid = conn.InspectHandles(1, [foo_at_bar_dot_com_handle])[0]
- assert jid == 'foo@bar.com'
- assert event.args[4] == False # suppress handler
+ event = q.expect('dbus-signal', signal='NewChannels')
+ path, props = event.args[0][0]
+ text_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
+ assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE])
+ assertEquals(cs.HT_CONTACT, props[cs.TARGET_HANDLE_TYPE])
+ foo_at_bar_dot_com_handle = props[cs.TARGET_HANDLE]
+ jid = conn.inspect_contact_sync(foo_at_bar_dot_com_handle)
+ assertEquals('foo@bar.com', jid)
# Exercise basic Channel Properties from spec 0.17.7
channel_props = text_chan.Properties.GetAll(cs.CHANNEL)
- assert channel_props.get('TargetHandle') == event.args[3],\
- (channel_props.get('TargetHandle'), event.args[3])
- assert channel_props.get('TargetHandleType') == cs.HT_CONTACT,\
- channel_props.get('TargetHandleType')
- assert channel_props.get('ChannelType') == \
- cs.CHANNEL_TYPE_TEXT,\
- channel_props.get('ChannelType')
- assert cs.CHANNEL_IFACE_CHAT_STATE in \
- channel_props.get('Interfaces', ()), \
- channel_props.get('Interfaces')
- assert cs.CHANNEL_IFACE_MESSAGES in \
- channel_props.get('Interfaces', ()), \
- channel_props.get('Interfaces')
- assert channel_props['TargetID'] == jid,\
- (channel_props['TargetID'], jid)
- assert channel_props['Requested'] == False
- assert channel_props['InitiatorHandle'] == event.args[3],\
- (channel_props['InitiatorHandle'], event.args[3])
- assert channel_props['InitiatorID'] == jid,\
- (channel_props['InitiatorID'], jid)
-
- received, message_received = q.expect_many(
- EventPattern('dbus-signal', signal='Received'),
- EventPattern('dbus-signal', signal='MessageReceived'),
- )
-
- # Check that C.T.Text.Received looks right
- # message type: normal
- assert received.args[3] == 0
- # flags: none
- assert received.args[4] == 0
- # body
- assert received.args[5] == 'hello'
-
+ assertEquals(props[cs.TARGET_HANDLE], channel_props.get('TargetHandle'))
+ assertEquals(cs.HT_CONTACT, channel_props.get('TargetHandleType'))
+ assertEquals(cs.CHANNEL_TYPE_TEXT, channel_props.get('ChannelType'))
+ assertContains(cs.CHANNEL_IFACE_CHAT_STATE, channel_props.get('Interfaces'))
+ assertContains(cs.CHANNEL_IFACE_MESSAGES, channel_props.get('Interfaces'))
+ assertEquals(jid, channel_props['TargetID'])
+ assertEquals(False, channel_props['Requested'])
+ assertEquals(props[cs.INITIATOR_HANDLE], channel_props['InitiatorHandle'])
+ assertEquals(jid, channel_props['InitiatorID'])
+
+ message_received = q.expect('dbus-signal', signal='MessageReceived')
# Check that C.I.Messages.MessageReceived looks right.
message = message_received.args[0]
@@ -114,9 +88,8 @@ def test(q, bus, conn, stream):
sent_token = text_chan.Messages.SendMessage(greeting, dbus.UInt32(0))
- stream_message, sent, message_sent = q.expect_many(
+ stream_message, message_sent = q.expect_many(
EventPattern('stream-message'),
- EventPattern('dbus-signal', signal='Sent'),
EventPattern('dbus-signal', signal='MessageSent'),
)
@@ -132,7 +105,7 @@ def test(q, bus, conn, stream):
header = sent_message[0]
assert header['message-type'] == 2, header # Notice
assert header['message-token'] == sent_token, header
- assertEquals(conn.GetSelfHandle(), header['message-sender'])
+ assertEquals(conn.Properties.Get(cs.CONN, "SelfHandle"), header['message-sender'])
assertEquals('test@localhost', header['message-sender-id'])
body = sent_message[1]
assert body['content-type'] == 'text/plain', body
@@ -140,16 +113,11 @@ def test(q, bus, conn, stream):
assert message_sent.args[2] == sent_token
- assert sent.args[1] == 2, sent.args # Notice
- assert sent.args[2] == u'what up', sent.args
-
-
# Send a message using Channel.Type.Text API
text_chan.Text.Send(0, 'goodbye')
- stream_message, sent, message_sent = q.expect_many(
+ stream_message, message_sent = q.expect_many(
EventPattern('stream-message'),
- EventPattern('dbus-signal', signal='Sent'),
EventPattern('dbus-signal', signal='MessageSent'),
)
@@ -170,9 +138,6 @@ def test(q, bus, conn, stream):
assert body['content-type'] == 'text/plain', body
assert body['content'] == u'goodbye', body
- assert sent.args[1] == 0, sent.args # message type normal
- assert sent.args[2] == u'goodbye', sent.args
-
# And now let's try a message with a malformed type='' attribute.
malformed = elem(
'message', from_='foo@bar.com/fubber', type="'")(
diff --git a/tests/twisted/tools/exec-with-log.sh.in b/tests/twisted/tools/exec-with-log.sh.in
index 9210eecc5..28968cad1 100644
--- a/tests/twisted/tools/exec-with-log.sh.in
+++ b/tests/twisted/tools/exec-with-log.sh.in
@@ -46,7 +46,7 @@ elif test -n "$GABBLE_TEST_REFDBG"; then
elif test -n "$GABBLE_TEST_STRACE"; then
GABBLE_WRAPPER="strace -o strace.log"
elif test -n "$GABBLE_TEST_BACKTRACE"; then
- GABBLE_WRAPPER="gdb -x run_and_bt.gdb"
+ GABBLE_WRAPPER="gdb -x @abs_top_srcdir@/tests/twisted/tools/run_and_bt.gdb"
fi
# Prevent libproxy from hitting the network for wpad configuration
diff --git a/tests/twisted/tubes/accept-muc-dbus-tube.py b/tests/twisted/tubes/accept-muc-dbus-tube.py
index df5b81ed0..2606fa254 100644
--- a/tests/twisted/tubes/accept-muc-dbus-tube.py
+++ b/tests/twisted/tubes/accept-muc-dbus-tube.py
@@ -2,7 +2,7 @@ import dbus
from servicetest import (
assertEquals, assertNotEquals, assertSameSets,
- call_async, EventPattern,
+ call_async, EventPattern, wrap_channel
)
from gabbletest import exec_test, acknowledge_iq, make_muc_presence
import constants as cs
@@ -11,6 +11,7 @@ from twisted.words.xish import xpath
import ns
from mucutil import join_muc_and_check
+import tubetestutil as t
def test(q, bus, conn, stream, access_control):
iq_event = q.expect('stream-iq', to=None, query_ns='vcard-temp',
@@ -19,7 +20,7 @@ def test(q, bus, conn, stream, access_control):
acknowledge_iq(stream, iq_event.stanza)
muc = 'chat@conf.localhost'
- _, _, test_handle, bob_handle = \
+ _, test_handle, bob_handle = \
join_muc_and_check(q, bus, conn, stream, muc)
# Bob offers a stream tube
@@ -63,22 +64,19 @@ def test(q, bus, conn, stream, access_control):
cs.SOCKET_ACCESS_CONTROL_LOCALHOST],
props[cs.DBUS_TUBE_SUPPORTED_ACCESS_CONTROLS])
- tube_chan = bus.get_object(conn.bus_name, path)
- tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_IFACE_TUBE)
- dbus_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_DBUS_TUBE)
- tube_chan_iface = dbus.Interface(tube_chan, cs.CHANNEL)
+ tube_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'DBusTube')
# only Bob is in DBusNames
dbus_names = tube_chan.Get(cs.CHANNEL_TYPE_DBUS_TUBE, 'DBusNames', dbus_interface=cs.PROPERTIES_IFACE)
assertEquals({bob_handle: bob_bus_name}, dbus_names)
- call_async(q, dbus_tube_iface, 'Accept', access_control)
+ call_async(q, tube_chan.DBusTube, 'Accept', access_control)
return_event, names_changed1, names_changed2, presence_event = q.expect_many(
EventPattern('dbus-return', method='Accept'),
EventPattern('dbus-signal', signal='DBusNamesChanged', interface=cs.CHANNEL_TYPE_DBUS_TUBE),
EventPattern('dbus-signal', signal='DBusNamesChanged', interface=cs.CHANNEL_TYPE_DBUS_TUBE),
- EventPattern('stream-presence', to='chat@conf.localhost/test'))
+ EventPattern('stream-presence', to='chat@conf.localhost/test', predicate=lambda e: t.presence_contains_tube(e)))
tube_addr = return_event.value[0]
assert len(tube_addr) > 0
@@ -92,7 +90,7 @@ def test(q, bus, conn, stream, access_control):
assertEquals('1', tube_node['id'])
self_bus_name = tube_node['dbus-name']
- tubes_self_handle = tube_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP)
+ tubes_self_handle = tube_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'SelfHandle')
assertNotEquals(0, tubes_self_handle)
# both of us are in DBusNames now
@@ -107,7 +105,7 @@ def test(q, bus, conn, stream, access_control):
assertEquals({tubes_self_handle: self_bus_name}, added)
assertEquals([], removed)
- tube_chan_iface.Close()
+ tube_chan.Channel.Close()
q.expect_many(
EventPattern('dbus-signal', signal='Closed'),
EventPattern('dbus-signal', signal='ChannelClosed'))
diff --git a/tests/twisted/tubes/accept-muc-stream-tube.py b/tests/twisted/tubes/accept-muc-stream-tube.py
index 7fc4aa0a6..a209ab08e 100644
--- a/tests/twisted/tubes/accept-muc-stream-tube.py
+++ b/tests/twisted/tubes/accept-muc-stream-tube.py
@@ -40,22 +40,22 @@ def test(q, bus, conn, stream, bytestream_cls,
announce_socks5_proxy(q, stream, disco_event.stanza)
- call_async(q, conn, 'RequestHandles', 2,
- ['chat@conf.localhost'])
-
- event = q.expect('dbus-return', method='RequestHandles')
- handles = event.value[0]
- room_handle = handles[0]
-
# join the muc
call_async(q, conn.Requests, 'CreateChannel', {
cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
- cs.TARGET_HANDLE: room_handle})
-
- _, stream_event = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [], [], [], [2], 0, 0]),
+ cs.TARGET_ID: 'chat@conf.localhost'})
+
+ q.expect_many(
+ EventPattern('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e:
+ e.args[0] == [] and # added
+ e.args[1] == [] and # removed
+ e.args[2] == [] and # local pending
+ len(e.args[3]) == 1 and # remote pending
+ e.args[4].get('actor', 0) == 0 and
+ e.args[4].get('change-reason', 0) == 0 and
+ e.args[4]['contact-ids'][e.args[3][0]] == 'chat@conf.localhost/test'),
EventPattern('stream-presence', to='chat@conf.localhost/test'))
# Send presence for other member of room.
@@ -64,12 +64,20 @@ def test(q, bus, conn, stream, bytestream_cls,
# Send presence for own membership of room.
stream.send(make_muc_presence('none', 'participant', 'chat@conf.localhost', 'test'))
- q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [2, 3], [], [], [], 0, 0])
-
- assert conn.InspectHandles(1, [2]) == ['chat@conf.localhost/test']
- assert conn.InspectHandles(1, [3]) == ['chat@conf.localhost/bob']
- bob_handle = 3
+ event = q.expect('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e:
+ len(e.args[0]) == 2 and # added
+ e.args[1] == [] and # removed
+ e.args[2] == [] and # local pending
+ e.args[3] == [] and # remote pending
+ e.args[4].get('actor', 0) == 0 and
+ e.args[4].get('change-reason', 0) == 0 and
+ set([e.args[4]['contact-ids'][h] for h in e.args[0]]) ==
+ set(['chat@conf.localhost/test', 'chat@conf.localhost/bob']))
+
+ for h in event.args[0]:
+ if event.args[4]['contact-ids'][h] == 'chat@conf.localhost/bob':
+ bob_handle = h
event = q.expect('dbus-return', method='CreateChannel')
@@ -102,11 +110,7 @@ def test(q, bus, conn, stream, bytestream_cls,
stream.send(presence)
# text channel
- event, new_event = q.expect_many(
- EventPattern('dbus-signal', signal='NewChannel'),
- EventPattern('dbus-signal', signal='NewChannels'))
-
- assert event.args[1] == cs.CHANNEL_TYPE_TEXT, event.args
+ new_event = q.expect('dbus-signal', signal='NewChannels')
channels = new_event.args[0]
assert len(channels) == 1
@@ -130,7 +134,6 @@ def test(q, bus, conn, stream, bytestream_cls,
assertSameSets([cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_TUBE],
props[cs.INTERFACES])
assert props[cs.REQUESTED] == False
- assert props[cs.TARGET_HANDLE] == room_handle
assert props[cs.TARGET_ID] == 'chat@conf.localhost'
assert props[cs.STREAM_TUBE_SERVICE] == 'echo'
assert props[cs.TUBE_PARAMETERS] == {'s': 'hello', 'ay': 'hello', 'u': 123, 'i': -123}
diff --git a/tests/twisted/tubes/accept-private-dbus-tube.py b/tests/twisted/tubes/accept-private-dbus-tube.py
index dbbeb3bed..fb81cb63e 100644
--- a/tests/twisted/tubes/accept-private-dbus-tube.py
+++ b/tests/twisted/tubes/accept-private-dbus-tube.py
@@ -37,7 +37,7 @@ def test(q, bus, conn, stream, bytestream_cls, access_control):
query_name='vCard'),
EventPattern('stream-iq', query_ns=ns.ROSTER))
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
acknowledge_iq(stream, vcard_event.stanza)
@@ -81,7 +81,7 @@ def test(q, bus, conn, stream, bytestream_cls, access_control):
# RequestChannel are the ones we wanted.
sync_dbus(bus, q, conn)
- bob_handle = conn.RequestHandles(cs.HT_CONTACT, ['bob@localhost'])[0]
+ bob_handle = conn.get_contact_handle_sync('bob@localhost')
# let's try to accept a D-Bus tube using the new API
bytestream = bytestream_cls(stream, q, 'gamma', bob_full_jid,
diff --git a/tests/twisted/tubes/check-create-tube-return.py b/tests/twisted/tubes/check-create-tube-return.py
index 46db340c4..2f1e34aa9 100644
--- a/tests/twisted/tubes/check-create-tube-return.py
+++ b/tests/twisted/tubes/check-create-tube-return.py
@@ -39,9 +39,8 @@ def test(q, bus, conn, stream):
stream.send(make_muc_presence('owner', 'moderator', muc, 'bob'))
stream.send(make_muc_presence('none', 'participant', muc, 'test'))
- ret, _, _ = q.expect_many(
+ ret, _ = q.expect_many(
EventPattern('dbus-return', method='CreateChannel'),
- EventPattern('dbus-signal', signal='NewChannel'),
EventPattern('dbus-signal', signal='NewChannels'),
)
@@ -62,9 +61,8 @@ def test(q, bus, conn, stream):
cs.TARGET_ID: muc,
cs.DBUS_TUBE_SERVICE_NAME: 'com.example.LolDongs'})
- ret, _, _ = q.expect_many(
+ ret, _ = q.expect_many(
EventPattern('dbus-return', method='CreateChannel'),
- EventPattern('dbus-signal', signal='NewChannel'),
EventPattern('dbus-signal', signal='NewChannels'),
)
diff --git a/tests/twisted/tubes/close-muc-with-closed-tube.py b/tests/twisted/tubes/close-muc-with-closed-tube.py
index ed08add64..c5a7a5da4 100644
--- a/tests/twisted/tubes/close-muc-with-closed-tube.py
+++ b/tests/twisted/tubes/close-muc-with-closed-tube.py
@@ -21,19 +21,22 @@ def test(q, bus, conn, stream):
acknowledge_iq(stream, iq_event.stanza)
- call_async(q, conn, 'RequestHandles', cs.HT_ROOM, ['chat@conf.localhost'])
-
- event = q.expect('dbus-return', method='RequestHandles')
- handles = event.value[0]
- room_handle = handles[0]
-
# join the muc
- call_async(q, conn, 'RequestChannel',
- cs.CHANNEL_TYPE_TEXT, cs.HT_ROOM, room_handle, True)
-
- _, stream_event = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [], [], [], [2], 0, 0]),
+ call_async(q, conn.Requests, 'CreateChannel', {
+ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
+ cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
+ cs.TARGET_ID: 'chat@conf.localhost'})
+
+ q.expect_many(
+ EventPattern('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e:
+ e.args[0] == [] and # added
+ e.args[1] == [] and # removed
+ e.args[2] == [] and # local pending
+ len(e.args[3]) == 1 and # remote pending
+ e.args[4].get('actor', 0) == 0 and
+ e.args[4].get('change-reason', 0) == 0 and
+ e.args[4]['contact-ids'][e.args[3][0]] == 'chat@conf.localhost/test'),
EventPattern('stream-presence', to='chat@conf.localhost/test'))
# Send presence for other member of room.
@@ -42,14 +45,22 @@ def test(q, bus, conn, stream):
# Send presence for own membership of room.
stream.send(make_muc_presence('none', 'participant', 'chat@conf.localhost', 'test'))
- q.expect('dbus-signal', signal='MembersChanged',
- args=[u'', [2, 3], [], [], [], 0, 0])
-
- assert conn.InspectHandles(cs.HT_CONTACT, [2, 3]) == \
- ['chat@conf.localhost/test', 'chat@conf.localhost/bob']
- bob_handle = 3
-
- event = q.expect('dbus-return', method='RequestChannel')
+ event = q.expect('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e:
+ len(e.args[0]) == 2 and # added
+ e.args[1] == [] and # removed
+ e.args[2] == [] and # local pending
+ e.args[3] == [] and # remote pending
+ e.args[4].get('actor', 0) == 0 and
+ e.args[4].get('change-reason', 0) == 0 and
+ set([e.args[4]['contact-ids'][h] for h in e.args[0]]) ==
+ set(['chat@conf.localhost/test', 'chat@conf.localhost/bob']))
+
+ for h in event.args[0]:
+ if event.args[4]['contact-ids'][h] == 'chat@conf.localhost/bob':
+ bob_handle = h
+
+ event = q.expect('dbus-return', method='CreateChannel')
text_chan = bus.get_object(conn.bus_name, event.value[0])
# Bob offers a muc tube
@@ -96,7 +107,6 @@ def test(q, bus, conn, stream):
assertEquals(cs.CHANNEL_TYPE_DBUS_TUBE, props[cs.CHANNEL_TYPE])
assertEquals(cs.HT_ROOM, props[cs.TARGET_HANDLE_TYPE])
- assertEquals(room_handle, props[cs.TARGET_HANDLE])
assertEquals('chat@conf.localhost', props[cs.TARGET_ID])
assertEquals(False, props[cs.REQUESTED])
diff --git a/tests/twisted/tubes/ensure-si-tube.py b/tests/twisted/tubes/ensure-si-tube.py
index dccb337cc..259c464a7 100644
--- a/tests/twisted/tubes/ensure-si-tube.py
+++ b/tests/twisted/tubes/ensure-si-tube.py
@@ -70,7 +70,7 @@ def test(q, bus, conn, stream):
feature['var'] = ns.TUBES
stream.send(result)
- bob_handle = conn.RequestHandles(1, ['bob@localhost'])[0]
+ bob_handle = conn.get_contact_handle_sync('bob@localhost')
def new_chan_predicate(e):
types = []
diff --git a/tests/twisted/tubes/offer-muc-dbus-tube.py b/tests/twisted/tubes/offer-muc-dbus-tube.py
index 06ccc2804..ff10045c9 100644
--- a/tests/twisted/tubes/offer-muc-dbus-tube.py
+++ b/tests/twisted/tubes/offer-muc-dbus-tube.py
@@ -6,7 +6,7 @@ import dbus
from dbus.connection import Connection
from dbus.lowlevel import SignalMessage
-from servicetest import call_async, EventPattern, assertContains, assertEquals
+from servicetest import call_async, EventPattern, assertContains, assertEquals, wrap_channel
from gabbletest import exec_test, acknowledge_iq, elem, make_muc_presence, sync_stream
import ns
import constants as cs
@@ -114,8 +114,8 @@ def test(q, bus, conn, stream, access_control):
# check if we can request muc D-Bus tube
t.check_conn_properties(q, conn)
- self_handle = conn.GetSelfHandle()
- self_name = conn.InspectHandles(1, [self_handle])[0]
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
+ self_name = conn.inspect_contact_sync(self_handle)
# offer a D-Bus tube to another room using new API
muc = 'chat2@conf.localhost'
@@ -146,32 +146,29 @@ def test(q, bus, conn, stream, access_control):
dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True)
assertContains((path, prop), all_channels)
- tube_chan = bus.get_object(conn.bus_name, path)
- dbus_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_DBUS_TUBE)
- chan_iface = dbus.Interface(tube_chan, cs.CHANNEL)
- tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE,
- byte_arrays=True)
+ tube_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'DBusTube')
+ tube_props = tube_chan.Properties.GetAll(cs.CHANNEL_IFACE_TUBE, byte_arrays=True)
assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED
# try to offer using a wrong access control
try:
- dbus_tube_iface.Offer(sample_parameters, cs.SOCKET_ACCESS_CONTROL_PORT)
+ tube_chan.DBusTube.Offer(sample_parameters, cs.SOCKET_ACCESS_CONTROL_PORT)
except dbus.DBusException, e:
assertEquals(e.get_dbus_name(), cs.INVALID_ARGUMENT)
else:
assert False
# offer the tube
- call_async(q, dbus_tube_iface, 'Offer', sample_parameters, access_control)
+ call_async(q, tube_chan.DBusTube, 'Offer', sample_parameters, access_control)
presence_event, return_event, status_event, dbus_changed_event = q.expect_many(
- EventPattern('stream-presence', to='chat2@conf.localhost/test'),
+ EventPattern('stream-presence', to='chat2@conf.localhost/test', predicate=lambda e: t.presence_contains_tube(e)),
EventPattern('dbus-return', method='Offer'),
EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[cs.TUBE_CHANNEL_STATE_OPEN]),
EventPattern('dbus-signal', signal='DBusNamesChanged', interface=cs.CHANNEL_TYPE_DBUS_TUBE))
- tube_self_handle = tube_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP)
+ tube_self_handle = tube_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'SelfHandle')
assert tube_self_handle != 0
# handle presence_event
@@ -188,7 +185,7 @@ def test(q, bus, conn, stream, access_control):
dbus_tube_adr = return_event.value[0]
bob_bus_name = ':2.Ym9i'
- bob_handle = conn.RequestHandles(cs.HT_CONTACT, ['chat2@conf.localhost/bob'])[0]
+ bob_handle = conn.get_contact_handle_sync('chat2@conf.localhost/bob')
def bob_in_tube():
presence = elem('presence', from_='chat2@conf.localhost/bob', to='chat2@conf.localhost')(
@@ -242,7 +239,7 @@ def test(q, bus, conn, stream, access_control):
names = tube_chan.Get(cs.CHANNEL_TYPE_DBUS_TUBE, 'DBusNames', dbus_interface=cs.PROPERTIES_IFACE)
assert names == {tube_self_handle: my_bus_name}
- chan_iface.Close()
+ tube_chan.Channel.Close()
_, _, event = q.expect_many(
EventPattern('dbus-signal', signal='Closed'),
EventPattern('dbus-signal', signal='ChannelClosed'),
diff --git a/tests/twisted/tubes/offer-muc-stream-tube.py b/tests/twisted/tubes/offer-muc-stream-tube.py
index 2188e82a9..1a3604563 100644
--- a/tests/twisted/tubes/offer-muc-stream-tube.py
+++ b/tests/twisted/tubes/offer-muc-stream-tube.py
@@ -5,7 +5,7 @@ import os
import dbus
-from servicetest import call_async, EventPattern, unwrap, assertContains, assertEquals
+from servicetest import call_async, EventPattern, unwrap, assertContains, assertEquals, wrap_channel
from gabbletest import acknowledge_iq, make_muc_presence
import constants as cs
import ns
@@ -74,7 +74,7 @@ def test(q, bus, conn, stream, bytestream_cls,
t.check_conn_properties(q, conn)
- bob_handle = conn.RequestHandles(cs.HT_CONTACT, ['chat@conf.localhost/bob'])[0]
+ bob_handle = conn.get_contact_handle_sync('chat@conf.localhost/bob')
address = t.create_server(q, address_type)
@@ -101,7 +101,7 @@ def test(q, bus, conn, stream, bytestream_cls,
cs.TARGET_ID: 'chat@conf.localhost',
cs.STREAM_TUBE_SERVICE: 'newecho',
}
- _, _, new_tube_path, new_tube_props = \
+ _, new_tube_path, new_tube_props = \
join_muc(q, bus, conn, stream, 'chat@conf.localhost', request)
e = q.expect('dbus-signal', signal='NewChannels',
@@ -120,23 +120,21 @@ def test(q, bus, conn, stream, bytestream_cls,
dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True)
assertContains((path, prop), all_channels)
- tube_chan = bus.get_object(conn.bus_name, path)
- stream_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE)
- chan_iface = dbus.Interface(tube_chan, cs.CHANNEL)
+ tube_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamTube')
tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE)
assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED
# offer the tube
- call_async(q, stream_tube_iface, 'Offer', address_type, address, access_control, {'foo': 'bar'})
+ call_async(q, tube_chan.StreamTube, 'Offer', address_type, address, access_control, {'foo': 'bar'})
stream_event, _, status_event = q.expect_many(
- EventPattern('stream-presence', to='chat@conf.localhost/test'),
+ EventPattern('stream-presence', to='chat@conf.localhost/test', predicate=lambda e: t.presence_contains_tube(e)),
EventPattern('dbus-return', method='Offer'),
EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[cs.TUBE_CHANNEL_STATE_OPEN]))
- tube_self_handle = tube_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP)
- assert conn.InspectHandles(cs.HT_CONTACT, [tube_self_handle]) == ['chat@conf.localhost/test']
+ tube_self_handle = tube_chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, 'SelfHandle')
+ assert conn.inspect_contact_sync(tube_self_handle) == 'chat@conf.localhost/test'
presence = stream_event.stanza
tubes_nodes = xpath.queryForNodes('/presence/tubes[@xmlns="%s"]'
@@ -165,7 +163,7 @@ def test(q, bus, conn, stream, bytestream_cls,
params[node['name']] = (node['type'], str(node))
assert params == {'foo': ('str', 'bar')}
- bob_handle = conn.RequestHandles(cs.HT_CONTACT, ['chat@conf.localhost/bob'])[0]
+ bob_handle = conn.get_contact_handle_sync('chat@conf.localhost/bob')
bytestream = connect_to_tube(stream, q, bytestream_cls, 'chat@conf.localhost', stream_tube_id)
@@ -190,7 +188,7 @@ def test(q, bus, conn, stream, bytestream_cls,
use_tube(q, bytestream, protocol, conn_id)
- chan_iface.Close()
+ tube_chan.Channel.Close()
q.expect_many(
EventPattern('dbus-signal', signal='Closed'),
EventPattern('dbus-signal', signal='ChannelClosed'))
diff --git a/tests/twisted/tubes/offer-private-dbus-tube.py b/tests/twisted/tubes/offer-private-dbus-tube.py
index bb61eb21c..ee4e190a7 100644
--- a/tests/twisted/tubes/offer-private-dbus-tube.py
+++ b/tests/twisted/tubes/offer-private-dbus-tube.py
@@ -202,8 +202,8 @@ def test(q, bus, conn, stream, bytestream_cls, access_control):
t.check_conn_properties(q, conn)
- self_handle = conn.GetSelfHandle()
- alice_handle = conn.RequestHandles(cs.HT_CONTACT, ["alice@localhost"])[0]
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
+ alice_handle = conn.get_contact_handle_sync('alice@localhost')
# send Alice's presence
caps = { 'ext': '', 'ver': '0.0.0',
diff --git a/tests/twisted/tubes/offer-private-stream-tube.py b/tests/twisted/tubes/offer-private-stream-tube.py
index de37041c2..807959d8e 100644
--- a/tests/twisted/tubes/offer-private-stream-tube.py
+++ b/tests/twisted/tubes/offer-private-stream-tube.py
@@ -51,7 +51,7 @@ def test(q, bus, conn, stream, bytestream_cls,
query_name='vCard'),
EventPattern('stream-iq', query_ns=ns.ROSTER))
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
acknowledge_iq(stream, vcard_event.stanza)
@@ -96,7 +96,7 @@ def test(q, bus, conn, stream, bytestream_cls,
sync_dbus(bus, q, conn)
# Test tubes with Bob. Bob has tube capabilities.
- bob_handle = conn.RequestHandles(1, ['bob@localhost'])[0]
+ bob_handle = conn.get_contact_handle_sync('bob@localhost')
# Try CreateChannel with correct properties
# Gabble must succeed
diff --git a/tests/twisted/tubes/test-get-available-tubes.py b/tests/twisted/tubes/test-get-available-tubes.py
index 7b860ebfd..a5508486d 100644
--- a/tests/twisted/tubes/test-get-available-tubes.py
+++ b/tests/twisted/tubes/test-get-available-tubes.py
@@ -39,9 +39,17 @@ def test(q, bus, conn, stream):
# Send presence for own membership of room.
stream.send(make_muc_presence('owner', 'moderator', 'chat@conf.localhost', 'test'))
- members, event = q.expect_many(
- EventPattern('dbus-signal', signal='MembersChanged',
- args=[u'', [2, 3], [], [], [], 0, 0]),
+ _, event = q.expect_many(
+ EventPattern('dbus-signal', signal='MembersChangedDetailed',
+ predicate=lambda e:
+ len(e.args[0]) == 2 and # added
+ e.args[1] == [] and # removed
+ e.args[2] == [] and # local pending
+ e.args[3] == [] and # remote pending
+ e.args[4].get('actor', 0) == 0 and
+ e.args[4].get('change-reason', 0) == 0 and
+ set([e.args[4]['contact-ids'][h] for h in e.args[0]]) ==
+ set(['chat@conf.localhost/test', 'chat@conf.localhost/bob'])),
EventPattern('dbus-return', method='CreateChannel'))
path = event.value[0]
diff --git a/tests/twisted/tubes/test-socks5-muc.py b/tests/twisted/tubes/test-socks5-muc.py
index 4153801f8..54947ec55 100644
--- a/tests/twisted/tubes/test-socks5-muc.py
+++ b/tests/twisted/tubes/test-socks5-muc.py
@@ -27,7 +27,7 @@ def test(q, bus, conn, stream):
announce_socks5_proxy(q, stream, disco_event.stanza)
- text_chan = join_muc(q, bus, conn, stream, 'chat@conf.localhost')
+ join_muc(q, bus, conn, stream, 'chat@conf.localhost')
# bob offers a stream tube
stream_tube_id = 1
diff --git a/tests/twisted/tubes/tubetestutil.py b/tests/twisted/tubes/tubetestutil.py
index 3eb86d9d5..3c53d1533 100644
--- a/tests/twisted/tubes/tubetestutil.py
+++ b/tests/twisted/tubes/tubetestutil.py
@@ -21,6 +21,7 @@ from twisted.internet import reactor
from twisted.internet.protocol import Factory, Protocol
from twisted.internet.error import CannotListenError
from twisted.internet import tcp
+from twisted.words.xish import xpath
_to_cleanup = []
@@ -181,7 +182,7 @@ def check_channel_properties(q, bus, conn, channel, channel_type,
assert channel_props['TargetID'] == contact_id
assert channel_props['Requested'] == True
assert channel_props['InitiatorID'] == 'test@localhost'
- assert channel_props['InitiatorHandle'] == conn.GetSelfHandle()
+ assert channel_props['InitiatorHandle'] == conn.Properties.Get(cs.CONN, "SelfHandle")
if channel_type == cs.CHANNEL_TYPE_TUBES:
assert state is None
@@ -373,3 +374,7 @@ def exec_stream_tube_test(test):
def exec_dbus_tube_test(test):
exec_tube_test(test, cs.SOCKET_ACCESS_CONTROL_CREDENTIALS)
exec_tube_test(test, cs.SOCKET_ACCESS_CONTROL_LOCALHOST)
+
+def presence_contains_tube(e):
+ return xpath.queryForNodes('/presence/tubes[@xmlns="%s"]/tube'
+ % ns.TUBES, e.stanza) is not None
diff --git a/tests/twisted/vcard/disconnect-during-pep.py b/tests/twisted/vcard/disconnect-during-pep.py
index cb05ad5b3..38f7d002a 100644
--- a/tests/twisted/vcard/disconnect-during-pep.py
+++ b/tests/twisted/vcard/disconnect-during-pep.py
@@ -15,7 +15,7 @@ def test(q, bus, conn, stream):
acknowledge_iq(stream, event.stanza)
- handle = conn.RequestHandles(cs.HT_CONTACT, ['bob@foo.com'])[0]
+ handle = conn.get_contact_handle_sync('bob@foo.com')
call_async(q, conn.Aliasing, 'RequestAliases', [handle])
# First, Gabble sends a PEP query
diff --git a/tests/twisted/vcard/get-contact-info.py b/tests/twisted/vcard/get-contact-info.py
index 6c61ecd24..f546c350f 100644
--- a/tests/twisted/vcard/get-contact-info.py
+++ b/tests/twisted/vcard/get-contact-info.py
@@ -17,7 +17,7 @@ def test(q, bus, conn, stream):
# returning an empty vcard will cause ContactInfoChanged to fire
q.expect('dbus-signal', signal='ContactInfoChanged')
- handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
+ handle = conn.get_contact_handle_sync('bob@foo.com')
call_async(q, conn.ContactInfo, 'RefreshContactInfo', [handle])
event = q.expect('stream-iq', to='bob@foo.com', query_ns='vcard-temp',
@@ -56,16 +56,8 @@ def test(q, bus, conn, stream):
u'Exemplary Team']),
]
# The request should be satisfied from the cache.
- assertEquals(
- {handle: contact_info}, conn.ContactInfo.GetContactInfo([handle]))
-
- # check the ContactAttribute
- assertEquals(
- {handle: {cs.CONN_IFACE_CONTACT_INFO + '/info': contact_info,
- 'org.freedesktop.Telepathy.Connection/contact-id': 'bob@foo.com'}},
- conn.Contacts.GetContactAttributes([handle],
- [cs.CONN_IFACE_CONTACT_INFO], False))
-
+ h2asv = conn.Contacts.GetContactAttributes([handle], [cs.CONN_IFACE_CONTACT_INFO], False)
+ assertEquals(contact_info, h2asv[handle][cs.ATTR_CONTACT_INFO])
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/vcard/overlapping-sets.py b/tests/twisted/vcard/overlapping-sets.py
index a57ca9cc4..a6565095f 100644
--- a/tests/twisted/vcard/overlapping-sets.py
+++ b/tests/twisted/vcard/overlapping-sets.py
@@ -17,7 +17,7 @@ def test(q, bus, conn, stream):
query_ns=ns.VCARD_TEMP, query_name='vCard')
sync_stream(q, stream)
- handle = conn.GetSelfHandle()
+ handle = conn.Properties.Get(cs.CONN, "SelfHandle")
call_async(q, conn.Aliasing, 'SetAliases', {handle: 'Robert the Bruce'})
sync_dbus(bus, q, conn)
acknowledge_iq(stream, vcard_get_event.stanza)
diff --git a/tests/twisted/vcard/refresh-contact-info.py b/tests/twisted/vcard/refresh-contact-info.py
index 3fc87d3f0..84630da67 100644
--- a/tests/twisted/vcard/refresh-contact-info.py
+++ b/tests/twisted/vcard/refresh-contact-info.py
@@ -15,7 +15,7 @@ def test(q, bus, conn, stream):
acknowledge_iq(stream, event.stanza)
- handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
+ handle = conn.get_contact_handle_sync('bob@foo.com')
call_async(q, conn.ContactInfo, 'RefreshContactInfo', [handle])
event = q.expect('stream-iq', to='bob@foo.com', query_ns='vcard-temp',
diff --git a/tests/twisted/vcard/test-alias-empty-vcard.py b/tests/twisted/vcard/test-alias-empty-vcard.py
index 8a03737f3..c711a07e3 100644
--- a/tests/twisted/vcard/test-alias-empty-vcard.py
+++ b/tests/twisted/vcard/test-alias-empty-vcard.py
@@ -14,7 +14,7 @@ def test(q, bus, conn, stream):
acknowledge_iq(stream, event.stanza)
- handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
+ handle = conn.get_contact_handle_sync('bob@foo.com')
call_async(q, conn.Aliasing, 'RequestAliases', [handle])
# Nack PEP query.
diff --git a/tests/twisted/vcard/test-alias-message.py b/tests/twisted/vcard/test-alias-message.py
index 362036a0e..07f889bf2 100644
--- a/tests/twisted/vcard/test-alias-message.py
+++ b/tests/twisted/vcard/test-alias-message.py
@@ -14,15 +14,22 @@ from mucutil import join_muc, make_muc_presence
import constants as cs
import ns
+def get_aliases(conn, contacts):
+ h2asv = conn.Contacts.GetContactAttributes(contacts, [cs.CONN_IFACE_ALIASING], False)
+ ret = {}
+ for h in contacts:
+ ret[h] = h2asv[h][cs.ATTR_ALIAS]
+ return ret
+
def test(q, bus, conn, stream):
expect_and_handle_get_vcard(q, stream)
jid = u'bora.horza.gobuchul@culture.lit'
alias = u'Horza'
- handle = conn.RequestHandles(cs.HT_CONTACT, [jid])[0]
+ handle = conn.get_contact_handle_sync(jid)
# We don't have an interesting alias for Horza
- assertEquals({handle: jid}, conn.Aliasing.GetAliases([handle]))
+ assertEquals({handle: jid}, get_aliases(conn, [handle]))
# Horza sends us a message containing his preferred nickname.
stream.send(
@@ -39,7 +46,7 @@ def test(q, bus, conn, stream):
channel = wrap_channel(bus.get_object(conn.bus_name, mr.path), 'Text')
# So now we know his alias.
- assertEquals({handle: alias}, conn.Aliasing.GetAliases([handle]))
+ assertEquals({handle: alias}, get_aliases(conn, [handle]))
# Presumably to avoid non-contacts being able to make Gabble's memory
# footprint grow forever, Gabble throws the alias away when we close the
@@ -51,7 +58,7 @@ def test(q, bus, conn, stream):
# FIXME: Gabble forgets the alias, but it doesn't signal that it has done
# so; it probably should.
# q.expect('dbus-signal', signal='AliasesChanged', args=[[(handle, jid)]])
- assertEquals({handle: jid}, conn.Aliasing.GetAliases([handle]))
+ assertEquals({handle: jid}, get_aliases(conn, [handle]))
# Basically the same test, but in a MUC.
@@ -68,12 +75,12 @@ def test(q, bus, conn, stream):
# make it explicit. Perhaps in future we might change this test to verify
# that it doesn't "work".
room_jid = 'clear-air-turbulence@culture.lit'
- _, muc, _, _ = join_muc(q, bus, conn, stream, room_jid)
+ muc, _, _ = join_muc(q, bus, conn, stream, room_jid)
bob_jid = room_jid + '/bob'
- bob_handle = conn.RequestHandles(cs.HT_CONTACT, [bob_jid])[0]
+ bob_handle = conn.get_contact_handle_sync(bob_jid)
- assertEquals({bob_handle: 'bob'}, conn.Aliasing.GetAliases([bob_handle]))
+ assertEquals({bob_handle: 'bob'}, get_aliases(conn, [bob_handle]))
stream.send(
elem('message', from_=bob_jid, type='groupchat')(
@@ -86,7 +93,7 @@ def test(q, bus, conn, stream):
args=[[(bob_handle, alias)]]),
EventPattern('dbus-signal', signal='MessageReceived'),)
- assertEquals({bob_handle: alias}, conn.Aliasing.GetAliases([bob_handle]))
+ assertEquals({bob_handle: alias}, get_aliases(conn, [bob_handle]))
muc.Close()
q.expect('stream-presence', to=room_jid + '/test')
@@ -99,7 +106,7 @@ def test(q, bus, conn, stream):
# so; it probably should.
# q.expect('dbus-signal', signal='AliasesChanged',
# args=[[(bob_handle, 'bob')]])
- assertEquals({bob_handle: 'bob'}, conn.Aliasing.GetAliases([bob_handle]))
+ assertEquals({bob_handle: 'bob'}, get_aliases(conn, [bob_handle]))
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/vcard/test-alias-pep.py b/tests/twisted/vcard/test-alias-pep.py
index 0adc2b9e6..201eeeeb1 100644
--- a/tests/twisted/vcard/test-alias-pep.py
+++ b/tests/twisted/vcard/test-alias-pep.py
@@ -15,7 +15,7 @@ def test(q, bus, conn, stream):
acknowledge_iq(stream, event.stanza)
- handle = conn.RequestHandles(cs.HT_CONTACT, ['bob@foo.com'])[0]
+ handle = conn.get_contact_handle_sync('bob@foo.com')
call_async(q, conn.Aliasing, 'RequestAliases', [handle])
event = q.expect('stream-iq', to='bob@foo.com', iq_type='get',
diff --git a/tests/twisted/vcard/test-alias.py b/tests/twisted/vcard/test-alias.py
index 7e8dff2ec..72d0bf5bc 100644
--- a/tests/twisted/vcard/test-alias.py
+++ b/tests/twisted/vcard/test-alias.py
@@ -13,7 +13,7 @@ def test(q, bus, conn, stream):
acknowledge_iq(stream, event.stanza)
- handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
+ handle = conn.get_contact_handle_sync('bob@foo.com')
call_async(q, conn.Aliasing, 'RequestAliases', [handle])
# Nack PEP query.
diff --git a/tests/twisted/vcard/test-avatar-async.py b/tests/twisted/vcard/test-avatar-async.py
index 423e9ff8d..a3e250ab5 100644
--- a/tests/twisted/vcard/test-avatar-async.py
+++ b/tests/twisted/vcard/test-avatar-async.py
@@ -48,7 +48,7 @@ def test(q, bus, conn, stream):
# When we start, there is no avatar
acknowledge_iq(stream, iq_event.stanza)
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
# Another resource confirms we have no avatar. We don't request our vCard
# because we already know there is no avatar
@@ -66,7 +66,7 @@ def test(q, bus, conn, stream):
q.unforbid_events([avatar_request_event, avatar_retrieved_event])
# Request on the first contact. Test the cache.
- handle = conn.RequestHandles(cs.HT_CONTACT, ['bob@foo.com'])[0]
+ handle = conn.get_contact_handle_sync('bob@foo.com')
test_get_avatar(q, bus, conn, stream, 'bob@foo.com', handle,
in_cache=False)
test_get_avatar(q, bus, conn, stream, 'bob@foo.com', handle,
@@ -74,7 +74,7 @@ def test(q, bus, conn, stream):
# Request another vCard and get resource-constraint
busy_contact = 'jean@busy-server.com'
- busy_handle = conn.RequestHandles(cs.HT_CONTACT, [busy_contact])[0]
+ busy_handle = conn.get_contact_handle_sync(busy_contact)
conn.Avatars.RequestAvatars([busy_handle])
iq_event = q.expect('stream-iq', to=busy_contact, query_ns='vcard-temp',
@@ -97,7 +97,7 @@ def test(q, bus, conn, stream):
# Request on a different contact, on another server
# We should get the avatar
- handle = conn.RequestHandles(cs.HT_CONTACT, ['bob2@foo.com'])[0]
+ handle = conn.get_contact_handle_sync('bob2@foo.com')
test_get_avatar(q, bus, conn, stream, 'bob2@foo.com', handle)
# Try again the contact on the busy server.
@@ -180,26 +180,23 @@ def test(q, bus, conn, stream):
# Gabble must reply without asking the vCard to the server because the
# avatar must be in the cache
q.forbid_events([avatar_request_event])
- data, mime = conn.Avatars.RequestAvatar(self_handle, byte_arrays=True)
- assertEquals('\o/', data)
- data, mime = conn.Avatars.RequestAvatar(handle, byte_arrays=True)
- assertEquals('hello', data)
+ conn.Avatars.RequestAvatars([self_handle])
+ e = q.expect('dbus-signal', signal='AvatarRetrieved')
+ assertEquals('\o/', e.args[2])
+ conn.Avatars.RequestAvatars([handle])
+ e = q.expect('dbus-signal', signal='AvatarRetrieved')
+ assertEquals('hello', e.args[2])
q.unforbid_events([avatar_request_event])
# First, ensure the pipeline is full
contacts = ['random_user_%s@bigserver.com' % i for i in range(1, 100) ]
- handles = conn.RequestHandles(cs.HT_CONTACT, contacts)
+ handles = conn.get_contact_handles_sync(contacts)
conn.Avatars.RequestAvatars(handles)
# Then, request yet another avatar. The request will time out before
# the IQ is sent, which used to trigger a crash in Gabble
- # (LP#445847). So, we assert that the error is NotAvailable (rather
- # than the error returned when the service crashes).
- try:
- conn.Avatars.RequestAvatar(handles[-1])
- except dbus.DBusException, e:
- assertEquals(cs.NOT_AVAILABLE, e.get_dbus_name())
- else:
- assert False
+ # (LP#445847).
+ conn.Avatars.RequestAvatars([handles[-1]])
+ sync_dbus(bus, q, conn)
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/vcard/test-avatar-retrieved.py b/tests/twisted/vcard/test-avatar-retrieved.py
index b612ca901..c332d5cfb 100644
--- a/tests/twisted/vcard/test-avatar-retrieved.py
+++ b/tests/twisted/vcard/test-avatar-retrieved.py
@@ -16,7 +16,7 @@ def test(q, bus, conn, stream):
acknowledge_iq(stream, iq_event.stanza)
- handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
+ handle = conn.get_contact_handle_sync('bob@foo.com')
conn.Avatars.RequestAvatars([handle])
conn.Avatars.RequestAvatars([handle])
conn.Avatars.RequestAvatars([handle])
diff --git a/tests/twisted/vcard/test-avatar-tokens.py b/tests/twisted/vcard/test-avatar-tokens.py
index 59f01c092..281a733bc 100644
--- a/tests/twisted/vcard/test-avatar-tokens.py
+++ b/tests/twisted/vcard/test-avatar-tokens.py
@@ -5,7 +5,7 @@ Test GetAvatarTokens() and GetKnownAvatarTokens().
from twisted.words.xish import domish
-from servicetest import unwrap, EventPattern
+from servicetest import unwrap, assertEquals
from gabbletest import exec_test, make_result_iq
import ns
import constants as cs
@@ -41,11 +41,14 @@ def test(q, bus, conn, stream):
stream.send(make_presence('che@foo.com', None))
q.expect('dbus-signal', signal='AvatarUpdated')
- handles = conn.RequestHandles(1, [
+ handles = conn.get_contact_handles_sync([
'amy@foo.com', 'bob@foo.com', 'che@foo.com', 'daf@foo.com' ])
- tokens = unwrap(conn.Avatars.GetAvatarTokens(handles))
- assert tokens == ['SHA1SUM-FOR-AMY', 'SHA1SUM-FOR-BOB', '', '']
+ h2asv = conn.Contacts.GetContactAttributes(handles, [cs.CONN_IFACE_AVATARS], False)
+ assertEquals('SHA1SUM-FOR-AMY', h2asv[handles[0]][cs.ATTR_AVATAR_TOKEN])
+ assertEquals('SHA1SUM-FOR-BOB', h2asv[handles[1]][cs.ATTR_AVATAR_TOKEN])
+ assertEquals('', h2asv[handles[2]][cs.ATTR_AVATAR_TOKEN])
+ assertEquals(None, h2asv[handles[3]].get(cs.ATTR_AVATAR_TOKEN))
tokens = unwrap(conn.Avatars.GetKnownAvatarTokens(handles))
tokens = sorted(tokens.items())
diff --git a/tests/twisted/vcard/test-avatar.py b/tests/twisted/vcard/test-avatar.py
index f72e8edb5..834c9e7fa 100644
--- a/tests/twisted/vcard/test-avatar.py
+++ b/tests/twisted/vcard/test-avatar.py
@@ -5,9 +5,8 @@ Test avatar support.
import base64
-from servicetest import call_async, EventPattern
+from servicetest import call_async, assertEquals
from gabbletest import exec_test, acknowledge_iq, make_result_iq
-import constants as cs
def test(q, bus, conn, stream):
event = q.expect('stream-iq', to=None, query_ns='vcard-temp',
@@ -15,8 +14,8 @@ def test(q, bus, conn, stream):
acknowledge_iq(stream, event.stanza)
- handle = conn.RequestHandles(1, ['bob@foo.com'])[0]
- call_async(q, conn.Avatars, 'RequestAvatar', handle, byte_arrays=True)
+ handle = conn.get_contact_handle_sync('bob@foo.com')
+ call_async(q, conn.Avatars, 'RequestAvatars', [handle])
event = q.expect('stream-iq', iq_type='get', to='bob@foo.com',
query_ns='vcard-temp', query_name='vCard')
@@ -26,8 +25,9 @@ def test(q, bus, conn, stream):
photo.addElement('BINVAL', content=base64.b64encode('hello'))
stream.send(result)
- q.expect('dbus-return', method='RequestAvatar',
- value=('hello', 'image/png'))
+ e = q.expect('dbus-signal', signal='AvatarRetrieved')
+ assertEquals('hello', e.args[2])
+ assertEquals('image/png', e.args[3])
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/vcard/test-set-alias.py b/tests/twisted/vcard/test-set-alias.py
index 9545ef90c..8d69d5193 100644
--- a/tests/twisted/vcard/test-set-alias.py
+++ b/tests/twisted/vcard/test-set-alias.py
@@ -22,7 +22,7 @@ def validate_pep_update(pep_update, expected_nickname):
assertLength(0, nick.children)
def test(q, bus, conn, stream):
- self_handle = conn.GetSelfHandle()
+ self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")
conn.Aliasing.SetAliases({self_handle: 'lala'})
expect_and_handle_get_vcard(q, stream)
diff --git a/tests/twisted/vcard/test-vcard-cache.py b/tests/twisted/vcard/test-vcard-cache.py
index 083f5b5e1..f1cbfcd98 100644
--- a/tests/twisted/vcard/test-vcard-cache.py
+++ b/tests/twisted/vcard/test-vcard-cache.py
@@ -17,8 +17,8 @@ def test(q, bus, conn, stream):
# Request our alias and avatar, expect them to be resolved from cache.
- handle = conn.GetSelfHandle()
- call_async(q, conn.Avatars, 'RequestAvatar', handle)
+ handle = conn.Properties.Get(cs.CONN, "SelfHandle")
+ call_async(q, conn.Avatars, 'RequestAvatars', [handle])
call_async(q, conn.Aliasing, 'RequestAliases', [handle])
# FIXME - find out why RequestAliases returns before RequestAvatar even
@@ -30,15 +30,10 @@ def test(q, bus, conn, stream):
r1, r2 = q.expect_many(
EventPattern('dbus-return', method='RequestAliases'),
- EventPattern('dbus-error', method='RequestAvatar'))
+ EventPattern('dbus-return', method='RequestAvatars'))
# Default alias is our jid
assert r1.value[0] == ['test@localhost']
- # We don't have a vCard yet
- assert r2.error.get_dbus_name() == cs.NOT_AVAILABLE, \
- r2.error.get_dbus_name()
- assert r2.error.args[0] == 'contact vCard has no photo'
-
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/vcard/test-vcard-race.py b/tests/twisted/vcard/test-vcard-race.py
index 5ecd978e1..9fa61e686 100644
--- a/tests/twisted/vcard/test-vcard-race.py
+++ b/tests/twisted/vcard/test-vcard-race.py
@@ -18,6 +18,7 @@ from gabbletest import (
exec_test, expect_and_handle_get_vcard, expect_and_handle_set_vcard,
make_result_iq, sync_stream)
import ns
+import constants as cs
def test(q, bus, conn, stream):
expect_and_handle_get_vcard(q, stream)
@@ -27,7 +28,7 @@ def test(q, bus, conn, stream):
# to reply and then set immediately.
sync_stream(q, stream)
- handle = conn.GetSelfHandle()
+ handle = conn.Properties.Get(cs.CONN, "SelfHandle")
call_async(q, conn.Aliasing, 'SetAliases', {handle: 'Some Guy'})
diff --git a/tests/twisted/vcard/update-get-failed.py b/tests/twisted/vcard/update-get-failed.py
index 225b70ecf..7580f25c2 100644
--- a/tests/twisted/vcard/update-get-failed.py
+++ b/tests/twisted/vcard/update-get-failed.py
@@ -17,7 +17,7 @@ def test(q, bus, conn, stream):
# Force Gabble to process the vCard before calling any methods.
sync_stream(q, stream)
- handle = conn.GetSelfHandle()
+ handle = conn.Properties.Get(cs.CONN, "SelfHandle")
call_async(q, conn.Avatars, 'SetAvatar', 'william shatner',
'image/x-actor-name')
diff --git a/tests/twisted/version.py b/tests/twisted/version.py
index 8bd37d888..bbc2b92c9 100644
--- a/tests/twisted/version.py
+++ b/tests/twisted/version.py
@@ -4,7 +4,7 @@ Tests Gabble's implementation of XEP-0092.
"""
from twisted.words.xish import xpath
-from servicetest import assertLength, assertEquals
+from servicetest import assertLength
from gabbletest import exec_test, elem_iq, elem
import ns
diff --git a/tools/lcov.am b/tools/lcov.am
index 80023cb78..d2d282ac3 100644
--- a/tools/lcov.am
+++ b/tools/lcov.am
@@ -7,7 +7,7 @@ lcov-report:
lcov --directory @top_srcdir@ --output-file @top_builddir@/lcov.info \
--remove @top_builddir@/lcov.info.tmp telepathy-glib-scan.c
rm @top_builddir@/lcov.info.tmp
- $(mkdir_p) @top_builddir@/lcov.html
+ $(MKDIR_P) @top_builddir@/lcov.html
echo "Coming soon!" > @top_builddir@/lcov.html/index.html
git_commit=`GIT_DIR=@top_srcdir@/.git git log -1 --pretty=format:%h 2>/dev/null`;\
genhtml --title "@PACKAGE_STRING@ $$git_commit" \