summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am2
-rw-r--r--NEWS54
-rw-r--r--configure.ac38
-rw-r--r--extensions/Channel_Type_FileTransfer_Future.xml67
-rw-r--r--extensions/Connection_Future.xml110
-rw-r--r--extensions/Connection_Interface_Addressing.xml245
-rw-r--r--extensions/Gabble_Plugin_Console.xml2
-rw-r--r--extensions/Makefile.am5
-rw-r--r--extensions/all.xml15
m---------lib/ext/wocky0
-rw-r--r--lib/gibber/gibber-debug.c4
-rw-r--r--lib/gibber/gibber-debug.h16
-rw-r--r--plugins/Makefile.am11
-rw-r--r--plugins/console/channel-manager.c279
-rw-r--r--plugins/console/channel-manager.h52
-rw-r--r--plugins/console/channel.c (renamed from plugins/console.c)299
-rw-r--r--plugins/console/channel.h53
-rw-r--r--plugins/console/debug.c (renamed from src/legacy-caps.c)36
-rw-r--r--plugins/console/debug.h (renamed from src/legacy-caps.h)34
-rw-r--r--plugins/console/plugin.c91
-rw-r--r--plugins/console/plugin.h (renamed from plugins/console.h)37
-rwxr-xr-xplugins/telepathy-gabble-xmpp-console163
-rw-r--r--plugins/test.c1
-rw-r--r--src/Makefile.am8
-rw-r--r--src/call-stream.c4
-rw-r--r--src/conn-addressing.c18
-rw-r--r--src/conn-aliasing.c55
-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-location.c53
-rw-r--r--src/conn-mail-notif.c4
-rw-r--r--src/conn-sidecars.c14
-rw-r--r--src/conn-sidecars.h2
-rw-r--r--src/connection.c393
-rw-r--r--src/connection.h9
-rw-r--r--src/debug.h36
-rw-r--r--src/ft-channel.c19
-rw-r--r--src/ft-manager.c11
-rw-r--r--src/gabble.c8
-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.c515
-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/plugin-loader.c9
-rw-r--r--src/private-tubes-factory.c176
-rw-r--r--src/private-tubes-factory.h4
-rw-r--r--src/protocol.c23
-rw-r--r--src/roster.c498
-rw-r--r--src/search-channel.c23
-rw-r--r--src/server-sasl-channel.c2
-rw-r--r--src/server-tls-manager.c14
-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.am48
-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/test-twice.py26
-rw-r--r--tests/twisted/console.py28
-rw-r--r--tests/twisted/constants.py161
-rw-r--r--tests/twisted/dataforms.py6
-rw-r--r--tests/twisted/file-transfer/file_transfer_helper.py17
-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.py13
-rw-r--r--tests/twisted/jingle-share/file_transfer_helper.py21
-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.py64
-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.py54
-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.py193
-rw-r--r--tests/twisted/run-test.sh.in4
-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.py226
-rw-r--r--tests/twisted/sidecar-own-caps.py7
-rw-r--r--tests/twisted/sidecars.py22
-rw-r--r--tests/twisted/test-debug.py41
-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/c-constants-gen.py12
-rw-r--r--tools/glib-client-gen.py94
-rw-r--r--tools/glib-client-marshaller-gen.py20
-rw-r--r--tools/glib-errors-check-gen.py62
-rw-r--r--tools/glib-errors-str-gen.py14
-rw-r--r--tools/glib-ginterface-gen.py22
-rw-r--r--tools/glib-gtypes-generator.py14
-rw-r--r--tools/glib-interfaces-gen.py14
-rw-r--r--tools/gobject-foo.py2
-rw-r--r--tools/lcov.am2
-rw-r--r--tools/libglibcodegen.py27
-rw-r--r--tools/libtpcodegen.py22
-rw-r--r--tools/make-version-script.py32
-rw-r--r--tools/xincludator.py13
271 files changed, 3514 insertions, 16745 deletions
diff --git a/.gitignore b/.gitignore
index 9c42dc2..bb2a5be 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/Makefile.am b/Makefile.am
index 288478b..516610d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,7 +2,7 @@ ACLOCAL_AMFLAGS = -I m4
SUBDIRS = docs tools extensions lib src data m4 plugins tests gabble
-DISTCHECK_CONFIGURE_FLAGS = --disable-debug --enable-gtk-doc
+DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
CLEANFILES = FIXME.out
diff --git a/NEWS b/NEWS
index 8f2d6c8..89c34e7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,57 @@
+telepathy-gabble 0.19.0 (UNRELEASED)
+====================================
+
+The “very confused owl” release.
+
+Compile-time configuration:
+
+• The --disable-debug option has gone away. The new configuration is
+ equivalent to --enable-debug.
+
+Dependencies:
+
+• telepathy-glib ≥ 0.23.0 is required
+
+• Autoconf 2.60 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)
+
+• Improve XMPP console (fd.o #66085, Will)
+
+Fixes:
+
+• Stop claiming to implement legacy Presence, which was deleted in 2011
+ (fd.o #69194, Guillaume)
+
+• Use the correct capability token to control whether we advertise ICE-UDP
+ support (Guillaume)
+
+• Implement RequestClientTypes (fd.o #70134, Guillaume)
+
+• Correct the type of private tubes' IDs, fixing a crash on 64-bit platforms
+ (fd.o #70038, Guillaume)
+
+• Use telepathy-glib to implement Addressing, Sidecars1,
+ FileTransfer.FileCollection (fd.o #26609, #69817; Simon)
+
+• Implement Protocol.I.Avatars correctly (Guillaume)
+
+Internal changes:
+
+• Fix various deprecated things (fd.o #69194, #69618, #69767, #70045;
+ Simon, Guillaume)
+
+• Improved regression test coverage (fd.o #69474, Simon)
+
+• Remove regression tests for obsolete APIs to reduce delta between
+ 0.20 and 1.0 branches (Simon, Guillaume)
+
telepathy-gabble 0.18.1 (2013-09-06)
====================================
diff --git a/configure.ac b/configure.ac
index bde9a51..2d4f118 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:
@@ -9,7 +9,7 @@ AC_PREREQ([2.59])
m4_define([gabble_major_version], [0])
m4_define([gabble_minor_version], [18])
-m4_define([gabble_micro_version], [1])
+m4_define([gabble_micro_version], [999])
m4_define([gabble_nano_version], [1])
# Some magic
@@ -23,8 +23,9 @@ 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])
+AM_INIT_AUTOMAKE([1.9 -Wno-portability tar-ustar subdir-objects])
AM_CONFIG_HEADER(config.h)
AC_USE_SYSTEM_EXTENSIONS
@@ -93,7 +94,6 @@ TP_COMPILER_WARNINGS([ERROR_CFLAGS], [test "x$official_release" = xno],
format-security \
init-self],
[missing-field-initializers \
- deprecated-declarations \
unused-parameter])
AC_SUBST([ERROR_CFLAGS])
@@ -149,10 +149,6 @@ if test -n "$with_ca_certificates"; then
fi
fi
-AC_ARG_ENABLE(debug,
- AC_HELP_STRING([--disable-debug],[compile without debug code]),
- enable_debug=$enableval, enable_debug=yes )
-
ifelse(gabble_nano_version, 0,
[ # Gabble is version x.y.z - disable coding style checks by default
AC_ARG_ENABLE(coding-style-checks,
@@ -167,11 +163,6 @@ AC_ARG_ENABLE(coding-style-checks,
[ENABLE_CODING_STYLE_CHECKS=$enableval], [ENABLE_CODING_STYLE_CHECKS=yes])
])
-if test x$enable_debug = xyes; then
- AC_DEFINE(ENABLE_DEBUG, [], [Enable debug code])
-fi
-AM_CONDITIONAL([ENABLE_DEBUG], [test "x$enable_debug" = xyes])
-
AC_SUBST([ENABLE_CODING_STYLE_CHECKS])
AC_ARG_ENABLE([installed-tests],
@@ -228,7 +219,7 @@ PKG_CHECK_MODULES(GLIB,
[glib-2.0 >= 2.32, gobject-2.0, gthread-2.0, gio-2.0])
PKG_CHECK_MODULES(GMODULE, [gmodule-2.0 >= 2.32])
-AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_30, [Ignore post 2.30 deprecations])
+AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_32, [Ignore post 2.32 deprecations])
AC_DEFINE(GLIB_VERSION_MAX_ALLOWED, GLIB_VERSION_2_32, [Prevent post 2.32 APIs])
AC_SUBST(GLIB_CFLAGS)
@@ -279,17 +270,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])
@@ -298,9 +278,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_24], [Ignore post 0.24 deprecations])
+AC_DEFINE([TP_VERSION_MAX_ALLOWED], [TP_VERSION_0_24], [Prevent post 0.24 APIs])
+PKG_CHECK_MODULES(TP_GLIB, [telepathy-glib >= 0.23.2])
AC_SUBST(TP_GLIB_CFLAGS)
AC_SUBST(TP_GLIB_LIBS)
@@ -462,7 +442,6 @@ Configure summary:
Compiler Flags..............: ${CFLAGS} ${ERROR_CFLAGS}
Prefix......................: ${prefix}
Coding style checks.........: ${ENABLE_CODING_STYLE_CHECKS}
- Enable debug................: ${enable_debug}
Python tests................: ${tests_enabled}
Install unit tests..........: ${installed_tests}
@@ -471,7 +450,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/Channel_Type_FileTransfer_Future.xml b/extensions/Channel_Type_FileTransfer_Future.xml
deleted file mode 100644
index b155136..0000000
--- a/extensions/Channel_Type_FileTransfer_Future.xml
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" ?>
-<node name="/Channel_Type_FileTransfer_Future"
- xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
- <tp:copyright>Copyright (C) 2010 Collabora Ltd.</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.Channel.Type.FileTransfer.FUTURE"
- tp:causes-havoc="a staging area for future File Transfer Channel functionality">
-
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>This interface contains functionality which we intend to incorporate
- into the File Transfer Channel interface in future.
- It should be considered to be conceptually part of the core
- File Transfer Channel interface, but without API or ABI guarantees.</p>
-
- <tp:rationale>
- <p>If we add new functionality to the Channel interface, libraries
- that use generated code (notably telepathy-glib) will have it as
- part of their ABI forever, meaning we can't make incompatible
- changes. By using this interface as a staging area for future
- Channel functionality, we can try out new properties, signals
- and methods as application-specific extensions, then merge them
- into the core Channel interface when we have enough implementation
- experience to declare them to be stable.</p>
-
- <p>The name is by analogy to Python's <code>__future__</code>
- pseudo-module.</p>
- </tp:rationale>
- </tp:docstring>
-
- <property name="FileCollection" tp:name-for-bindings="FileCollection"
- type="s" access="read">
- <tp:added version="0.19.2">(in Channel.Type.FileTransfer.FUTURE
- pseudo-interface)</tp:added>
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>The FileCollection to which this channel belongs.</p>
-
- <p>A channel's FileCollection property can never change.</p>
-
- <p>At least on GTalk and apparently also on iChat the user can
- send a set of files to a contact and that contact can then
- pick and choose which files to actually receive.
-
- The CM should emit all new FT channels belonging to one collection
- at the same time, UIs supporting this feature can then
- bundle all these channels together in some way and show a
- nice UI. UIs not supporting it will treat them as seperate
- transfers, which is not great but a reasonable fallback</p>
- </tp:docstring>
- </property>
-
- </interface>
-</node>
-<!-- vim:set sw=2 sts=2 et ft=xml: -->
diff --git a/extensions/Connection_Future.xml b/extensions/Connection_Future.xml
deleted file mode 100644
index 1104798..0000000
--- a/extensions/Connection_Future.xml
+++ /dev/null
@@ -1,110 +0,0 @@
-<?xml version="1.0" ?>
-<node name="/Connection_FUTURE"
- xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"
- >
- <tp:copyright>Copyright © 2009 Collabora Limited</tp:copyright>
- <tp:copyright>Copyright © 2009 Nokia Corporation</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.FUTURE"
- tp:causes-havoc='experimental'>
- <tp:requires interface="org.freedesktop.Telepathy.Connection"/>
-
- <method name="EnsureSidecar" tp:name-for-bindings="Ensure_Sidecar">
- <tp:added version="0.19.UNRELEASED"/>
-
- <arg direction="in" name="Main_Interface" type="s"
- tp:type="DBus_Interface">
- <tp:docstring>
- The "primary" interface implemented by an object attached
- to a connection. For example, a Gabble plugin implementing
- fine-grained control of XEP-0016 privacy lists might expose an object
- implementing <tt>com.example.PrivacyLists</tt>.
- </tp:docstring>
- </arg>
-
- <arg direction="out" name="Path" type="o">
- <tp:docstring>The object path of the sidecar, exported by the same bus
- name as the Connection to which it is attached.</tp:docstring>
- </arg>
- <arg direction="out" name="Properties" type="a{sv}"
- tp:type="Qualified_Property_Value_Map">
- <tp:docstring>Immutable properties of the sidecar.</tp:docstring>
- </arg>
-
- <tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>Request an object with a particular interface providing additional
- connection-specific functionality, together with its immutable
- properties. These will often be implemented by plug-ins to the
- connection managers; for example, support for an XMPP XEP for which
- no generic Telepathy interface exists might be implemented by a
- Gabble plugin exposing a sidecar with a particular interface.</p>
-
- <p>This method may be called at any point during the lifetime of a
- connection, even before its <tp:type>Connection_Status</tp:type>
- changes to Connected. It MAY take a long time to
- return—perhaps it needs to wait for a connection to be established
- and for all the services supported by the server to be discovered
- before determining whether necessary server-side support is
- available—so callers SHOULD override the default method timeout (25
- seconds) with a much higher value (perhaps even MAX_INT32, meaning
- “no timeout” in recent versions of libdbus).</p>
-
- <tp:rationale>
- <p>There is an implicit assumption that any connection
- manager plugin will only want to export one “primary” object per
- feature it implements, since there is a one-to-one mapping between
- interface and object. This is reasonable since Sidecars are
- (intended to be) analogous to extra interfaces on the connection,
- providing once-per-connection shared functionality; it also makes
- client code straightforward (look up the interface you care about
- in a dictionary, build a proxy object from the value). More
- “plural” plugins are likely to want to implement new types of
- <tp:dbus-ref
- namespace="org.freedesktop.Telepathy">Channel</tp:dbus-ref>
- instead.</p>
- </tp:rationale>
- </tp:docstring>
-
- <tp:error name="org.freedesktop.Telepathy.Error.NotImplemented">
- <tp:docstring>
- The requested sidecar is not implemented by this connection manager,
- or a necessary server-side component does not exist. (FIXME: split
- these two errors out? Then again, once we list the guaranteed and
- possible sidecars on a Protocol object, clients can tell the
- difference themselves, because they shouldn't be calling this in the
- first case.)
- </tp:docstring>
- </tp:error>
-
- <tp:error name="org.freedesktop.Telepathy.Error.ServiceBusy">
- <tp:docstring>
- A server-side component needed by the requested sidecar reported it
- is currently too busy, or did not respond for some
- implementation-defined time. The caller may wish to try again later.
- </tp:docstring>
- </tp:error>
-
- <tp:error name="org.freedesktop.Telepathy.Error.Cancelled">
- <tp:docstring>
- The connection was disconnected while the sidecar was being set up.
- </tp:docstring>
- </tp:error>
- </method>
-
- </interface>
-</node>
diff --git a/extensions/Connection_Interface_Addressing.xml b/extensions/Connection_Interface_Addressing.xml
deleted file mode 100644
index 2d8145f..0000000
--- 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/Gabble_Plugin_Console.xml b/extensions/Gabble_Plugin_Console.xml
index 1e3b523..a2d94ca 100644
--- a/extensions/Gabble_Plugin_Console.xml
+++ b/extensions/Gabble_Plugin_Console.xml
@@ -23,7 +23,7 @@
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
value="true"/>
<tp:docstring xmlns="http://www.w3.org/1999/xhtml">
- <p>A sidecar interface providing an XMPP console.</p>
+ <p>A channel type providing an XMPP console.</p>
</tp:docstring>
<method name="SendIQ" tp:name-for-bindings="Send_IQ">
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index b435ae3..70210ad 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -2,9 +2,6 @@ tools_dir = $(top_srcdir)/tools
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 +46,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 99997d6..b7c3174 100644
--- a/extensions/all.xml
+++ b/extensions/all.xml
@@ -33,14 +33,10 @@ 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"/>
-<xi:include href="Channel_Type_FileTransfer_Future.xml"/>
<xi:include href="Connection_Interface_Gabble_Decloak.xml"/>
-<xi:include href="Connection_Future.xml"/>
<xi:include href="Gabble_Plugin_Console.xml"/>
<xi:include href="Gabble_Plugin_Gateways.xml"/>
@@ -108,17 +104,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 0db9f32fd023fc728abf1780c26b957102c3292
+Subproject c5932733128be4bfb1d5b0ce9be5b136746266d
diff --git a/lib/gibber/gibber-debug.c b/lib/gibber/gibber-debug.c
index 29b74f4..69cf1a6 100644
--- a/lib/gibber/gibber-debug.c
+++ b/lib/gibber/gibber-debug.c
@@ -6,8 +6,6 @@
#include "gibber-debug.h"
-#ifdef ENABLE_DEBUG
-
static DebugFlags flags = 0;
static gboolean initialized = FALSE;
@@ -96,5 +94,3 @@ gibber_debug_stanza (DebugFlags flag,
}
}
#endif
-
-#endif
diff --git a/lib/gibber/gibber-debug.h b/lib/gibber/gibber-debug.h
index 8c813bd..7bc7f18 100644
--- a/lib/gibber/gibber-debug.h
+++ b/lib/gibber/gibber-debug.h
@@ -12,8 +12,6 @@
G_BEGIN_DECLS
-#ifdef ENABLE_DEBUG
-
typedef enum
{
DEBUG_TRANSPORT = 1 << 0,
@@ -59,20 +57,6 @@ void gibber_debug_stanza (DebugFlags flag, GibberXmppStanza *stanza,
#endif /* DEBUG_FLAG */
-#else /* ENABLE_DEBUG */
-
-#ifdef DEBUG_FLAG
-
-#define DEBUG(format, ...) G_STMT_START { } G_STMT_END
-
-#define DEBUG_STANZA(stanza, format, ...) G_STMT_START { } G_STMT_END
-
-#define DEBUGGING (0)
-
-#endif /* DEBUG_FLAG */
-
-#endif /* ENABLE_DEBUG */
-
G_END_DECLS
#endif
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index a511604..2b00079 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -62,8 +62,15 @@ libgateways_la_SOURCES = \
gateways.h
libconsole_la_SOURCES = \
- console.c \
- console.h
+ console/channel-manager.c \
+ console/channel-manager.h \
+ console/channel.c \
+ console/channel.h \
+ console/debug.c \
+ console/debug.h \
+ console/plugin.c \
+ console/plugin.h \
+ $(NULL)
AM_CFLAGS = $(ERROR_CFLAGS) \
-I $(top_srcdir) -I $(top_builddir) \
diff --git a/plugins/console/channel-manager.c b/plugins/console/channel-manager.c
new file mode 100644
index 0000000..2f49552
--- /dev/null
+++ b/plugins/console/channel-manager.c
@@ -0,0 +1,279 @@
+/* XML console plugin
+ *
+ * Copyright © 2011–2013 Collabora Ltd. <http://www.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 "console/channel-manager.h"
+
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#include "extensions/extensions.h"
+#include "console/channel.h"
+
+static void channel_manager_iface_init (gpointer, gpointer);
+
+G_DEFINE_TYPE_WITH_CODE (GabbleConsoleChannelManager, gabble_console_channel_manager,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER, channel_manager_iface_init)
+ G_IMPLEMENT_INTERFACE (GABBLE_TYPE_CAPS_CHANNEL_MANAGER, NULL);
+ )
+
+enum {
+ PROP_CONNECTION = 1,
+};
+
+static void connection_status_changed_cb (
+ TpBaseConnection *conn,
+ guint status,
+ guint reason,
+ GabbleConsoleChannelManager *self);
+static void gabble_console_channel_manager_close_all (
+ GabbleConsoleChannelManager *self);
+
+static void
+gabble_console_channel_manager_init (GabbleConsoleChannelManager *self)
+{
+ g_weak_ref_init (&self->plugin_connection_ref, NULL);
+}
+
+
+static void
+gabble_console_channel_manager_constructed (GObject *object)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+ GabblePluginConnection *plugin_connection;
+
+ G_OBJECT_CLASS (gabble_console_channel_manager_parent_class)->constructed (object);
+
+ plugin_connection = g_weak_ref_get (&self->plugin_connection_ref);
+ if (plugin_connection != NULL)
+ {
+ g_signal_connect_object (plugin_connection, "status-changed",
+ G_CALLBACK (connection_status_changed_cb), self, 0);
+ g_object_unref (plugin_connection);
+ }
+}
+
+
+static void
+gabble_console_channel_manager_set_property (
+ GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+
+ switch (property_id)
+ {
+ case PROP_CONNECTION:
+ g_weak_ref_set (&self->plugin_connection_ref, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+gabble_console_channel_manager_get_property (
+ GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+
+ switch (property_id)
+ {
+ case PROP_CONNECTION:
+ g_value_take_object (value, g_weak_ref_get (&self->plugin_connection_ref));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+
+static void
+gabble_console_channel_manager_dispose (
+ GObject *object)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (object);
+
+ gabble_console_channel_manager_close_all (self);
+ g_weak_ref_clear (&self->plugin_connection_ref);
+
+ G_OBJECT_CLASS (gabble_console_channel_manager_parent_class)->dispose (object);
+}
+
+
+static void
+connection_status_changed_cb (
+ TpBaseConnection *conn,
+ guint status,
+ guint reason,
+ GabbleConsoleChannelManager *self)
+{
+ switch (status)
+ {
+ case TP_CONNECTION_STATUS_DISCONNECTED:
+ gabble_console_channel_manager_close_all (self);
+ break;
+
+ default:
+ return;
+ }
+}
+
+static void
+gabble_console_channel_manager_close_all (
+ GabbleConsoleChannelManager *self)
+{
+ TpBaseChannel *channel;
+
+ while ((channel = g_queue_peek_head (&self->console_channels)) != NULL)
+ {
+ tp_base_channel_close (channel);
+ }
+}
+
+
+static void
+gabble_console_channel_manager_class_init (GabbleConsoleChannelManagerClass *klass)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+
+ oclass->constructed = gabble_console_channel_manager_constructed;
+ oclass->set_property = gabble_console_channel_manager_set_property;
+ oclass->get_property = gabble_console_channel_manager_get_property;
+ oclass->dispose = gabble_console_channel_manager_dispose;
+
+ g_object_class_install_property (oclass, PROP_CONNECTION,
+ g_param_spec_object ("plugin-connection", "Gabble Plugin Connection",
+ "Gabble Plugin Connection",
+ GABBLE_TYPE_PLUGIN_CONNECTION,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+}
+
+
+static const gchar * const allowed[] = {
+ TP_PROP_CHANNEL_CHANNEL_TYPE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+ NULL
+};
+
+static void
+gabble_console_channel_manager_type_foreach_channel_class (GType type,
+ TpChannelManagerTypeChannelClassFunc func,
+ gpointer user_data)
+{
+ GHashTable *table = tp_asv_new (
+ TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_NONE,
+ NULL);
+
+ func (type, table, NULL, user_data);
+
+ g_hash_table_unref (table);
+}
+
+
+static void
+console_channel_closed_cb (
+ GabbleConsoleChannel *channel,
+ gpointer user_data)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (user_data);
+
+ tp_channel_manager_emit_channel_closed_for_object (self,
+ TP_EXPORTABLE_CHANNEL (channel));
+
+ if (g_queue_remove (&self->console_channels, channel))
+ {
+ g_object_unref (channel);
+ }
+}
+
+
+static gboolean
+gabble_console_channel_manager_create_channel (
+ TpChannelManager *manager,
+ gpointer request_token,
+ GHashTable *request_properties)
+{
+ GabbleConsoleChannelManager *self = GABBLE_CONSOLE_CHANNEL_MANAGER (manager);
+ GabblePluginConnection *connection;
+ TpBaseChannel *channel = NULL;
+ GError *error = NULL;
+ GSList *request_tokens;
+
+ if (tp_strdiff (tp_asv_get_string (request_properties,
+ TP_IFACE_CHANNEL ".ChannelType"),
+ GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE))
+ return FALSE;
+
+ if (tp_asv_get_uint32 (request_properties,
+ TP_IFACE_CHANNEL ".TargetHandleType", NULL) != 0)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED,
+ "Console channels can't have a target handle");
+ goto error;
+ }
+
+ if (tp_channel_manager_asv_has_unknown_properties (request_properties,
+ allowed,
+ allowed,
+ &error))
+ goto error;
+
+ connection = g_weak_ref_get (&self->plugin_connection_ref);
+ g_return_val_if_fail (connection != NULL, FALSE);
+
+ channel = g_object_new (GABBLE_TYPE_CONSOLE_CHANNEL,
+ "connection", connection,
+ NULL);
+ tp_base_channel_register (channel);
+ g_signal_connect (channel, "closed", (GCallback) console_channel_closed_cb,
+ self);
+ g_queue_push_tail (&self->console_channels, channel);
+
+ request_tokens = g_slist_prepend (NULL, request_token);
+ tp_channel_manager_emit_new_channel (self,
+ TP_EXPORTABLE_CHANNEL (channel), request_tokens);
+ g_slist_free (request_tokens);
+
+ g_object_unref (connection);
+ 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 void
+channel_manager_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ TpChannelManagerIface *iface = g_iface;
+
+ iface->type_foreach_channel_class = gabble_console_channel_manager_type_foreach_channel_class;
+ iface->create_channel = gabble_console_channel_manager_create_channel;
+}
diff --git a/plugins/console/channel-manager.h b/plugins/console/channel-manager.h
new file mode 100644
index 0000000..5e7a8b9
--- /dev/null
+++ b/plugins/console/channel-manager.h
@@ -0,0 +1,52 @@
+/* XML console plugin
+ *
+ * Copyright © 2011–2013 Collabora Ltd. <http://www.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 <glib-object.h>
+#include <gabble/gabble.h>
+
+typedef struct _GabbleConsoleChannelManager GabbleConsoleChannelManager;
+typedef struct _GabbleConsoleChannelManagerClass GabbleConsoleChannelManagerClass;
+
+struct _GabbleConsoleChannelManagerClass {
+ GObjectClass parent_class;
+};
+
+struct _GabbleConsoleChannelManager {
+ GObject parent;
+
+ GWeakRef plugin_connection_ref;
+ GQueue console_channels;
+};
+
+GType gabble_console_channel_manager_get_type (void);
+
+#define GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER \
+ (gabble_console_channel_manager_get_type ())
+#define GABBLE_CONSOLE_CHANNEL_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER, GabbleConsoleChannelManager))
+#define GABBLE_CONSOLE_CHANNEL_MANAGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER,\
+ GabbleConsoleChannelManagerClass))
+#define GABBLE_IS_CONSOLE_CHANNEL_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER))
+#define GABBLE_IS_CONSOLE_CHANNEL_MANAGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER))
+#define GABBLE_CONSOLE_CHANNEL_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER,\
+ GabbleConsoleChannelManagerClass))
diff --git a/plugins/console.c b/plugins/console/channel.c
index fd49d0b..3ddbef9 100644
--- a/plugins/console.c
+++ b/plugins/console/channel.c
@@ -18,156 +18,27 @@
*/
#include "config.h"
-
-#include "console.h"
+#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 "extensions/extensions.h"
-
#include <gabble/gabble.h>
+#include "extensions/extensions.h"
-/*************************
- * Plugin implementation *
- *************************/
-
-static guint debug = 0;
-
-#define DEBUG(format, ...) \
-G_STMT_START { \
- if (debug != 0) \
- g_debug ("%s: " format, G_STRFUNC, ## __VA_ARGS__); \
-} G_STMT_END
-
-static const GDebugKey debug_keys[] = {
- { "console", 1 },
- { NULL, 0 }
-};
-
-static void plugin_iface_init (
- gpointer g_iface,
- gpointer data);
-
-static const gchar * const sidecar_interfaces[] = {
- GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE,
- NULL
-};
-
-G_DEFINE_TYPE_WITH_CODE (GabbleConsolePlugin, gabble_console_plugin,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GABBLE_TYPE_PLUGIN, plugin_iface_init);
- )
-
-static void
-gabble_console_plugin_init (GabbleConsolePlugin *self)
-{
-}
-
-static void
-gabble_console_plugin_class_init (GabbleConsolePluginClass *klass)
-{
-}
-
-static void
-gabble_console_plugin_create_sidecar_async (
- GabblePlugin *plugin,
- const gchar *sidecar_interface,
- GabblePluginConnection *connection,
- WockySession *session,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (plugin),
- callback, user_data,
- gabble_console_plugin_create_sidecar_async);
- GabbleSidecar *sidecar = NULL;
-
- if (!tp_strdiff (sidecar_interface, GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE))
- {
- sidecar = g_object_new (GABBLE_TYPE_CONSOLE_SIDECAR,
- "connection", connection,
- "session", session,
- NULL);
- }
- else
- {
- g_simple_async_result_set_error (result, TP_ERROR,
- TP_ERROR_NOT_IMPLEMENTED, "'%s' not implemented", sidecar_interface);
- }
-
- if (sidecar != NULL)
- g_simple_async_result_set_op_res_gpointer (result, sidecar,
- g_object_unref);
-
- g_simple_async_result_complete_in_idle (result);
- g_object_unref (result);
-}
-
-static GabbleSidecar *
-gabble_console_plugin_create_sidecar_finish (
- GabblePlugin *plugin,
- GAsyncResult *result,
- GError **error)
-{
- GabbleSidecar *sidecar;
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
- error))
- return NULL;
-
- g_return_val_if_fail (g_simple_async_result_is_valid (result,
- G_OBJECT (plugin), gabble_console_plugin_create_sidecar_async), NULL);
-
- sidecar = GABBLE_SIDECAR (g_simple_async_result_get_op_res_gpointer (
- G_SIMPLE_ASYNC_RESULT (result)));
-
- return g_object_ref (sidecar);
-}
-
-static void
-plugin_iface_init (
- gpointer g_iface,
- gpointer data G_GNUC_UNUSED)
-{
- GabblePluginInterface *iface = g_iface;
-
- iface->name = "XMPP console";
- iface->version = PACKAGE_VERSION;
- iface->sidecar_interfaces = sidecar_interfaces;
- iface->create_sidecar_async = gabble_console_plugin_create_sidecar_async;
- iface->create_sidecar_finish = gabble_console_plugin_create_sidecar_finish;
-}
-
-GabblePlugin *
-gabble_plugin_create (void)
-{
- debug = g_parse_debug_string (g_getenv ("GABBLE_DEBUG"), debug_keys,
- G_N_ELEMENTS (debug_keys) - 1);
- DEBUG ("loaded");
-
- return g_object_new (GABBLE_TYPE_CONSOLE_PLUGIN,
- NULL);
-}
-
-/**************************
- * Sidecar implementation *
- **************************/
+#include "console/debug.h"
enum {
PROP_0,
- PROP_CONNECTION,
- PROP_SESSION,
PROP_SPEW
};
-struct _GabbleConsoleSidecarPrivate
+struct _GabbleConsoleChannelPrivate
{
WockySession *session;
- TpBaseConnection *connection;
WockyXmppReader *reader;
WockyXmppWriter *writer;
@@ -182,43 +53,58 @@ struct _GabbleConsoleSidecarPrivate
gulong sending_id;
};
-static void sidecar_iface_init (
- gpointer g_iface,
- gpointer data);
static void console_iface_init (
gpointer g_iface,
gpointer data);
-static void gabble_console_sidecar_set_spew (
- GabbleConsoleSidecar *self,
+static void gabble_console_channel_set_spew (
+ GabbleConsoleChannel *self,
gboolean spew);
+gchar *gabble_console_channel_get_path (TpBaseChannel *chan);
+static void gabble_console_channel_close (TpBaseChannel *chan);
-G_DEFINE_TYPE_WITH_CODE (GabbleConsoleSidecar, gabble_console_sidecar,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SIDECAR, sidecar_iface_init);
+G_DEFINE_TYPE_WITH_CODE (GabbleConsoleChannel, gabble_console_channel,
+ TP_TYPE_BASE_CHANNEL,
G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_GABBLE_PLUGIN_CONSOLE,
console_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init);
)
static void
-gabble_console_sidecar_init (GabbleConsoleSidecar *self)
+gabble_console_channel_init (GabbleConsoleChannel *self)
{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GABBLE_TYPE_CONSOLE_SIDECAR,
- GabbleConsoleSidecarPrivate);
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GABBLE_TYPE_CONSOLE_CHANNEL,
+ GabbleConsoleChannelPrivate);
self->priv->reader = wocky_xmpp_reader_new_no_stream_ns (
WOCKY_XMPP_NS_JABBER_CLIENT);
self->priv->writer = wocky_xmpp_writer_new_no_stream ();
}
+
+static void
+gabble_console_channel_constructed (GObject *object)
+{
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (object);
+ void (*chain_up)(GObject *) =
+ G_OBJECT_CLASS (gabble_console_channel_parent_class)->constructed;
+
+ if (chain_up != NULL)
+ chain_up (object);
+
+ self->priv->session = g_object_ref (
+ gabble_plugin_connection_get_session (
+ GABBLE_PLUGIN_CONNECTION (
+ tp_base_channel_get_connection (
+ TP_BASE_CHANNEL (self)))));
+ g_return_if_fail (self->priv->session != NULL);
+}
+
static void
-gabble_console_sidecar_get_property (
+gabble_console_channel_get_property (
GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (object);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (object);
switch (property_id)
{
@@ -232,28 +118,18 @@ gabble_console_sidecar_get_property (
}
static void
-gabble_console_sidecar_set_property (
+gabble_console_channel_set_property (
GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (object);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (object);
switch (property_id)
{
- case PROP_CONNECTION:
- g_assert (self->priv->connection == NULL); /* construct-only */
- self->priv->connection = g_value_dup_object (value);
- break;
-
- case PROP_SESSION:
- g_assert (self->priv->session == NULL); /* construct-only */
- self->priv->session = g_value_dup_object (value);
- break;
-
case PROP_SPEW:
- gabble_console_sidecar_set_spew (self, g_value_get_boolean (value));
+ gabble_console_channel_set_spew (self, g_value_get_boolean (value));
break;
default:
@@ -262,15 +138,14 @@ gabble_console_sidecar_set_property (
}
static void
-gabble_console_sidecar_dispose (GObject *object)
+gabble_console_channel_dispose (GObject *object)
{
void (*chain_up) (GObject *) =
- G_OBJECT_CLASS (gabble_console_sidecar_parent_class)->dispose;
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (object);
+ G_OBJECT_CLASS (gabble_console_channel_parent_class)->dispose;
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (object);
- gabble_console_sidecar_set_spew (self, FALSE);
+ gabble_console_channel_set_spew (self, FALSE);
- tp_clear_object (&self->priv->connection);
tp_clear_object (&self->priv->reader);
tp_clear_object (&self->priv->writer);
tp_clear_object (&self->priv->session);
@@ -280,46 +155,25 @@ gabble_console_sidecar_dispose (GObject *object)
}
static void
-gabble_console_sidecar_class_init (GabbleConsoleSidecarClass *klass)
+gabble_console_channel_class_init (GabbleConsoleChannelClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ TpBaseChannelClass *channel_class = TP_BASE_CHANNEL_CLASS (klass);
static TpDBusPropertiesMixinPropImpl console_props[] = {
{ "SpewStanzas", "spew-stanzas", "spew-stanzas" },
{ NULL },
};
- static TpDBusPropertiesMixinIfaceImpl interfaces[] = {
- { GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE,
- tp_dbus_properties_mixin_getter_gobject_properties,
- /* FIXME: if we were feeling clever, we'd override the setter so that
- * we can monitor the bus name of any application which sets
- * SpewStanzas to TRUE and flip it back to false when that application
- * dies.
- *
- * Alternatively, we could just replace this sidecar with a channel.
- */
- tp_dbus_properties_mixin_setter_gobject_properties,
- console_props
- },
- { NULL },
- };
-
- object_class->get_property = gabble_console_sidecar_get_property;
- object_class->set_property = gabble_console_sidecar_set_property;
- object_class->dispose = gabble_console_sidecar_dispose;
- g_type_class_add_private (klass, sizeof (GabbleConsoleSidecarPrivate));
+ object_class->constructed = gabble_console_channel_constructed;
+ object_class->get_property = gabble_console_channel_get_property;
+ object_class->set_property = gabble_console_channel_set_property;
+ object_class->dispose = gabble_console_channel_dispose;
- g_object_class_install_property (object_class, PROP_CONNECTION,
- g_param_spec_object ("connection", "Connection",
- "Gabble connection",
- GABBLE_TYPE_PLUGIN_CONNECTION,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ channel_class->channel_type = GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE;
+ channel_class->get_object_path_suffix = gabble_console_channel_get_path;
+ channel_class->close = gabble_console_channel_close;
- g_object_class_install_property (object_class, PROP_SESSION,
- g_param_spec_object ("session", "Session",
- "Wocky session",
- WOCKY_TYPE_SESSION,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ g_type_class_add_private (klass, sizeof (GabbleConsoleChannelPrivate));
g_object_class_install_property (object_class, PROP_SPEW,
g_param_spec_boolean ("spew-stanzas", "SpewStanzas",
@@ -327,19 +181,26 @@ gabble_console_sidecar_class_init (GabbleConsoleSidecarClass *klass)
FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- klass->props_class.interfaces = interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (GabbleConsoleSidecarClass, props_class));
+ tp_dbus_properties_mixin_implement_interface (object_class,
+ GABBLE_IFACE_QUARK_GABBLE_PLUGIN_CONSOLE,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ tp_dbus_properties_mixin_setter_gobject_properties,
+ console_props);
}
-static void sidecar_iface_init (
- gpointer g_iface,
- gpointer data)
+gchar *
+gabble_console_channel_get_path (TpBaseChannel *chan)
+{
+ return g_strdup_printf ("console%p", chan);
+}
+
+static void
+gabble_console_channel_close (TpBaseChannel *chan)
{
- GabbleSidecarInterface *iface = g_iface;
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (chan);
- iface->interface = GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE;
- iface->get_immutable_properties = NULL;
+ gabble_console_channel_set_spew (self, FALSE);
+ tp_base_channel_destroyed (chan);
}
static gboolean
@@ -348,7 +209,7 @@ incoming_cb (
WockyStanza *stanza,
gpointer user_data)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (user_data);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (user_data);
const guint8 *body;
gsize length;
@@ -364,7 +225,7 @@ sending_cb (
WockyStanza *stanza,
gpointer user_data)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (user_data);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (user_data);
if (stanza != NULL)
{
@@ -379,11 +240,11 @@ sending_cb (
}
static void
-gabble_console_sidecar_set_spew (
- GabbleConsoleSidecar *self,
+gabble_console_channel_set_spew (
+ GabbleConsoleChannel *self,
gboolean spew)
{
- GabbleConsoleSidecarPrivate *priv = self->priv;
+ GabbleConsoleChannelPrivate *priv = self->priv;
if (!spew != !priv->spew)
{
@@ -424,7 +285,7 @@ return_from_send_iq (
GAsyncResult *result,
gpointer user_data)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (source);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (source);
DBusGMethodInvocation *context = user_data;
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
GError *error = NULL;
@@ -523,12 +384,12 @@ validate_jid (const gchar **to,
*/
static gboolean
parse_me_a_stanza (
- GabbleConsoleSidecar *self,
+ GabbleConsoleChannel *self,
const gchar *xml,
WockyStanza **stanza_out,
GError **error)
{
- GabbleConsoleSidecarPrivate *priv = self->priv;
+ GabbleConsoleChannelPrivate *priv = self->priv;
WockyStanza *stanza;
wocky_xmpp_reader_reset (priv->reader);
@@ -554,13 +415,13 @@ parse_me_a_stanza (
static void
console_send_iq (
- GabbleSvcGabblePluginConsole *sidecar,
+ GabbleSvcGabblePluginConsole *channel,
const gchar *type_str,
const gchar *to,
const gchar *body,
DBusGMethodInvocation *context)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (sidecar);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (channel);
WockyPorter *porter = wocky_session_get_porter (self->priv->session);
WockyStanzaSubType sub_type;
WockyStanza *fragment;
@@ -640,11 +501,11 @@ stanza_looks_coherent (
static void
console_send_stanza (
- GabbleSvcGabblePluginConsole *sidecar,
+ GabbleSvcGabblePluginConsole *channel,
const gchar *xml,
DBusGMethodInvocation *context)
{
- GabbleConsoleSidecar *self = GABBLE_CONSOLE_SIDECAR (sidecar);
+ GabbleConsoleChannel *self = GABBLE_CONSOLE_CHANNEL (channel);
WockyPorter *porter = wocky_session_get_porter (self->priv->session);
WockyStanza *stanza = NULL;
GError *error = NULL;
diff --git a/plugins/console/channel.h b/plugins/console/channel.h
new file mode 100644
index 0000000..7e41c5a
--- /dev/null
+++ b/plugins/console/channel.h
@@ -0,0 +1,53 @@
+/* XML console plugin
+ *
+ * Copyright © 2011 Collabora Ltd. <http://www.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 <glib-object.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+typedef struct _GabbleConsoleChannel GabbleConsoleChannel;
+typedef struct _GabbleConsoleChannelClass GabbleConsoleChannelClass;
+typedef struct _GabbleConsoleChannelPrivate GabbleConsoleChannelPrivate;
+
+struct _GabbleConsoleChannel {
+ TpBaseChannel parent;
+
+ GabbleConsoleChannelPrivate *priv;
+};
+
+struct _GabbleConsoleChannelClass {
+ TpBaseChannelClass parent;
+};
+
+GType gabble_console_channel_get_type (void);
+
+#define GABBLE_TYPE_CONSOLE_CHANNEL \
+ (gabble_console_channel_get_type ())
+#define GABBLE_CONSOLE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GABBLE_TYPE_CONSOLE_CHANNEL, \
+ GabbleConsoleChannel))
+#define GABBLE_CONSOLE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GABBLE_TYPE_CONSOLE_CHANNEL, \
+ GabbleConsoleChannelClass))
+#define GABBLE_IS_CONSOLE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GABBLE_TYPE_CONSOLE_CHANNEL))
+#define GABBLE_IS_CONSOLE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GABBLE_TYPE_CONSOLE_CHANNEL))
+#define GABBLE_CONSOLE_CHANNEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_CONSOLE_CHANNEL, \
+ GabbleConsoleChannelClass))
diff --git a/src/legacy-caps.c b/plugins/console/debug.c
index 827fc15..251549a 100644
--- a/src/legacy-caps.c
+++ b/plugins/console/debug.c
@@ -1,7 +1,6 @@
-/*
- * legacy-caps.c - Connection.Interface.Capabilities constants and utilities
- * Copyright (C) 2005 Collabora Ltd.
- * Copyright (C) 2005 Nokia Corporation
+/* XML console plugin
+ *
+ * Copyright © 2011 Collabora Ltd. <http://www.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
@@ -18,23 +17,20 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "config.h"
-#include "legacy-caps.h"
+#include <glib.h>
-#include <telepathy-glib/telepathy-glib-dbus.h>
+#include "console/debug.h"
-#define DEBUG_FLAG GABBLE_DEBUG_PRESENCE
-#include "debug.h"
-#ifdef ENABLE_VOIP
-#include "media-factory.h"
-#endif
+int gabble_console_debug = 0;
-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}
+static const GDebugKey debug_keys[] = {
+ { "console", 1 },
+ { NULL, 0 }
};
+
+void
+gabble_console_debug_init (void)
+{
+ gabble_console_debug = g_parse_debug_string (g_getenv ("GABBLE_DEBUG"),
+ debug_keys, G_N_ELEMENTS (debug_keys) - 1);
+}
diff --git a/src/legacy-caps.h b/plugins/console/debug.h
index e2de46c..afe94c9 100644
--- a/src/legacy-caps.h
+++ b/plugins/console/debug.h
@@ -1,7 +1,6 @@
-/*
- * legacy-caps.h - Connection.Interface.Capabilities constants and utilities
- * Copyright (C) 2005 Collabora Ltd.
- * Copyright (C) 2005 Nokia Corporation
+/* XML console plugin
+ *
+ * Copyright © 2011 Collabora Ltd. <http://www.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
@@ -18,25 +17,12 @@
* 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 int gabble_console_debug;
-extern const CapabilityConversionData capabilities_conversions[];
+#define DEBUG(format, ...) \
+G_STMT_START { \
+ if (gabble_console_debug != 0) \
+ g_debug ("%s: " format, G_STRFUNC, ## __VA_ARGS__); \
+} G_STMT_END
-#endif
+void gabble_console_debug_init (void);
diff --git a/plugins/console/plugin.c b/plugins/console/plugin.c
new file mode 100644
index 0000000..c17cf71
--- /dev/null
+++ b/plugins/console/plugin.c
@@ -0,0 +1,91 @@
+/* XML console plugin
+ *
+ * Copyright © 2011 Collabora Ltd. <http://www.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 "console/plugin.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <wocky/wocky.h>
+#include <gabble/gabble.h>
+#include "extensions/extensions.h"
+
+#include "console/channel-manager.h"
+#include "console/channel.h"
+#include "console/debug.h"
+
+static void plugin_iface_init (
+ gpointer g_iface,
+ gpointer data);
+
+static const gchar * const sidecar_interfaces[] = {
+ GABBLE_IFACE_GABBLE_PLUGIN_CONSOLE,
+ NULL
+};
+
+G_DEFINE_TYPE_WITH_CODE (GabbleConsolePlugin, gabble_console_plugin,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GABBLE_TYPE_PLUGIN, plugin_iface_init);
+ )
+
+static void
+gabble_console_plugin_init (GabbleConsolePlugin *self)
+{
+}
+
+static void
+gabble_console_plugin_class_init (GabbleConsolePluginClass *klass)
+{
+}
+
+static GPtrArray *
+gabble_console_plugin_create_channel_managers (GabblePlugin *plugin,
+ GabblePluginConnection *plugin_connection)
+{
+ GPtrArray *ret = g_ptr_array_new ();
+
+ g_ptr_array_add (ret,
+ g_object_new (GABBLE_TYPE_CONSOLE_CHANNEL_MANAGER,
+ "plugin-connection", plugin_connection,
+ NULL));
+
+ return ret;
+}
+
+static void
+plugin_iface_init (
+ gpointer g_iface,
+ gpointer data G_GNUC_UNUSED)
+{
+ GabblePluginInterface *iface = g_iface;
+
+ iface->name = "XMPP console";
+ iface->version = PACKAGE_VERSION;
+ iface->create_channel_managers = gabble_console_plugin_create_channel_managers;
+}
+
+GabblePlugin *
+gabble_plugin_create (void)
+{
+ gabble_console_debug_init ();
+
+ DEBUG ("loaded");
+
+ return g_object_new (GABBLE_TYPE_CONSOLE_PLUGIN,
+ NULL);
+}
diff --git a/plugins/console.h b/plugins/console/plugin.h
index e646d06..153484f 100644
--- a/plugins/console.h
+++ b/plugins/console/plugin.h
@@ -19,10 +19,6 @@
#include <glib-object.h>
-#include <gio/gio.h>
-#include <wocky/wocky.h>
-#include <telepathy-glib/telepathy-glib.h>
-
typedef struct _GabbleConsolePlugin GabbleConsolePlugin;
typedef struct _GabbleConsolePluginClass GabbleConsolePluginClass;
typedef struct _GabbleConsolePluginPrivate GabbleConsolePluginPrivate;
@@ -53,36 +49,3 @@ GType gabble_console_plugin_get_type (void);
#define GABBLE_CONSOLE_PLUGIN_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_CONSOLE_PLUGIN, \
GabbleConsolePluginClass))
-
-typedef struct _GabbleConsoleSidecar GabbleConsoleSidecar;
-typedef struct _GabbleConsoleSidecarClass GabbleConsoleSidecarClass;
-typedef struct _GabbleConsoleSidecarPrivate GabbleConsoleSidecarPrivate;
-
-struct _GabbleConsoleSidecar {
- GObject parent;
- GabbleConsoleSidecarPrivate *priv;
-};
-
-struct _GabbleConsoleSidecarClass {
- GObjectClass parent;
-
- TpDBusPropertiesMixinClass props_class;
-};
-
-GType gabble_console_sidecar_get_type (void);
-
-#define GABBLE_TYPE_CONSOLE_SIDECAR \
- (gabble_console_sidecar_get_type ())
-#define GABBLE_CONSOLE_SIDECAR(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), GABBLE_TYPE_CONSOLE_SIDECAR, \
- GabbleConsoleSidecar))
-#define GABBLE_CONSOLE_SIDECAR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), GABBLE_TYPE_CONSOLE_SIDECAR, \
- GabbleConsoleSidecarClass))
-#define GABBLE_IS_CONSOLE_SIDECAR(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GABBLE_TYPE_CONSOLE_SIDECAR))
-#define GABBLE_IS_CONSOLE_SIDECAR_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), GABBLE_TYPE_CONSOLE_SIDECAR))
-#define GABBLE_CONSOLE_SIDECAR_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), GABBLE_TYPE_CONSOLE_SIDECAR, \
- GabbleConsoleSidecarClass))
diff --git a/plugins/telepathy-gabble-xmpp-console b/plugins/telepathy-gabble-xmpp-console
index 8b96469..a72c92b 100755
--- a/plugins/telepathy-gabble-xmpp-console
+++ b/plugins/telepathy-gabble-xmpp-console
@@ -3,10 +3,10 @@
"""
The world's worst XMPP console user interface.
-Pass it the bus name of a Gabble connection; type some words; get minimalistic
+Pass it a Gabble account name; type some words; get minimalistic
error reporting.
-Copyright © 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+Copyright © 2011–2013 Collabora Ltd. <http://www.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
@@ -24,23 +24,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import sys
-import re
from xml.dom import minidom
-from gi.repository import Gtk
-from gi.repository import GLib
-from gi.repository import Gio
-from gi.repository import GtkSource
+from gi.repository import Gtk, GLib, Gio, GtkSource
+from gi.repository import TelepathyGLib as Tp
PADDING = 6
-def pathify(name):
- return '/' + name.replace('.', '/')
-
-def nameify(path):
- return (path[1:]).replace('/', '.')
-
-CONN_FUTURE_IFACE = "org.freedesktop.Telepathy.Connection.FUTURE"
CONSOLE_IFACE = "org.freedesktop.Telepathy.Gabble.Plugin.Console"
class StanzaViewer(Gtk.ScrolledWindow):
@@ -302,32 +292,27 @@ class Window(Gtk.Window):
STANZA_PAGE = 1
SNOOPY_PAGE = 2
- def __init__(self, bus, connection_bus_name):
+ def __init__(self, account):
Gtk.Window.__init__(self)
self.set_title('XMPP Console')
self.set_default_size(600, 371)
- conn_future_proxy = Gio.DBusProxy.new_sync(bus, 0, None,
- connection_bus_name, pathify(connection_bus_name),
- CONN_FUTURE_IFACE, None)
- try:
- sidecar_path, _ = conn_future_proxy.EnsureSidecar('(s)', CONSOLE_IFACE)
- except Exception, e:
- print """
-Couldn't connect to the XMPP console interface on '%(connection_bus_name)s':
- %(e)s
-Check that it's a running Jabber connection, and that you have the console
-plugin installed.""" % locals()
+ request = Tp.AccountChannelRequest.new(
+ account,
+ { Tp.PROP_CHANNEL_CHANNEL_TYPE: CONSOLE_IFACE },
+ 0)
+ request.create_and_handle_channel_async(None, self.__create_cb, None)
- raise SystemExit(2)
-
- self.console_proxy = Gio.DBusProxy.new_sync(bus, 0, None,
- connection_bus_name, sidecar_path, CONSOLE_IFACE, None)
+ self.connect('destroy', Window.__destroy_cb)
+ def __build_ui(self):
# Build up the UI
+ self.grid = Gtk.Grid()
+ self.add(self.grid)
+
self.nb = Gtk.Notebook()
- self.add(self.nb)
+ self.grid.attach(self.nb, 0, 0, 1, 1)
self.iq = IQPage(self.console_proxy)
self.nb.insert_page(self.iq,
@@ -344,57 +329,103 @@ plugin installed.""" % locals()
Gtk.Label.new_with_mnemonic("_Monitor network traffic"),
self.SNOOPY_PAGE)
- self.connect('destroy', Window.__destroy_cb)
+ self.infobar = Gtk.InfoBar()
+ self.infobar.set_message_type(Gtk.MessageType.WARNING)
+ self.infobar.set_no_show_all(True)
+ label = Gtk.Label("The connection went away! Time to leave.")
+ label.show()
+ self.infobar.get_content_area().add(label)
+ self.infobar_close_button = self.infobar.add_button("Close", Gtk.ResponseType.CLOSE)
+ self.infobar.connect('response', lambda infobar, response: Gtk.main_quit())
+ self.infobar.connect('close', lambda infobar: Gtk.main_quit())
+
+ self.grid.attach_next_to(self.infobar, self.nb,
+ Gtk.PositionType.BOTTOM, 1, 1)
+
+ def __create_cb(self, request, result, _):
+ try:
+ channel, context = request.create_and_handle_channel_finish(result)
+ channel.connect('invalidated', self.__channel_invalidated_cb)
+
+ bus_name = channel.get_bus_name()
+ sidecar_path = channel.get_object_path()
+
+ bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
+ self.console_proxy = Gio.DBusProxy.new_sync(bus, 0, None,
+ bus_name, sidecar_path, CONSOLE_IFACE, None)
+
+ except GLib.GError as e:
+ print """
+Couldn't connect to the XMPP console interface on '%(name)s':
+%(e)s
+Check that you have the console plugin installed.""" % {
+ 'name': request.get_account().get_path_suffix(),
+ 'e': e,
+ }
+ raise SystemExit(2)
+
+ self.__build_ui()
+ self.show_all()
+
+ def __channel_invalidated_cb(self, channel, domain, code, message):
+ self.infobar.show()
+ self.infobar_close_button.grab_focus()
+ self.nb.set_sensitive(False)
+ # TODO: try to reconnect?
def __destroy_cb(self):
- self.snoopy.teardown()
+ try:
+ self.snoopy.teardown()
+ except GLib.GError, e:
+ print "Couldn't turn off the monitor (maybe the connection went away?)"
+ print e
Gtk.main_quit()
-GABBLE_PREFIX = 'org.freedesktop.Telepathy.Connection.gabble.jabber.'
-
-AM_BUS_NAME = 'org.freedesktop.Telepathy.AccountManager'
-ACCOUNT_PREFIX = '/org/freedesktop/Telepathy/Account'
-ACCOUNT_IFACE = 'org.freedesktop.Telepathy.Account'
+def usage(am):
+ xmpp_accounts = sorted(
+ account.get_path_suffix()
+ for account in am.dup_valid_accounts()
+ if account.get_cm_name() == 'gabble')
-def usage():
print """
Usage:
%(arg0)s gabble/jabber/blahblah
- %(arg0)s %(prefix)sblahblah
-List account identifiers using `mc-tool list | grep gabble`.
-List connection bus names using `qdbus | grep gabble`.
+Here are some account identifiers:
+
+ %(accounts)s
""" % { 'arg0': sys.argv[0],
- 'prefix': GABBLE_PREFIX,
+ 'accounts': '\n '.join(xmpp_accounts),
}
raise SystemExit(1)
-if __name__ == '__main__':
- bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
-
- if len(sys.argv) != 2:
- usage()
-
- thing = sys.argv[1]
-
- if re.match('^gabble/jabber/[a-zA-Z0-9_]+$', thing):
- # Looks like an account path to me.
- account_proxy = Gio.DBusProxy.new_sync(bus, 0, None,
- AM_BUS_NAME, '%s/%s' % (ACCOUNT_PREFIX, thing),
- ACCOUNT_IFACE, None)
- path = account_proxy.get_cached_property('Connection').get_string()
- if path == '/':
- print "%s is not online" % thing
- raise SystemExit(1)
- else:
- thing = nameify(path)
+def am_prepared_cb(am, result, account_suffix):
+ try:
+ am.prepare_finish(result)
+ except GLib.GError as e:
+ print e
+ raise SystemExit(2)
+
+ if account_suffix is None:
+ usage(am)
- if not re.match('^%s[a-zA-Z0-9_]+$' % GABBLE_PREFIX, thing):
- usage()
+ for account in am.dup_valid_accounts():
+ if account.get_path_suffix() == account_suffix:
+ if account.get_connection() is None:
+ print "%s is not online." % account_suffix
+ raise SystemExit(2)
+ else:
+ win = Window(account)
+ return
+
+ usage(am)
+
+if __name__ == '__main__':
+ account_suffix = sys.argv[1] if len(sys.argv) == 2 else None
- win = Window(bus, thing)
- win.show_all()
+ am = Tp.AccountManager.dup()
+ am.prepare_async([], am_prepared_cb, account_suffix)
Gtk.main()
diff --git a/plugins/test.c b/plugins/test.c
index bb6b719..e084b00 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 22a0278..6f5b47c 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 89af93c..4653ff6 100644
--- a/src/call-stream.c
+++ b/src/call-stream.c
@@ -101,7 +101,7 @@ get_stun_servers (GabbleCallStream *self)
WockyJingleFactory *jf;
GList *stun_servers;
- arr = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free);
+ arr = g_ptr_array_new_with_free_func ((GDestroyNotify) tp_value_array_free);
jf = wocky_jingle_session_get_factory (self->priv->content->session);
stun_servers = wocky_jingle_info_get_stun_servers (
wocky_jingle_factory_get_jingle_info (jf));
@@ -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 7fff354..6043115 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 2663703..e5bef80 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 */
@@ -476,7 +470,6 @@ nick_publish_msg_reply_cb (GabbleConnection *conn,
GObject *object,
gpointer user_data)
{
-#ifdef ENABLE_DEBUG
GError *error = NULL;
if (wocky_stanza_extract_errors (reply_msg, NULL, &error, NULL, NULL))
@@ -486,7 +479,6 @@ nick_publish_msg_reply_cb (GabbleConnection *conn,
g_clear_error (&error);
}
-#endif
}
static gboolean
@@ -632,20 +624,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 +632,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 +645,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 +889,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 +1163,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 353e323..d165449 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 a905551..681a04d 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 0e2899f..a26506d 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 1a5ff1e..2947534 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-location.c b/src/conn-location.c
index ae78d68..b511966 100644
--- a/src/conn-location.c
+++ b/src/conn-location.c
@@ -439,28 +439,21 @@ conn_location_properties_getter (GObject *object,
}
else if (!tp_strdiff (g_quark_to_string (name), "LocationAccessControl"))
{
- GValueArray *access_control = g_value_array_new (2);
- GValue type = {0,};
- GValue variant = {0,};
- GValue *allocated_value;
-
- /* G_TYPE_UINT is the D-Bus type of TpRichPresenceAccessControlType */
- g_value_init (&type, G_TYPE_UINT);
- g_value_set_uint (&type,
- TP_RICH_PRESENCE_ACCESS_CONTROL_TYPE_PUBLISH_LIST);
- g_value_array_append (access_control, &type);
- g_value_unset (&type);
-
- g_value_init (&variant, G_TYPE_VALUE);
+ GValueArray *access_control;
+ GValue dummy = G_VALUE_INIT;
+
/* For Publish_List, the variant isn't used, so we set a dummy value,
* (guint) 0 */
- allocated_value = tp_g_value_slice_new (G_TYPE_UINT);
- g_value_set_uint (allocated_value, 0);
- g_value_set_boxed (&variant, allocated_value);
- g_value_array_append (access_control, &variant);
- g_value_unset (&variant);
- tp_g_value_slice_free (allocated_value);
+ g_value_init (&dummy, G_TYPE_UINT);
+ g_value_set_uint (&dummy, 0);
+
+ access_control = tp_value_array_build (2,
+ G_TYPE_UINT,
+ (guint) TP_RICH_PRESENCE_ACCESS_CONTROL_TYPE_PUBLISH_LIST,
+ G_TYPE_VALUE, &dummy,
+ G_TYPE_INVALID);
+ g_value_unset (&dummy);
g_value_take_boxed (value, access_control);
}
else if (name == g_quark_from_static_string ("SupportedLocationFeatures"))
@@ -486,9 +479,9 @@ conn_location_properties_setter (GObject *object,
gpointer setter_data,
GError **error)
{
- GValueArray *access_control;
- GValue *access_control_type_value;
- TpRichPresenceAccessControlType access_control_type;
+ guint access_control_type;
+ GValue *access_control_argument;
+
g_return_val_if_fail (interface ==
TP_IFACE_QUARK_CONNECTION_INTERFACE_LOCATION, FALSE);
@@ -496,17 +489,13 @@ conn_location_properties_setter (GObject *object,
* already checked this. */
g_assert (name == g_quark_from_static_string ("LocationAccessControl"));
- access_control = g_value_get_boxed (value);
-
- /* TpDBusPropertiesMixin already checked this */
- g_assert (access_control->n_values == 2);
-
- access_control_type_value = g_value_array_get_nth (access_control, 0);
-
- /* TpDBusPropertiesMixin already checked this */
- g_assert (G_VALUE_TYPE (access_control_type_value) == G_TYPE_UINT);
+ /* TpDBusPropertiesMixin already checked that it was a (uv). */
+ g_assert (G_VALUE_HOLDS (value,
+ TP_STRUCT_TYPE_RICH_PRESENCE_ACCESS_CONTROL));
- access_control_type = g_value_get_uint (access_control_type_value);
+ tp_value_array_unpack (g_value_get_boxed (value), 2,
+ &access_control_type,
+ &access_control_argument);
if (access_control_type !=
TP_RICH_PRESENCE_ACCESS_CONTROL_TYPE_PUBLISH_LIST)
diff --git a/src/conn-mail-notif.c b/src/conn-mail-notif.c
index 0bc7169..afefdf7 100644
--- a/src/conn-mail-notif.c
+++ b/src/conn-mail-notif.c
@@ -123,7 +123,7 @@ return_from_request_inbox_url (GabbleConnection *conn)
if (error == NULL)
{
- g_value_array_free (result);
+ tp_value_array_free (result);
g_ptr_array_unref (empty_array);
}
else
@@ -214,7 +214,7 @@ gabble_mail_notification_request_mail_url (
tp_svc_connection_interface_mail_notification_return_from_request_mail_url (
context, result);
- g_value_array_free (result);
+ tp_value_array_free (result);
g_ptr_array_unref (empty_array);
g_free (url);
}
diff --git a/src/conn-sidecars.c b/src/conn-sidecars.c
index d2dd57e..87407a4 100644
--- a/src/conn-sidecars.c
+++ b/src/conn-sidecars.c
@@ -178,7 +178,7 @@ create_sidecar_cb (
GList *l;
for (l = contexts; l != NULL; l = l->next)
- gabble_svc_connection_future_return_from_ensure_sidecar (l->data,
+ tp_svc_connection_interface_sidecars1_return_from_ensure_sidecar (l->data,
path, props);
g_hash_table_unref (props);
@@ -200,7 +200,7 @@ out:
static void
gabble_connection_ensure_sidecar (
- GabbleSvcConnectionFUTURE *iface,
+ TpSvcConnectionInterfaceSidecars1 *iface,
const gchar *sidecar_iface,
DBusGMethodInvocation *context)
{
@@ -238,7 +238,7 @@ gabble_connection_ensure_sidecar (
GHashTable *props = gabble_sidecar_get_immutable_properties (sidecar);
DEBUG ("sidecar %s already exists at %s", sidecar_iface, path);
- gabble_svc_connection_future_return_from_ensure_sidecar (context, path,
+ tp_svc_connection_interface_sidecars1_return_from_ensure_sidecar (context, path,
props);
g_free (path);
@@ -340,14 +340,12 @@ sidecars_conn_status_changed_cb (
}
void
-conn_future_iface_init (
- gpointer g_iface,
- gpointer iface_data)
+conn_sidecars_iface_init (gpointer g_iface)
{
- GabbleSvcConnectionFUTUREClass *klass = g_iface;
+ TpSvcConnectionInterfaceSidecars1Class *klass = g_iface;
#define IMPLEMENT(x) \
- gabble_svc_connection_future_implement_##x (\
+ tp_svc_connection_interface_sidecars1_implement_##x (\
klass, gabble_connection_##x)
IMPLEMENT (ensure_sidecar);
#undef IMPLEMENT
diff --git a/src/conn-sidecars.h b/src/conn-sidecars.h
index 46e076c..a2459a8 100644
--- a/src/conn-sidecars.h
+++ b/src/conn-sidecars.h
@@ -27,7 +27,7 @@ G_BEGIN_DECLS
void conn_sidecars_init (GabbleConnection *conn);
void conn_sidecars_dispose (GabbleConnection *conn);
-void conn_future_iface_init (gpointer g_iface, gpointer iface_data);
+void conn_sidecars_iface_init (gpointer g_iface);
G_END_DECLS
diff --git a/src/connection.c b/src/connection.c
index 4bc10fc..598e571 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,
@@ -132,15 +125,15 @@ G_DEFINE_TYPE_WITH_CODE(GabbleConnection,
G_IMPLEMENT_INTERFACE
(TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
gabble_conn_contact_caps_iface_init);
- G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_CONNECTION_FUTURE,
- conn_future_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_SIDECARS1,
+ conn_sidecars_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_MAIL_NOTIFICATION,
conn_mail_notif_iface_init);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CLIENT_TYPES,
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,
@@ -900,9 +883,9 @@ static const gchar *implemented_interfaces[] = {
TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
TP_IFACE_CONNECTION_INTERFACE_LOCATION,
GABBLE_IFACE_CONNECTION_INTERFACE_GABBLE_DECLOAK,
- GABBLE_IFACE_CONNECTION_FUTURE,
+ TP_IFACE_CONNECTION_INTERFACE_SIDECARS1,
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 c3e9138..842f9e5 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/debug.h b/src/debug.h
index 83bf432..6566eda 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -73,49 +73,21 @@ G_END_DECLS
gabble_log (G_LOG_LEVEL_INFO, DEBUG_FLAG, "%s (%s): " format, \
G_STRFUNC, G_STRLOC, ##__VA_ARGS__)
-#ifdef ENABLE_DEBUG
-# define DEBUG(format, ...) \
+#define DEBUG(format, ...) \
gabble_log (G_LOG_LEVEL_DEBUG, DEBUG_FLAG, "%s (%s): " format, \
G_STRFUNC, G_STRLOC, ##__VA_ARGS__)
-# define DEBUGGING gabble_debug_flag_is_set (DEBUG_FLAG)
+#define DEBUGGING gabble_debug_flag_is_set (DEBUG_FLAG)
-# define STANZA_DEBUG(st, s) \
+#define STANZA_DEBUG(st, s) \
NODE_DEBUG (wocky_stanza_get_top_node (st), s)
-# define NODE_DEBUG(n, s) \
+#define NODE_DEBUG(n, s) \
G_STMT_START { \
gchar *debug_tmp = wocky_node_to_string (n); \
gabble_log (G_LOG_LEVEL_DEBUG, DEBUG_FLAG, "%s: %s:\n%s", G_STRFUNC, s, debug_tmp); \
g_free (debug_tmp); \
} G_STMT_END
-#else /* !defined (ENABLE_DEBUG) */
-static inline void
-DEBUG (
- const gchar *format,
- ...)
-{
-}
-
-# define DEBUGGING 0
-
-static inline void
-STANZA_DEBUG (
- WockyStanza *stanza,
- const gchar *format,
- ...)
-{
-}
-
-static inline void
-NODE_DEBUG (
- WockyNode *node,
- const gchar *format,
- ...)
-{
-}
-#endif /* !defined (ENABLE_DEBUG) */
-
#endif /* DEBUG_FLAG */
#endif /* __DEBUG_H__ */
diff --git a/src/ft-channel.c b/src/ft-channel.c
index fd82405..cf7359b 100644
--- a/src/ft-channel.c
+++ b/src/ft-channel.c
@@ -65,8 +65,6 @@ G_DEFINE_TYPE_WITH_CODE (GabbleFileTransferChannel, gabble_file_transfer_channel
TP_TYPE_BASE_CHANNEL,
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_FILE_TRANSFER,
file_transfer_iface_init);
- G_IMPLEMENT_INTERFACE (GABBLE_TYPE_SVC_CHANNEL_TYPE_FILETRANSFER_FUTURE,
- NULL);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA,
NULL);
);
@@ -96,7 +94,6 @@ enum
PROP_BYTESTREAM,
#ifdef ENABLE_JINGLE_FILE_TRANSFER
- /* Chan.Type.FileTransfer.FUTURE */
PROP_GTALK_FILE_COLLECTION,
#endif
@@ -521,7 +518,7 @@ gabble_file_transfer_channel_fill_immutable_properties (TpBaseChannel *chan,
TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "AvailableSocketTypes",
TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "TransferredBytes",
TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "InitialOffset",
- GABBLE_IFACE_CHANNEL_TYPE_FILETRANSFER_FUTURE, "FileCollection",
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "FileCollection",
TP_IFACE_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA, "ServiceName",
TP_IFACE_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA, "Metadata",
NULL);
@@ -548,7 +545,6 @@ gabble_file_transfer_channel_get_interfaces (TpBaseChannel *base)
interfaces = TP_BASE_CHANNEL_CLASS (
gabble_file_transfer_channel_parent_class)->get_interfaces (base);
- g_ptr_array_add (interfaces, GABBLE_IFACE_CHANNEL_TYPE_FILETRANSFER_FUTURE);
g_ptr_array_add (interfaces, TP_IFACE_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA);
return interfaces;
@@ -577,10 +573,6 @@ gabble_file_transfer_channel_class_init (
{ "InitialOffset", "initial-offset", NULL },
{ "Date", "date", NULL },
{ "URI", "uri", NULL },
- { NULL }
- };
-
- static TpDBusPropertiesMixinPropImpl file_future_props[] = {
{ "FileCollection", "file-collection", NULL },
{ NULL }
};
@@ -597,11 +589,6 @@ gabble_file_transfer_channel_class_init (
file_transfer_channel_properties_setter,
file_props
},
- { GABBLE_IFACE_CHANNEL_TYPE_FILETRANSFER_FUTURE,
- tp_dbus_properties_mixin_getter_gobject_properties,
- NULL,
- file_future_props
- },
{ TP_IFACE_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA,
tp_dbus_properties_mixin_getter_gobject_properties,
NULL,
@@ -633,7 +620,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 +661,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 a4266b5..cca26d4 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/gabble.c b/src/gabble.c
index e7e4da4..64c6bf4 100644
--- a/src/gabble.c
+++ b/src/gabble.c
@@ -44,7 +44,6 @@ construct_cm (void)
GABBLE_TYPE_CONNECTION_MANAGER, NULL);
}
-#ifdef ENABLE_DEBUG
static TpDebugSender *debug_sender = NULL;
static void
@@ -102,9 +101,6 @@ log_handler (const gchar *log_domain,
log_to_debug_sender (log_domain, log_level, message);
}
-#endif
-
-
void
gabble_init (void)
{
@@ -148,7 +144,6 @@ gabble_main (int argc,
g_log_set_always_fatal (fatal_mask);
#endif
-#ifdef ENABLE_DEBUG
gabble_debug_set_flags_from_env ();
stamp_logs = (g_getenv ("GABBLE_TIMING") != NULL);
@@ -168,7 +163,6 @@ gabble_main (int argc,
if (g_getenv ("GABBLE_PERSIST") != NULL)
tp_debug_set_persistent (TRUE);
-#endif
loader = gabble_plugin_loader_dup ();
@@ -179,10 +173,8 @@ gabble_main (int argc,
g_object_unref (loader);
-#ifdef ENABLE_DEBUG
g_log_set_default_handler (g_log_default_handler, NULL);
g_object_unref (debug_sender);
-#endif
wocky_deinit ();
diff --git a/src/media-channel-hold.c b/src/media-channel-hold.c
deleted file mode 100644
index b4dc26c..0000000
--- 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 4459df7..0000000
--- 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 c4ab89e..0000000
--- 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 cbe488a..0000000
--- 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 2d46258..039f549 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,28 @@ _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 +784,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,29 +809,12 @@ 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);
- 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_call_channel_class ());
- g_value_set_static_boxed (va->values + 1, call_allowed);
-
- g_ptr_array_add (arr, va);
+ g_ptr_array_add (arr,
+ tp_value_array_build (2,
+ TP_HASH_TYPE_CHANNEL_CLASS, gabble_media_factory_call_channel_class (),
+ G_TYPE_STRV, call_allowed,
+ G_TYPE_INVALID));
}
static void
@@ -1210,29 +825,22 @@ 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, qc_ice = 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_TOKEN_CHANNEL_INTERFACE_MEDIA_SIGNALLING_GTALK_P2P);
qc_gtalk_p2p = g_quark_from_static_string (
TP_TOKEN_CHANNEL_TYPE_CALL_GTALK_P2P);
- q_ice_udp = g_quark_from_static_string (
- TP_TOKEN_CHANNEL_INTERFACE_MEDIA_SIGNALLING_ICE_UDP);
qc_ice = g_quark_from_static_string (
TP_TOKEN_CHANNEL_TYPE_CALL_ICE);
/* 'ice-udp' isn't the proper cap name, 'ice' is. We keep supporting
* 'ice-udp' for now to not break existing clients. */
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");
}
@@ -1248,10 +856,10 @@ 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 },
+ { qc_gtalk_p2p, &gtalk_p2p },
+ { qc_ice_udp, &ice_udp },
{ qc_ice, &ice_udp },
- { q_h264, &h264 }, { qc_h264, &h264 },
+ { qc_h264, &h264 },
{ 0, NULL },
};
@@ -1278,27 +886,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,
@@ -1311,14 +904,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 98007f6..b02b4b5 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 426aa8a..0000000
--- 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 0fb3504..0000000
--- 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 errnum,
- 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 01bb717..6b80708 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 15c337b..78f79c7 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 0f1dbcb..39f4685 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/plugin-loader.c b/src/plugin-loader.c
index 2e14c07..3927159 100644
--- a/src/plugin-loader.c
+++ b/src/plugin-loader.c
@@ -89,13 +89,18 @@ plugin_loader_try_to_load (
}
else
{
- gchar *sidecars = g_strjoinv (", ",
- (gchar **) gabble_plugin_get_sidecar_interfaces (plugin));
+ const gchar * const *interfaces = gabble_plugin_get_sidecar_interfaces (plugin);
const gchar *version = gabble_plugin_get_version (plugin);
+ gchar *sidecars;
if (version == NULL)
version = "(unspecified)";
+ if (interfaces != NULL)
+ sidecars = g_strjoinv (", ", (gchar **) interfaces);
+ else
+ sidecars = g_strdup ("none (maybe it implements some channels instead?)");
+
DEBUG ("loaded '%s' version %s (%s), implementing these sidecars: %s",
gabble_plugin_get_name (plugin), version, path, sidecars);
diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c
index 1924509..b70f1b0 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,8 +966,6 @@ static void
channel_closed_cb (GabbleTubeIface *tube,
GabblePrivateTubesFactory *self)
{
- GabblePrivateTubesFactoryPrivate *priv =
- GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE (self);
guint64 id;
g_object_get (tube,
@@ -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 d9e01f1..5725b7f 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 deeaa8d..ce2f59b 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"
@@ -180,6 +181,9 @@ static TpCMParamSpec jabber_params[] = {
{ "extra-certificate-identities", "as", 0,
0, NULL, 0 /* unused */, NULL, NULL },
+ { "account-path-suffix", "s", G_TYPE_STRING,
+ 0, NULL, 0 /* unused */, NULL, NULL },
+
{ NULL, NULL, 0, 0, NULL, 0 }
};
@@ -276,6 +280,8 @@ new_connection (TpBaseProtocol *protocol,
conn = g_object_new (GABBLE_TYPE_CONNECTION,
"protocol", PROTOCOL_NAME,
"password", tp_asv_get_string (params, "password"),
+ "account-path-suffix", tp_asv_get_string (params,
+ "account-path-suffix"),
NULL);
/* split up account into username, stream-server and resource */
@@ -330,6 +336,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 +461,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 +489,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 d2cc4da..aa07a60 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;
+ GHashTableIter iter;
+ gpointer k;
- tp_intset_fast_iter_init (&iter, created_groups);
-
- 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,22 +721,21 @@ _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;
}
-
-#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,14 +761,11 @@ _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);
}
-#endif /* ENABLE_DEBUG */
-
static WockyStanza *
_gabble_roster_message_new (GabbleRoster *roster,
@@ -743,21 +805,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 +836,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 +846,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 +877,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:
@@ -1100,14 +1151,13 @@ process_roster (
item = _gabble_roster_item_update (roster, handle, item_node,
google_roster, &nickname_updated);
-#ifdef ENABLE_DEBUG
+
if (DEBUGGING)
{
gchar *dump = _gabble_roster_item_dump (item);
DEBUG ("jid: %s, %s", jid, dump);
g_free (dump);
}
-#endif
if (nickname_updated)
g_array_append_val (updated_nicknames, handle);
@@ -1685,7 +1735,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 +1864,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 +1879,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 +1887,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 +1934,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 +1995,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;
@@ -1977,14 +2022,12 @@ roster_item_apply_edits (GabbleRoster *roster,
memcpy (&edited_item, item, sizeof (GabbleRosterItem));
-#ifdef ENABLE_DEBUG
if (DEBUGGING)
{
gchar *dump = _gabble_roster_item_dump (&edited_item);
DEBUG ("Before, contact#%u: %s", contact, dump);
g_free (dump);
}
-#endif
if (edits->create)
{
@@ -2060,14 +2103,13 @@ roster_item_apply_edits (GabbleRoster *roster,
if (edits->add_to_groups != NULL || edits->remove_from_groups != NULL ||
edits->remove_from_all_other_groups)
{
-#ifdef ENABLE_DEBUG
if (DEBUGGING)
{
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 +2125,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
@@ -2092,32 +2134,34 @@ roster_item_apply_edits (GabbleRoster *roster,
DEBUG ("Not removing from any groups");
}
}
-#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;
}
@@ -2132,14 +2176,12 @@ roster_item_apply_edits (GabbleRoster *roster,
edited_item.subscription = GABBLE_ROSTER_SUBSCRIPTION_NONE;
}
-#ifdef ENABLE_DEBUG
if (DEBUGGING)
{
gchar *dump = _gabble_roster_item_dump (&edited_item);
DEBUG ("After, contact#%u: %s", contact, dump);
g_free (dump);
}
-#endif
if (!altered)
{
@@ -2168,7 +2210,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 +2495,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 +2537,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 +2563,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 +3095,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 +3133,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 +3161,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 +3168,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 +3192,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 +3201,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 +3225,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 +3251,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 +3271,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 +3290,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 +3306,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 +3323,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 +3352,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 +3378,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 +3388,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 +3400,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 +3429,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 +3443,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 +3454,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/search-channel.c b/src/search-channel.c
index 0c253ba..ab8a7d1 100644
--- a/src/search-channel.c
+++ b/src/search-channel.c
@@ -519,26 +519,13 @@ static GValueArray *
make_field (const gchar *field_name,
gchar **values)
{
- GValueArray *field = g_value_array_new (3);
- GValue *value;
static const gchar **empty = { NULL };
- g_value_array_append (field, NULL);
- value = g_value_array_get_nth (field, 0);
- g_value_init (value, G_TYPE_STRING);
- g_value_set_static_string (value, field_name);
-
- g_value_array_append (field, NULL);
- value = g_value_array_get_nth (field, 1);
- g_value_init (value, G_TYPE_STRV);
- g_value_set_static_boxed (value, empty);
-
- g_value_array_append (field, NULL);
- value = g_value_array_get_nth (field, 2);
- g_value_init (value, G_TYPE_STRV);
- g_value_set_boxed (value, values);
-
- return field;
+ return tp_value_array_build (3,
+ G_TYPE_STRING, field_name,
+ G_TYPE_STRV, empty,
+ G_TYPE_STRV, values,
+ G_TYPE_INVALID);
}
static gchar *
diff --git a/src/server-sasl-channel.c b/src/server-sasl-channel.c
index 3eb4f66..9ff8505 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/server-tls-manager.c b/src/server-tls-manager.c
index 4e961cd..6a23c99 100644
--- a/src/server-tls-manager.c
+++ b/src/server-tls-manager.c
@@ -556,7 +556,9 @@ gabble_server_tls_manager_get_rejection_details (GabbleServerTLSManager *self,
GabbleTLSCertificate *certificate;
GPtrArray *rejections;
GValueArray *rejection;
- TpTLSCertificateRejectReason tls_reason;
+ guint tls_reason;
+ const gchar *dbus_error_tmp;
+ GHashTable *details_tmp;
/* We probably want the rejection details of last completed operation */
g_return_if_fail (self->priv->completed_channels != NULL);
@@ -574,9 +576,13 @@ gabble_server_tls_manager_get_rejection_details (GabbleServerTLSManager *self,
rejection = g_ptr_array_index (rejections, 0);
- tls_reason = g_value_get_uint (g_value_array_get_nth (rejection, 0));
- *dbus_error = g_value_dup_string (g_value_array_get_nth (rejection, 1));
- *details = g_value_dup_boxed (g_value_array_get_nth (rejection, 2));
+ tp_value_array_unpack (rejection, 3,
+ &tls_reason,
+ &dbus_error_tmp,
+ &details_tmp);
+
+ *dbus_error = g_strdup (dbus_error_tmp);
+ *details = g_boxed_copy (TP_HASH_TYPE_STRING_VARIANT_MAP, details_tmp);
*reason = cert_reject_reason_to_conn_reason (tls_reason);
diff --git a/src/tls-certificate.c b/src/tls-certificate.c
index 303b706..c00bac7 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 d982e79..3b6197e 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 7faf514..aef131e 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 b727f39..6cfa8ca 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 e1d2289..c623813 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 74e933e..9f40b75 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 b097316..90da9fd 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 a0d60be..ebc4c39 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 d93d5b3..22cf954 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 \
@@ -78,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 \
@@ -176,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 \
@@ -187,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)
@@ -271,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 \
@@ -344,24 +312,12 @@ else
@echo "and then re-run configure."
endif
-if ENABLE_DEBUG
-DEBUGGING_PYBOOL = True
-else
-DEBUGGING_PYBOOL = False
-endif
-
if ENABLE_PLUGINS
PLUGINS_ENABLED_PYBOOL = True
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
@@ -390,9 +346,7 @@ config.py: Makefile
$(AM_V_GEN) { \
echo "PACKAGE_STRING = \"$(PACKAGE_STRING)\""; \
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)"; \
diff --git a/tests/twisted/addressing.py b/tests/twisted/addressing.py
index 9528e12..057617b 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 0272e95..25301b9 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 138cb26..ec7ec7b 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 95b1624..0000000
--- 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 9c63e03..0102d5c 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 2b13183..b4725a8 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 0460fd6..122aaf6 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 5c4562c..ce0ca5f 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 42f69cf..4b14205 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 1313c6d..dea958b 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 7ea84f5..c35d0db 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 34a145b..fda08ec 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 3d3f698..1ceb6f8 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 11b05d9..b5579a2 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 2eaeebe..7becd11 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 e9c0b1c..2c34036 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/test-twice.py b/tests/twisted/connect/test-twice.py
index 437ecec..9ab1b09 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 95c76a3..f92e57a 100644
--- a/tests/twisted/console.py
+++ b/tests/twisted/console.py
@@ -4,14 +4,14 @@ A smoketest for the XMPP console API.
from servicetest import (
ProxyWrapper, EventPattern,
- call_async, assertEquals, assertContains, assertNotEquals, sync_dbus,
+ call_async, assertEquals, assertNotEquals, 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:
@@ -27,9 +27,25 @@ def send_unrecognised_get(q, stream):
return q.expect('stream-iq', iq_type='error')
def test(q, bus, conn, stream):
- path, _ = conn.Future.EnsureSidecar(CONSOLE_PLUGIN_IFACE)
+ rccs = conn.Properties.Get(cs.CONN_IFACE_REQUESTS,
+ 'RequestableChannelClasses')
+
+ fixed = {
+ cs.CHANNEL_TYPE: CONSOLE_PLUGIN_IFACE,
+ cs.TARGET_HANDLE_TYPE: cs.HT_NONE,
+ }
+ allowed = []
+ assertContains((fixed, allowed), rccs)
+
+ path, _ = conn.Requests.CreateChannel({ cs.CHANNEL_TYPE: CONSOLE_PLUGIN_IFACE })
+ other_path, _ = conn.Requests.CreateChannel({ cs.CHANNEL_TYPE: CONSOLE_PLUGIN_IFACE })
+
+ assertNotEquals(path, other_path)
+ # leave the other one open, to test we don't crash on disconnect
+
console = ProxyWrapper(bus.get_object(conn.bus_name, path),
- CONSOLE_PLUGIN_IFACE)
+ CONSOLE_PLUGIN_IFACE,
+ {'Channel': cs.CHANNEL})
assert not console.Properties.Get(CONSOLE_PLUGIN_IFACE, 'SpewStanzas')
es = [
@@ -88,5 +104,7 @@ def test(q, bus, conn, stream):
assertEquals('body', body.name)
assertEquals(ns.CLIENT, body.uri)
+ console.Channel.Close()
+
if __name__ == '__main__':
exec_test(test)
diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py
index d541c75..e21bc13 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'
@@ -30,6 +54,7 @@ CHANNEL_IFACE_ROOM = CHANNEL + '.Interface.Room2'
CHANNEL_IFACE_ROOM_CONFIG = CHANNEL + '.Interface.RoomConfig1'
CHANNEL_IFACE_SUBJECT = CHANNEL + '.Interface.Subject2'
CHANNEL_IFACE_FILE_TRANSFER_METADATA = CHANNEL + '.Interface.FileTransfer.Metadata'
+CHANNEL_IFACE_SMS = CHANNEL + '.Interface.SMS'
CHANNEL_TYPE_CALL = CHANNEL + ".Type.Call1"
CHANNEL_TYPE_CONTACT_LIST = CHANNEL + ".Type.ContactList"
@@ -38,15 +63,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 +85,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 +126,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 +196,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'
@@ -182,6 +204,8 @@ CONN_IFACE_CONTACTS = CONN + '.Interface.Contacts'
CONN_IFACE_CONTACT_CAPS = CONN + '.Interface.ContactCapabilities'
CONN_IFACE_CONTACT_INFO = CONN + ".Interface.ContactInfo"
CONN_IFACE_PRESENCE = CONN + '.Interface.Presence'
+CONN_IFACE_RENAMING = CONN + '.Interface.Renaming'
+CONN_IFACE_SIDECARS1 = CONN + '.Interface.Sidecars1'
CONN_IFACE_SIMPLE_PRESENCE = CONN + '.Interface.SimplePresence'
CONN_IFACE_REQUESTS = CONN + '.Interface.Requests'
CONN_IFACE_LOCATION = CONN + '.Interface.Location'
@@ -193,12 +217,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 +244,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 +256,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'
@@ -330,7 +368,7 @@ FT_DATE = CHANNEL_TYPE_FILE_TRANSFER + '.Date'
FT_AVAILABLE_SOCKET_TYPES = CHANNEL_TYPE_FILE_TRANSFER + '.AvailableSocketTypes'
FT_TRANSFERRED_BYTES = CHANNEL_TYPE_FILE_TRANSFER + '.TransferredBytes'
FT_INITIAL_OFFSET = CHANNEL_TYPE_FILE_TRANSFER + '.InitialOffset'
-FT_FILE_COLLECTION = CHANNEL_TYPE_FILE_TRANSFER + '.FUTURE.FileCollection'
+FT_FILE_COLLECTION = CHANNEL_TYPE_FILE_TRANSFER + '.FileCollection'
FT_URI = CHANNEL_TYPE_FILE_TRANSFER + '.URI'
FT_SERVICE_NAME = CHANNEL_IFACE_FILE_TRANSFER_METADATA + '.ServiceName'
FT_METADATA = CHANNEL_IFACE_FILE_TRANSFER_METADATA + '.Metadata'
@@ -407,8 +445,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 +516,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 +527,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 +579,58 @@ 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_MESSAGES1 = PREFIX + '.ChannelDispatcher.Interface.Messages1'
+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"
+
+# Channel.Interface.SMS
+SMS_FLASH = CHANNEL_IFACE_SMS + '.Flash'
+SMS_CHANNEL = CHANNEL_IFACE_SMS + '.SMSChannel'
diff --git a/tests/twisted/dataforms.py b/tests/twisted/dataforms.py
index 6004c15..87cb625 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 79b3acf..4fa915b 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,11 +216,10 @@ 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,
- cs.CHANNEL_TYPE_FILE_TRANSFER + '.FUTURE',
], props[cs.INTERFACES])
assert props[cs.TARGET_HANDLE] == self.handle
assert props[cs.TARGET_ID] == self.contact_name
@@ -229,7 +228,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 +333,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,11 +407,10 @@ 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,
- cs.CHANNEL_TYPE_FILE_TRANSFER + '.FUTURE',
], props[cs.INTERFACES])
assertEquals(self.handle, props[cs.TARGET_HANDLE])
assertEquals(self.contact_name, props[cs.TARGET_ID])
@@ -422,7 +419,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 336d7a0..f8c65c9 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 8667a9c..337e90c 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 743906a..c7d6c9b 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 a5a8d97..51b0e46 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 f2e79ab..89b865d 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 bb13894..491e86f 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 17d0799..dc1d691 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 e6b8baa..fe2ce66 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 d4073dd..ebe1b2e 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"
@@ -68,7 +63,7 @@ def test_not_acceptable(q, gateways_iface, stream):
def test(q, bus, conn, stream):
# Request a sidecar thate we support before we're connected; it should just
# wait around until we're connected.
- call_async(q, conn.Future, 'EnsureSidecar', PLUGIN_IFACE)
+ call_async(q, conn.Sidecars1, 'EnsureSidecar', PLUGIN_IFACE)
conn.Connect()
q.expect('dbus-signal', signal='StatusChanged',
diff --git a/tests/twisted/jingle-share/file_transfer_helper.py b/tests/twisted/jingle-share/file_transfer_helper.py
index 19a45ca..07119d4 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):
@@ -275,7 +270,6 @@ class ReceiveFileTest(FileTransferTest):
assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_FILE_TRANSFER, props
assertSameSets(
[ cs.CHANNEL_IFACE_FILE_TRANSFER_METADATA,
- cs.CHANNEL_TYPE_FILE_TRANSFER + '.FUTURE',
], props[cs.INTERFACES])
assert props[cs.TARGET_HANDLE] == self.handle, props
assert props[cs.TARGET_ID] == self.target, props
@@ -430,7 +424,6 @@ class SendFileTest(FileTransferTest):
assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_FILE_TRANSFER
assertSameSets(
[ cs.CHANNEL_IFACE_FILE_TRANSFER_METADATA,
- cs.CHANNEL_TYPE_FILE_TRANSFER + '.FUTURE',
], props[cs.INTERFACES])
assert props[cs.TARGET_HANDLE] == self.handle
assert props[cs.TARGET_ID] == self.target
diff --git a/tests/twisted/jingle-share/jingleshareutils.py b/tests/twisted/jingle-share/jingleshareutils.py
index 6ade4f5..21030dc 100644
--- a/tests/twisted/jingle-share/jingleshareutils.py
+++ b/