summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.co.uk>2013-09-26 15:03:35 -0400
committerXavier Claessens <xavier.claessens@collabora.co.uk>2013-10-02 14:28:48 -0400
commitaf26addebbc4d20783c29f5b8d57cfc9183ba395 (patch)
tree0b449e70d53124c47726938186c73bf56b76f070
parent64bca7fa674595f531d77aaf8c31253dc944413c (diff)
Port to telepathy-glib-1folks-for-tp-spec-0.99.2
Note the evil hack in Makefiles when generating vapi files. I have to use sed to change the namespace from "Tp." to "TelepathyGLib.". It seems vapigen is confused between telepathy-glib's gir namespace and its vapi namespace. I don't know why. https://bugzilla.gnome.org/show_bug.cgi?id=708871
-rw-r--r--backends/telepathy/Makefile.am2
-rw-r--r--backends/telepathy/lib/Makefile.am8
-rw-r--r--backends/telepathy/lib/folks-telepathy-uninstalled.pc.in2
-rw-r--r--backends/telepathy/lib/folks-telepathy.deps2
-rw-r--r--backends/telepathy/lib/folks-telepathy.pc.in2
-rw-r--r--backends/telepathy/lib/tp-lowlevel.c1
-rw-r--r--backends/telepathy/lib/tpf-persona-store.vala38
-rw-r--r--backends/telepathy/lib/tpf-persona.vala10
-rw-r--r--backends/telepathy/tp-backend.vala18
-rw-r--r--configure.ac11
-rw-r--r--docs/Makefile.am2
-rw-r--r--folks/folks-uninstalled.pc.in2
-rw-r--r--tests/folks/aggregation.vala2
-rw-r--r--tests/lib/telepathy/contactlist/Makefile.am8
-rw-r--r--tests/lib/telepathy/contactlist/backend.c15
-rw-r--r--tests/lib/telepathy/contactlist/broken-client-types-conn.c65
-rw-r--r--tests/lib/telepathy/contactlist/broken-client-types-conn.h50
-rw-r--r--tests/lib/telepathy/contactlist/bug-19101-conn.c74
-rw-r--r--tests/lib/telepathy/contactlist/bug-19101-conn.h51
-rw-r--r--tests/lib/telepathy/contactlist/contact-list-manager.c140
-rw-r--r--tests/lib/telepathy/contactlist/contact-list-manager.h2
-rw-r--r--tests/lib/telepathy/contactlist/contacts-conn.c472
-rw-r--r--tests/lib/telepathy/contactlist/contacts-conn.h76
-rw-r--r--tests/lib/telepathy/contactlist/dbus-tube-chan.c455
-rw-r--r--tests/lib/telepathy/contactlist/dbus-tube-chan.h127
-rw-r--r--tests/lib/telepathy/contactlist/echo-chan.c223
-rw-r--r--tests/lib/telepathy/contactlist/echo-chan.h56
-rw-r--r--tests/lib/telepathy/contactlist/echo-conn.c165
-rw-r--r--tests/lib/telepathy/contactlist/echo-conn.h56
-rw-r--r--tests/lib/telepathy/contactlist/echo-im-manager.c382
-rw-r--r--tests/lib/telepathy/contactlist/echo-im-manager.h54
-rw-r--r--tests/lib/telepathy/contactlist/file-transfer-chan.c763
-rw-r--r--tests/lib/telepathy/contactlist/file-transfer-chan.h63
-rw-r--r--tests/lib/telepathy/contactlist/my-conn-proxy.c364
-rw-r--r--tests/lib/telepathy/contactlist/my-conn-proxy.h124
-rw-r--r--tests/lib/telepathy/contactlist/myassert.h16
-rw-r--r--tests/lib/telepathy/contactlist/room-list-chan.c3
-rw-r--r--tests/lib/telepathy/contactlist/room-list-chan.h2
-rw-r--r--tests/lib/telepathy/contactlist/simple-account-manager.c67
-rw-r--r--tests/lib/telepathy/contactlist/simple-account-manager.h4
-rw-r--r--tests/lib/telepathy/contactlist/simple-account.c84
-rw-r--r--tests/lib/telepathy/contactlist/simple-account.h6
-rw-r--r--tests/lib/telepathy/contactlist/simple-channel-dispatch-operation.c303
-rw-r--r--tests/lib/telepathy/contactlist/simple-channel-dispatch-operation.h73
-rw-r--r--tests/lib/telepathy/contactlist/simple-channel-dispatcher.c394
-rw-r--r--tests/lib/telepathy/contactlist/simple-channel-dispatcher.h66
-rw-r--r--tests/lib/telepathy/contactlist/simple-channel-manager.c95
-rw-r--r--tests/lib/telepathy/contactlist/simple-channel-manager.h54
-rw-r--r--tests/lib/telepathy/contactlist/simple-channel-request.c508
-rw-r--r--tests/lib/telepathy/contactlist/simple-channel-request.h70
-rw-r--r--tests/lib/telepathy/contactlist/simple-client.c250
-rw-r--r--tests/lib/telepathy/contactlist/simple-client.h64
-rw-r--r--tests/lib/telepathy/contactlist/simple-conn.c132
-rw-r--r--tests/lib/telepathy/contactlist/simple-conn.h8
-rw-r--r--tests/lib/telepathy/contactlist/stream-tube-chan.c650
-rw-r--r--tests/lib/telepathy/contactlist/stream-tube-chan.h129
-rw-r--r--tests/lib/telepathy/contactlist/stub-object.c68
-rw-r--r--tests/lib/telepathy/contactlist/stub-object.h11
-rw-r--r--tests/lib/telepathy/contactlist/textchan-group.c329
-rw-r--r--tests/lib/telepathy/contactlist/textchan-group.h72
-rw-r--r--tests/lib/telepathy/contactlist/textchan-null.c579
-rw-r--r--tests/lib/telepathy/contactlist/textchan-null.h137
-rw-r--r--tests/lib/telepathy/contactlist/tls-certificate.c350
-rw-r--r--tests/lib/telepathy/contactlist/tls-certificate.h68
-rw-r--r--tests/lib/telepathy/contactlist/tp-test-contactlist.deps2
-rw-r--r--tests/lib/telepathy/contactlist/util.c207
-rw-r--r--tests/lib/telepathy/contactlist/util.h38
-rw-r--r--tests/lib/telepathy/tpf-test.deps2
-rw-r--r--tests/telepathy/Makefile.am2
-rw-r--r--tests/telepathy/individual-properties.vala2
-rw-r--r--tests/telepathy/individual-retrieval.vala2
-rwxr-xr-xtests/tools/manager-file.py4
-rw-r--r--tools/import-pidgin.vala2
73 files changed, 7235 insertions, 1503 deletions
diff --git a/backends/telepathy/Makefile.am b/backends/telepathy/Makefile.am
index d22d9697..6e036d1a 100644
--- a/backends/telepathy/Makefile.am
+++ b/backends/telepathy/Makefile.am
@@ -17,7 +17,7 @@ telepathy_la_VALAFLAGS = \
--pkg gee-0.8 \
--pkg gio-2.0 \
--pkg gobject-2.0 \
- --pkg telepathy-glib \
+ --pkg telepathy-glib-1 \
$(NULL)
backenddir = $(BACKEND_DIR)/telepathy
diff --git a/backends/telepathy/lib/Makefile.am b/backends/telepathy/lib/Makefile.am
index 0d32f81f..480d2703 100644
--- a/backends/telepathy/lib/Makefile.am
+++ b/backends/telepathy/lib/Makefile.am
@@ -78,8 +78,8 @@ tp-lowlevel.vapi: TpLowlevel-$(API_VERSION_DOT).gir
$(AM_V_GEN)$(VAPIGEN) $(VAPIGENFLAGS) \
--library tp-lowlevel \
--pkg gio-2.0 \
- --pkg telepathy-glib \
- TpLowlevel-$(API_VERSION_DOT).gir
+ --pkg telepathy-glib-1 \
+ TpLowlevel-$(API_VERSION_DOT).gir && sed -i "s/Tp\./TelepathyGLib\./g" $@
touch $@
endif
@@ -156,7 +156,7 @@ libtp_zeitgeist_la_VALAFLAGS = \
--pkg gio-2.0 \
--pkg gee-0.8 \
--pkg zeitgeist-2.0 \
- --pkg telepathy-glib \
+ --pkg telepathy-glib-1 \
--pkg folks \
--pkg build-conf \
--library tp-zeitgeist \
@@ -226,7 +226,7 @@ libfolks_telepathy_la_VALAFLAGS = \
--pkg gobject-2.0 \
--pkg gio-2.0 \
--pkg gee-0.8 \
- --pkg telepathy-glib \
+ --pkg telepathy-glib-1 \
--includedir folks \
--library folks-telepathy \
--vapi folks-telepathy.vapi \
diff --git a/backends/telepathy/lib/folks-telepathy-uninstalled.pc.in b/backends/telepathy/lib/folks-telepathy-uninstalled.pc.in
index c3a70c3e..81dcdeb5 100644
--- a/backends/telepathy/lib/folks-telepathy-uninstalled.pc.in
+++ b/backends/telepathy/lib/folks-telepathy-uninstalled.pc.in
@@ -7,6 +7,6 @@ vapidir=@abs_top_srcdir@/folks
Name: Folks Telepathy support library (uninstalled copy)
Description: Telepathy support library for the Folks meta-contacts library
Version: @VERSION@
-Requires: folks glib-2.0 gobject-2.0 gee-0.8 telepathy-glib >= 0.11.11
+Requires: folks glib-2.0 gobject-2.0 gee-0.8 telepathy-glib-1 >= 0.99.1
Libs: ${abs_top_builddir}/backends/telepathy/libfolks-telepathy.la
Cflags: -I${abs_top_srcdir} -I${abs_top_srcdir}/backends/telepathy -I${abs_top_builddir}
diff --git a/backends/telepathy/lib/folks-telepathy.deps b/backends/telepathy/lib/folks-telepathy.deps
index dec8d50a..8ecb0884 100644
--- a/backends/telepathy/lib/folks-telepathy.deps
+++ b/backends/telepathy/lib/folks-telepathy.deps
@@ -1,4 +1,4 @@
glib-2.0
gobject-2.0
folks
-telepathy-glib
+telepathy-glib-1
diff --git a/backends/telepathy/lib/folks-telepathy.pc.in b/backends/telepathy/lib/folks-telepathy.pc.in
index 3e569160..1e5d8999 100644
--- a/backends/telepathy/lib/folks-telepathy.pc.in
+++ b/backends/telepathy/lib/folks-telepathy.pc.in
@@ -10,6 +10,6 @@ vapidir=@datadir@/vala/vapi
Name: Folks Telepathy support library
Description: Telepathy support library for the Folks meta-contacts library
Version: @VERSION@
-Requires: folks glib-2.0 gobject-2.0 gee-0.8 telepathy-glib >= 0.11.11
+Requires: folks glib-2.0 gobject-2.0 gee-0.8 telepathy-glib-1 >= 0.99.1
Libs: -L${libdir} -lfolks-telepathy
Cflags: -I${includedir}
diff --git a/backends/telepathy/lib/tp-lowlevel.c b/backends/telepathy/lib/tp-lowlevel.c
index da5052c2..d803e0f8 100644
--- a/backends/telepathy/lib/tp-lowlevel.c
+++ b/backends/telepathy/lib/tp-lowlevel.c
@@ -27,6 +27,7 @@
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
#include "tp-lowlevel.h"
diff --git a/backends/telepathy/lib/tpf-persona-store.vala b/backends/telepathy/lib/tpf-persona-store.vala
index b5b0ac6e..63a5b00d 100644
--- a/backends/telepathy/lib/tpf-persona-store.vala
+++ b/backends/telepathy/lib/tpf-persona-store.vala
@@ -395,8 +395,8 @@ public class Tpf.PersonaStore : Folks.PersonaStore
/* We do not trust local-xmpp or IRC at all, since Persona UIDs can be
* faked by just changing hostname/username or nickname. */
- if (account.get_protocol () == "local-xmpp" ||
- account.get_protocol () == "irc")
+ if (account.get_protocol_name () == "local_xmpp" ||
+ account.get_protocol_name () == "irc")
this.trust_level = PersonaStoreTrust.NONE;
else
this.trust_level = PersonaStoreTrust.PARTIAL;
@@ -487,14 +487,14 @@ public class Tpf.PersonaStore : Folks.PersonaStore
* contacts. */
var factory = this._account_manager.get_factory ();
factory.add_contact_features ({
- ContactFeature.ALIAS,
- ContactFeature.AVATAR_DATA,
- ContactFeature.AVATAR_TOKEN,
- ContactFeature.CAPABILITIES,
- ContactFeature.CLIENT_TYPES,
- ContactFeature.PRESENCE,
- ContactFeature.CONTACT_INFO,
- ContactFeature.CONTACT_GROUPS
+ Contact.get_feature_quark_alias (),
+ Contact.get_feature_quark_avatar_data (),
+ Contact.get_feature_quark_avatar_token (),
+ Contact.get_feature_quark_capabilities (),
+ Contact.get_feature_quark_client_types (),
+ Contact.get_feature_quark_presence (),
+ Contact.get_feature_quark_contact_info (),
+ Contact.get_feature_quark_contact_groups (),
});
this._account_manager.invalidated.connect (
@@ -511,7 +511,7 @@ public class Tpf.PersonaStore : Folks.PersonaStore
this._remove_store (this._persona_set);
}
});
- this._account_manager.account_validity_changed.connect (
+ this._account_manager.account_usability_changed.connect (
(a, valid) =>
{
if (!valid && this.account == a)
@@ -762,11 +762,11 @@ public class Tpf.PersonaStore : Folks.PersonaStore
0
});
- if (!this.account.connection.has_interface_by_id (
- iface_quark_connection_interface_contact_list ()))
+ if (!this.account.connection.is_prepared (
+ TelepathyGLib.Connection.get_feature_quark_contact_list ()))
{
debug ("Connection does not implement ContactList iface; " +
- "legacy CMs are not supported any more.");
+ "skipping store with no contact list.");
this._remove_store (this._persona_set);
@@ -851,7 +851,7 @@ public class Tpf.PersonaStore : Folks.PersonaStore
if ((ci_flags & ContactInfoFlags.CAN_SET) != 0)
{
var field_specs =
- connection.get_contact_info_supported_fields ();
+ connection.dup_contact_info_supported_fields ();
foreach (var field_spec in field_specs)
{
/* XXX: we ignore the maximum count for each type of
@@ -876,12 +876,12 @@ public class Tpf.PersonaStore : Folks.PersonaStore
private async void _load_cache (HashSet<Persona>? old_personas)
{
/* Only load from the cache if the account is enabled and valid. */
- if (this.account.enabled == false || this.account.valid == false)
+ if (this.account.enabled == false || this.account.usable == false)
{
debug ("Skipping loading cache for Tpf.PersonaStore %p ('%s'): " +
"enabled: %s, valid: %s.", this, this.id,
this.account.enabled ? "yes" : "no",
- this.account.valid ? "yes" : "no");
+ this.account.usable ? "yes" : "no");
return;
}
@@ -973,7 +973,7 @@ public class Tpf.PersonaStore : Folks.PersonaStore
/* Only store/load the cache if the account is enabled and valid;
* otherwise, the PersonaStore will get removed and the cache
* deleted later anyway. */
- if (!this.account.enabled || !this.account.valid)
+ if (!this.account.enabled || !this.account.usable)
{
debug ("Skipping storing cache for Tpf.PersonaStore %p (ā€˜%sā€™) as " +
"its TpAccount is disabled or invalid.", this, this.id);
@@ -1680,7 +1680,7 @@ public class Tpf.PersonaStore : Folks.PersonaStore
private async void _populate_counters ()
{
this._zg_controller = new FolksTpZeitgeist.Controller (this,
- this.account.protocol, (p, dt) =>
+ this.account.protocol_name, (p, dt) =>
{
var persona = p as Tpf.Persona;
assert (persona != null);
diff --git a/backends/telepathy/lib/tpf-persona.vala b/backends/telepathy/lib/tpf-persona.vala
index 6a3cf550..4d9572e5 100644
--- a/backends/telepathy/lib/tpf-persona.vala
+++ b/backends/telepathy/lib/tpf-persona.vala
@@ -765,10 +765,10 @@ public class Tpf.Persona : Folks.Persona,
* interface along with the code in
* Kf.Persona.linkable_property_to_links(), but that depends on
* bgo#624842 being fixed. */
- iid: account.get_protocol () + ":" + id,
+ iid: account.get_protocol_name () + ":" + id,
uid: uid,
store: store,
- is_user: contact.handle == connection.self_handle);
+ is_user: contact == connection.self_contact);
debug ("Created new Tpf.Persona '%s' for service-specific UID '%s': %p",
uid, id, this);
@@ -815,9 +815,9 @@ public class Tpf.Persona : Folks.Persona,
try
{
var im_addr = ImDetails.normalise_im_address (this.display_id,
- account.get_protocol ());
+ account.get_protocol_name ());
var im_fd = new ImFieldDetails (im_addr);
- this._im_addresses.set (account.get_protocol (), im_fd);
+ this._im_addresses.set (account.get_protocol_name (), im_fd);
}
catch (ImDetailsError e)
{
@@ -974,7 +974,7 @@ public class Tpf.Persona : Folks.Persona,
AbstractFieldDetails<string>.hash_static,
AbstractFieldDetails<string>.equal_static);
- var contact_info = contact.get_contact_info ();
+ var contact_info = contact.dup_contact_info ();
foreach (var info in contact_info)
{
if (info.field_name == "") {}
diff --git a/backends/telepathy/tp-backend.vala b/backends/telepathy/tp-backend.vala
index f593604e..b119db19 100644
--- a/backends/telepathy/tp-backend.vala
+++ b/backends/telepathy/tp-backend.vala
@@ -84,8 +84,8 @@ public class Folks.Backends.Tp.Backend : Folks.Backend
PersonaStore[] removed_stores = {};
/* First handle adding any missing persona stores. */
- GLib.List<unowned Account> accounts =
- this._account_manager.get_valid_accounts ();
+ GLib.List<Account> accounts =
+ this._account_manager.dup_usable_accounts ();
foreach (Account account in accounts)
{
string id = account.get_object_path ();
@@ -170,11 +170,11 @@ public class Folks.Backends.Tp.Backend : Folks.Backend
yield this._account_manager.prepare_async (null);
this._account_manager.account_enabled.connect (
this._account_enabled_cb);
- this._account_manager.account_validity_changed.connect (
- this._account_validity_changed_cb);
+ this._account_manager.account_usability_changed.connect (
+ this._account_usability_changed_cb);
- GLib.List<unowned Account> accounts =
- this._account_manager.get_valid_accounts ();
+ GLib.List<Account> accounts =
+ this._account_manager.dup_usable_accounts ();
foreach (Account account in accounts)
{
this._account_enabled_cb (account);
@@ -210,8 +210,8 @@ public class Folks.Backends.Tp.Backend : Folks.Backend
this._account_manager.account_enabled.disconnect (
this._account_enabled_cb);
- this._account_manager.account_validity_changed.disconnect (
- this._account_validity_changed_cb);
+ this._account_manager.account_usability_changed.disconnect (
+ this._account_usability_changed_cb);
this._account_manager = null;
this._is_quiescent = false;
@@ -226,7 +226,7 @@ public class Folks.Backends.Tp.Backend : Folks.Backend
}
}
- private void _account_validity_changed_cb (Account account, bool valid)
+ private void _account_usability_changed_cb (Account account, bool valid)
{
if (valid)
this._account_enabled_cb (account);
diff --git a/configure.ac b/configure.ac
index d00dc945..0fa03951 100644
--- a/configure.ac
+++ b/configure.ac
@@ -159,7 +159,7 @@ AS_IF([test "x$enable_libsocialweb_backend" != "xno"], [
have_libsocialweb_backend="yes", have_libsocialweb_backend="no")
AS_IF([test "x$have_libsocialweb_backend" = "xyes" -a \
"x$enable_vala" = "xyes"], [
- VALA_CHECK_PACKAGES([telepathy-glib
+ VALA_CHECK_PACKAGES([telepathy-glib-1
gio-2.0
gee-0.8
libsocialweb-client],
@@ -209,10 +209,13 @@ PKG_CHECK_MODULES([DBUS_GLIB], [dbus-glib-1 dbus-1])
PKG_CHECK_MODULES([GEE], [gee-0.8 >= $GEE_REQUIRED])
-TP_GLIB_REQUIRED=0.19.0
+TP_GLIB_REQUIRED=0.99.1
AS_IF([test x$enable_telepathy_backend = xyes], [
- PKG_CHECK_MODULES([TP_GLIB], [telepathy-glib >= $TP_GLIB_REQUIRED])])
+ PKG_CHECK_MODULES([TP_GLIB], [
+ telepathy-glib-1 >= $TP_GLIB_REQUIRED
+ telepathy-glib-1-dbus >= $TP_GLIB_REQUIRED
+ ])])
case "x$enable_zeitgeist" in
xyes)
AS_IF([test x$enable_telepathy_backend = xyes],
@@ -341,7 +344,7 @@ AS_IF([test "x$enable_vala" = "xyes"], [
gee-0.8])
AS_IF([test x$enable_telepathy_backend = xyes], [
- VALA_CHECK_PACKAGES([telepathy-glib])
+ VALA_CHECK_PACKAGES([telepathy-glib-1])
AS_IF([test "x$have_zeitgeist" == "xyes"], [
VALA_CHECK_PACKAGES([zeitgeist-2.0])
])
diff --git a/docs/Makefile.am b/docs/Makefile.am
index d94b21a7..56ece334 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -135,7 +135,7 @@ folks_telepathy_doc_deps = \
gmodule-2.0 \
gio-2.0 \
gee-0.8 \
- telepathy-glib \
+ telepathy-glib-1 \
zeitgeist-2.0 \
tp-lowlevel \
build-conf \
diff --git a/folks/folks-uninstalled.pc.in b/folks/folks-uninstalled.pc.in
index 642d8015..a4db1a70 100644
--- a/folks/folks-uninstalled.pc.in
+++ b/folks/folks-uninstalled.pc.in
@@ -7,6 +7,6 @@ vapidir=@abs_top_srcdir@/folks
Name: Folks (uninstalled copy)
Description: The Folks meta-contacts library
Version: @VERSION@
-Requires: glib-2.0 gobject-2.0 gee-0.8 telepathy-glib >= 0.11.11
+Requires: glib-2.0 gobject-2.0 gee-0.8 telepathy-glib-1 >= 0.99.1
Libs: ${abs_top_builddir}/folks/libfolks.la
Cflags: -I${abs_top_srcdir} -I${abs_top_builddir}
diff --git a/tests/folks/aggregation.vala b/tests/folks/aggregation.vala
index 22946bb0..410d8f78 100644
--- a/tests/folks/aggregation.vala
+++ b/tests/folks/aggregation.vala
@@ -26,7 +26,7 @@ public class AggregationTests : TpfTest.MixedTestCase
private HashSet<string> _default_personas;
private static string iid_prefix =
- "telepathy:/org/freedesktop/Telepathy/Account/cm/protocol/account:";
+ "telepathy:/im/telepathy1/Account/cm/protocol/account:";
private string olivier_sha1 = Checksum.compute_for_string (ChecksumType.SHA1,
iid_prefix + "olivier@example.com");
diff --git a/tests/lib/telepathy/contactlist/Makefile.am b/tests/lib/telepathy/contactlist/Makefile.am
index 05d23f63..b9b69107 100644
--- a/tests/lib/telepathy/contactlist/Makefile.am
+++ b/tests/lib/telepathy/contactlist/Makefile.am
@@ -11,7 +11,7 @@ VAPIGENFLAGS += \
--pkg gee-0.8 \
--pkg gmodule-2.0 \
--pkg dbus-glib-1 \
- --pkg telepathy-glib \
+ --pkg telepathy-glib-1 \
$(NULL)
noinst_LTLIBRARIES = libtp-test-contactlist.la
@@ -36,8 +36,8 @@ libtp_test_contactlist_la_SOURCES = \
simple-account-manager.h \
simple-conn.c \
simple-conn.h \
- textchan-null.c \
- textchan-null.h \
+ echo-chan.c \
+ echo-chan.h \
util.c \
util.h \
$(NULL)
@@ -84,7 +84,7 @@ tp-test-contactlist.vapi: tp-test-contactlist.gir tp-test-contactlist.deps
@test x$(srcdir) = x. || cp $(srcdir)/tp-test-contactlist.deps .
$(MAKE) $(AM_MAKEFLAGS) tp-test-contactlist.gir
$(AM_V_GEN)$(VAPIGEN) $(VAPIGENFLAGS) --library tp-test-contactlist \
- tp-test-contactlist.gir
+ tp-test-contactlist.gir && sed -i "s/Tp\./TelepathyGLib\./g" $@
touch $@
endif
diff --git a/tests/lib/telepathy/contactlist/backend.c b/tests/lib/telepathy/contactlist/backend.c
index b7193dc2..243b4a6b 100644
--- a/tests/lib/telepathy/contactlist/backend.c
+++ b/tests/lib/telepathy/contactlist/backend.c
@@ -20,9 +20,8 @@
#include <config.h>
#include <glib.h>
-#include <telepathy-glib/base-connection.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/svc-account.h>
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
#include "simple-account.h"
#include "simple-account-manager.h"
@@ -133,7 +132,7 @@ void
tp_tests_backend_set_up (TpTestsBackend *self)
{
TpTestsBackendPrivate *priv = self->priv;
- TpSimpleClientFactory *factory;
+ TpClientFactory *factory;
GError *error = NULL;
/* Override the handler set in the general Folks.TestCase class */
@@ -160,7 +159,7 @@ tp_tests_backend_set_up (TpTestsBackend *self)
priv->client_am = tp_account_manager_dup ();
factory = tp_proxy_get_factory (priv->client_am);
- tp_simple_client_factory_add_contact_features_varargs (factory,
+ tp_client_factory_add_contact_features_varargs (factory,
TP_CONTACT_FEATURE_ALIAS,
TP_CONTACT_FEATURE_AVATAR_DATA,
TP_CONTACT_FEATURE_AVATAR_TOKEN,
@@ -169,7 +168,7 @@ tp_tests_backend_set_up (TpTestsBackend *self)
TP_CONTACT_FEATURE_PRESENCE,
TP_CONTACT_FEATURE_CONTACT_INFO,
TP_CONTACT_FEATURE_CONTACT_GROUPS,
- TP_CONTACT_FEATURE_INVALID);
+ 0);
}
static void
@@ -268,7 +267,7 @@ tp_tests_backend_add_account (TpTestsBackend *self,
const gchar *account)
{
TpTestsBackendPrivate *priv = self->priv;
- TpSimpleClientFactory *factory;
+ TpClientFactory *factory;
AccountData *data;
gchar *conn_path;
GError *error = NULL;
@@ -286,7 +285,7 @@ tp_tests_backend_add_account (TpTestsBackend *self,
g_assert_no_error (error);
factory = tp_proxy_get_factory (priv->client_am);
- data->client_conn = tp_simple_client_factory_ensure_connection (factory,
+ data->client_conn = tp_client_factory_ensure_connection (factory,
conn_path, NULL, &error);
g_assert_no_error (error);
diff --git a/tests/lib/telepathy/contactlist/broken-client-types-conn.c b/tests/lib/telepathy/contactlist/broken-client-types-conn.c
new file mode 100644
index 00000000..0ffd9929
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/broken-client-types-conn.c
@@ -0,0 +1,65 @@
+/*
+ * broken-client-types-conn.c - a connection with a broken client
+ * types implementation which inexplicably returns presence information!
+ *
+ * Copyright Ā© 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "broken-client-types-conn.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsBrokenClientTypesConnection,
+ tp_tests_broken_client_types_connection,
+ TP_TESTS_TYPE_CONTACTS_CONNECTION,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CLIENT_TYPES,
+ NULL);
+ );
+
+static void
+tp_tests_broken_client_types_connection_init (
+ TpTestsBrokenClientTypesConnection *self)
+{
+}
+
+static void
+broken_fill_client_types (
+ GObject *object,
+ const GArray *contacts,
+ GHashTable *attributes)
+{
+ guint i;
+
+ for (i = 0; i < contacts->len; i++)
+ {
+ TpHandle handle = g_array_index (contacts, guint, i);
+ /* Muahaha. Actually we add Presence information. */
+ GValueArray *presence = tp_value_array_build (3,
+ G_TYPE_UINT, TP_CONNECTION_PRESENCE_TYPE_AVAILABLE,
+ G_TYPE_STRING, "available",
+ G_TYPE_STRING, "hi mum!",
+ G_TYPE_INVALID);
+
+ tp_contacts_mixin_set_contact_attribute (attributes,
+ handle,
+ TP_TOKEN_CONNECTION_INTERFACE_PRESENCE_PRESENCE,
+ tp_g_value_slice_new_take_boxed (G_TYPE_VALUE_ARRAY, presence));
+ }
+}
+
+static void
+tp_tests_broken_client_types_connection_class_init (
+ TpTestsBrokenClientTypesConnectionClass *klass)
+{
+ TpTestsContactsConnectionClass *cc_class =
+ TP_TESTS_CONTACTS_CONNECTION_CLASS (klass);
+
+ cc_class->fill_client_types = broken_fill_client_types;
+}
diff --git a/tests/lib/telepathy/contactlist/broken-client-types-conn.h b/tests/lib/telepathy/contactlist/broken-client-types-conn.h
new file mode 100644
index 00000000..ad36d7d5
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/broken-client-types-conn.h
@@ -0,0 +1,50 @@
+/*
+ * broken-client-types-conn.h - header for a connection with a broken client
+ * types implementation which inexplicably returns presence information!
+ *
+ * Copyright Ā© 2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef TP_TESTS_BROKEN_CLIENT_TYPES_CONN_H
+#define TP_TESTS_BROKEN_CLIENT_TYPES_CONN_H
+
+#include "contacts-conn.h"
+
+typedef struct _TpTestsBrokenClientTypesConnection TpTestsBrokenClientTypesConnection;
+typedef struct _TpTestsBrokenClientTypesConnectionClass TpTestsBrokenClientTypesConnectionClass;
+typedef struct _TpTestsBrokenClientTypesConnectionPrivate TpTestsBrokenClientTypesConnectionPrivate;
+
+struct _TpTestsBrokenClientTypesConnectionClass {
+ TpTestsContactsConnectionClass parent_class;
+};
+
+struct _TpTestsBrokenClientTypesConnection {
+ TpTestsContactsConnection parent;
+
+ TpTestsBrokenClientTypesConnectionPrivate *priv;
+};
+
+GType tp_tests_broken_client_types_connection_get_type (void);
+
+/* HI MUM */
+#define TP_TESTS_TYPE_BROKEN_CLIENT_TYPES_CONNECTION \
+ (tp_tests_broken_client_types_connection_get_type ())
+#define TP_TESTS_BROKEN_CLIENT_TYPES_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_BROKEN_CLIENT_TYPES_CONNECTION, \
+ TpTestsBrokenClientTypesConnection))
+#define TP_TESTS_BROKEN_CLIENT_TYPES_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_BROKEN_CLIENT_TYPES_CONNECTION, \
+ TpTestsBrokenClientTypesConnectionClass))
+#define TP_TESTS_IS_BROKEN_CLIENT_TYPES_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_BROKEN_CLIENT_TYPES_CONNECTION))
+#define TP_TESTS_IS_BROKEN_CLIENT_TYPES_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_BROKEN_CLIENT_TYPES_CONNECTION))
+#define TP_TESTS_BROKEN_CLIENT_TYPES_CONNECTION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_BROKEN_CLIENT_TYPES_CONNECTION, \
+ TpTestsBrokenClientTypesConnectionClass))
+
+#endif // TP_TESTS_BROKEN_CLIENT_TYPES_CONN_H
diff --git a/tests/lib/telepathy/contactlist/bug-19101-conn.c b/tests/lib/telepathy/contactlist/bug-19101-conn.c
new file mode 100644
index 00000000..52a4b683
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/bug-19101-conn.c
@@ -0,0 +1,74 @@
+/*
+ * bug-19101-conn.c - a broken connection to reproduce bug #19101
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "bug-19101-conn.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#include "debug.h"
+
+static void contacts_iface_init (gpointer g_iface, gpointer iface_data);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsBug19101Connection,
+ tp_tests_bug19101_connection, TP_TESTS_TYPE_CONTACTS_CONNECTION,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS,
+ contacts_iface_init);
+ )
+
+static void
+tp_tests_bug19101_connection_init (TpTestsBug19101Connection *self)
+{
+}
+
+static void
+tp_tests_bug19101_connection_class_init (TpTestsBug19101ConnectionClass *klass)
+{
+}
+
+/* A broken implementation of GetContactByID, which returns an empty dict
+ * of attributes for each id.
+ */
+static void
+tp_tests_bug19101_connection_get_contact_by_id (
+ TpSvcConnectionInterfaceContacts *iface,
+ const gchar *id,
+ const char **interfaces,
+ DBusGMethodInvocation *context)
+{
+ TpBaseConnection *base_conn = TP_BASE_CONNECTION (iface);
+ TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
+ base_conn, TP_HANDLE_TYPE_CONTACT);
+ TpHandle handle;
+ GHashTable *table;
+
+ handle = tp_handle_ensure (contact_repo, id, NULL, NULL);
+ table = g_hash_table_new (NULL, NULL);
+
+ tp_svc_connection_interface_contacts_return_from_get_contact_by_id (
+ context, handle, table);
+
+ g_hash_table_unref (table);
+}
+
+static void
+contacts_iface_init (gpointer g_iface, gpointer iface_data)
+{
+ TpSvcConnectionInterfaceContactsClass *klass =
+ (TpSvcConnectionInterfaceContactsClass *) g_iface;
+
+#define IMPLEMENT(x) tp_svc_connection_interface_contacts_implement_##x ( \
+ klass, tp_tests_bug19101_connection_##x)
+ IMPLEMENT(get_contact_by_id);
+#undef IMPLEMENT
+}
diff --git a/tests/lib/telepathy/contactlist/bug-19101-conn.h b/tests/lib/telepathy/contactlist/bug-19101-conn.h
new file mode 100644
index 00000000..23b670e3
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/bug-19101-conn.h
@@ -0,0 +1,51 @@
+/*
+ * bug-19101-conn.h - header for a broken connection to reproduce bug #19101
+ *
+ * Copyright (C) 2007-2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_BUG19101_CONN_H__
+#define __TP_TESTS_BUG19101_CONN_H__
+
+#include "contacts-conn.h"
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsBug19101Connection TpTestsBug19101Connection;
+typedef struct _TpTestsBug19101ConnectionClass TpTestsBug19101ConnectionClass;
+
+struct _TpTestsBug19101ConnectionClass {
+ TpTestsContactsConnectionClass parent_class;
+};
+
+struct _TpTestsBug19101Connection {
+ TpTestsContactsConnection parent;
+};
+
+GType tp_tests_bug19101_connection_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_BUG19101_CONNECTION \
+ (tp_tests_bug19101_connection_get_type ())
+#define BUG_19101_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_BUG19101_CONNECTION, \
+ TpTestsBug19101Connection))
+#define BUG_19101_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_BUG19101_CONNECTION, \
+ TpTestsBug19101ConnectionClass))
+#define BUG_19101_IS_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_BUG19101_CONNECTION))
+#define BUG_19101_IS_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_BUG19101_CONNECTION))
+#define BUG_19101_CONNECTION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_BUG19101_CONNECTION, \
+ TpTestsBug19101ConnectionClass))
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_BUG19101_CONN_H__ */
diff --git a/tests/lib/telepathy/contactlist/contact-list-manager.c b/tests/lib/telepathy/contactlist/contact-list-manager.c
index b816673a..bce8e21a 100644
--- a/tests/lib/telepathy/contactlist/contact-list-manager.c
+++ b/tests/lib/telepathy/contactlist/contact-list-manager.c
@@ -26,8 +26,7 @@ struct _TpTestsContactListManagerPrivate
GHashTable *contact_details;
TpHandleRepoIface *contact_repo;
- TpHandleRepoIface *group_repo;
- TpHandleSet *groups;
+ GHashTable *groups;
};
static void contact_groups_iface_init (TpContactGroupListInterface *iface);
@@ -49,7 +48,7 @@ typedef struct {
TpSubscriptionState subscribe;
TpSubscriptionState publish;
gchar *publish_request;
- TpHandleSet *groups;
+ GHashTable *groups;
TpHandle handle;
TpHandleRepoIface *contact_repo;
@@ -61,7 +60,7 @@ contact_detail_destroy (gpointer p)
ContactDetails *d = p;
g_free (d->publish_request);
- tp_handle_set_destroy (d->groups);
+ g_hash_table_unref (d->groups);
g_slice_free (ContactDetails, d);
}
@@ -86,7 +85,7 @@ ensure_contact (TpTestsContactListManager *self,
d->subscribe = TP_SUBSCRIPTION_STATE_NO;
d->publish = TP_SUBSCRIPTION_STATE_NO;
d->publish_request = NULL;
- d->groups = tp_handle_set_new (self->priv->group_repo);
+ d->groups = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
d->handle = handle;
d->contact_repo = self->priv->contact_repo;
@@ -117,7 +116,7 @@ close_all (TpTestsContactListManager *self)
self->priv->status_changed_id = 0;
}
tp_clear_pointer (&self->priv->contact_details, g_hash_table_unref);
- tp_clear_pointer (&self->priv->groups, tp_handle_set_destroy);
+ tp_clear_pointer (&self->priv->groups, g_hash_table_unref);
}
static void
@@ -197,16 +196,15 @@ contact_list_dup_groups (TpBaseContactList *base)
if (self->priv->groups != NULL)
{
- TpIntsetFastIter iter;
- TpHandle group;
+ GHashTableIter iter;
+ gpointer name;
- ret = g_ptr_array_sized_new (tp_handle_set_size (self->priv->groups) + 1);
+ ret = g_ptr_array_sized_new (g_hash_table_size (self->priv->groups) + 1);
- tp_intset_fast_iter_init (&iter, tp_handle_set_peek (self->priv->groups));
- while (tp_intset_fast_iter_next (&iter, &group))
+ g_hash_table_iter_init (&iter, self->priv->groups);
+ while (g_hash_table_iter_next (&iter, &name, NULL))
{
- g_ptr_array_add (ret, g_strdup (tp_handle_inspect (
- self->priv->group_repo, group)));
+ g_ptr_array_add (ret, g_strdup (name));
}
}
else
@@ -229,16 +227,15 @@ contact_list_dup_contact_groups (TpBaseContactList *base,
if (d != NULL && d->groups != NULL)
{
- TpIntsetFastIter iter;
- TpHandle group;
+ GHashTableIter iter;
+ gpointer name;
- ret = g_ptr_array_sized_new (tp_handle_set_size (d->groups) + 1);
+ ret = g_ptr_array_sized_new (g_hash_table_size (d->groups) + 1);
- tp_intset_fast_iter_init (&iter, tp_handle_set_peek (d->groups));
- while (tp_intset_fast_iter_next (&iter, &group))
+ g_hash_table_iter_init (&iter, d->groups);
+ while (g_hash_table_iter_next (&iter, &name, NULL))
{
- g_ptr_array_add (ret, g_strdup (tp_handle_inspect (
- self->priv->group_repo, group)));
+ g_ptr_array_add (ret, g_strdup (name));
}
}
else
@@ -256,14 +253,13 @@ contact_list_dup_group_members (TpBaseContactList *base,
const gchar *group)
{
TpTestsContactListManager *self = TP_TESTS_CONTACT_LIST_MANAGER (base);
- TpHandleSet *set;
- TpHandle group_handle;
GHashTableIter iter;
gpointer k, v;
+ TpHandleSet *set;
set = tp_handle_set_new (self->priv->contact_repo);
- group_handle = tp_handle_lookup (self->priv->group_repo, group, NULL, NULL);
- if (G_UNLIKELY (group_handle == 0))
+
+ if (G_UNLIKELY (g_hash_table_lookup (self->priv->groups, group) == NULL))
{
/* clearly it doesn't have members */
return set;
@@ -275,13 +271,31 @@ contact_list_dup_group_members (TpBaseContactList *base,
ContactDetails *d = v;
if (d->groups != NULL &&
- tp_handle_set_is_member (d->groups, group_handle))
+ g_hash_table_lookup (d->groups, group) != NULL)
tp_handle_set_add (set, GPOINTER_TO_UINT (k));
}
return set;
}
+static GPtrArray *
+group_difference (GHashTable *left,
+ GHashTable *right)
+{
+ GHashTableIter iter;
+ GPtrArray *set = g_ptr_array_sized_new (g_hash_table_size (left));
+ gpointer name;
+
+ g_hash_table_iter_init (&iter, left);
+ while (g_hash_table_iter_next (&iter, &name, NULL))
+ {
+ if (g_hash_table_lookup (right, name) == NULL)
+ g_ptr_array_add (set, name);
+ }
+
+ return set;
+}
+
static void
contact_list_set_contact_groups_async (TpBaseContactList *base,
TpHandle contact,
@@ -292,25 +306,24 @@ contact_list_set_contact_groups_async (TpBaseContactList *base,
{
TpTestsContactListManager *self = TP_TESTS_CONTACT_LIST_MANAGER (base);
ContactDetails *d;
- TpIntset *set, *added_set, *removed_set;
- GPtrArray *added_names, *removed_names;
+ GHashTable *tmp;
+ GPtrArray *added, *removed;
GPtrArray *new_groups;
- TpIntsetFastIter iter;
- TpHandle group_handle;
guint i;
d = ensure_contact (self, contact);
new_groups = g_ptr_array_new ();
- set = tp_intset_new ();
+ /* make a hash table so we only have one difference function */
+ tmp = g_hash_table_new (g_str_hash, g_str_equal);
for (i = 0; i < n; i++)
{
- group_handle = tp_handle_ensure (self->priv->group_repo, names[i], NULL, NULL);
- tp_intset_add (set, group_handle);
+ g_hash_table_insert (tmp, (gpointer) names[i], GUINT_TO_POINTER (1));
- if (!tp_handle_set_is_member (self->priv->groups, group_handle))
+ if (g_hash_table_lookup (self->priv->groups, names[i]) == NULL)
{
- tp_handle_set_add (self->priv->groups, group_handle);
+ g_hash_table_insert (self->priv->groups, g_strdup (names[i]),
+ GUINT_TO_POINTER (1));
g_ptr_array_add (new_groups, (gchar *) names[i]);
}
}
@@ -321,42 +334,30 @@ contact_list_set_contact_groups_async (TpBaseContactList *base,
(const gchar * const *) new_groups->pdata, new_groups->len);
}
- added_set = tp_intset_difference (set, tp_handle_set_peek (d->groups));
- added_names = g_ptr_array_sized_new (tp_intset_size (added_set));
- tp_intset_fast_iter_init (&iter, added_set);
- while (tp_intset_fast_iter_next (&iter, &group_handle))
- {
- g_ptr_array_add (added_names, (gchar *) tp_handle_inspect (
- self->priv->group_repo, group_handle));
- }
- tp_intset_destroy (added_set);
+ /* see which groups were added and which were removed */
+ added = group_difference (tmp, d->groups);
+ removed = group_difference (d->groups, tmp);
- removed_set = tp_intset_difference (tp_handle_set_peek (d->groups), set);
- removed_names = g_ptr_array_sized_new (tp_intset_size (removed_set));
- tp_intset_fast_iter_init (&iter, removed_set);
- while (tp_intset_fast_iter_next (&iter, &group_handle))
- {
- g_ptr_array_add (removed_names, (gchar *) tp_handle_inspect (
- self->priv->group_repo, group_handle));
- }
- tp_intset_destroy (removed_set);
+ g_hash_table_unref (tmp);
- tp_handle_set_destroy (d->groups);
- d->groups = tp_handle_set_new_from_intset (self->priv->group_repo, set);
- tp_intset_destroy (set);
+ /* update the list of groups the contact thinks it has */
+ g_hash_table_remove_all (d->groups);
+ for (i = 0; i < n; i++)
+ g_hash_table_insert (d->groups, g_strdup (names[i]), GUINT_TO_POINTER (1));
- if (added_names->len > 0 || removed_names->len > 0)
+ /* signal the change */
+ if (added->len > 0 || removed->len > 0)
{
tp_base_contact_list_one_contact_groups_changed (base, contact,
- (const gchar * const *) added_names->pdata, added_names->len,
- (const gchar * const *) removed_names->pdata, removed_names->len);
+ (const gchar * const *) added->pdata, added->len,
+ (const gchar * const *) removed->pdata, removed->len);
}
tp_simple_async_report_success_in_idle ((GObject *) self, callback,
user_data, contact_list_set_contact_groups_async);
- g_ptr_array_unref (added_names);
- g_ptr_array_unref (removed_names);
+ g_ptr_array_unref (added);
+ g_ptr_array_unref (removed);
g_ptr_array_unref (new_groups);
}
@@ -551,9 +552,8 @@ constructed (GObject *object)
self->priv->contact_repo = tp_base_connection_get_handles (self->priv->conn,
TP_HANDLE_TYPE_CONTACT);
- self->priv->group_repo = tp_base_connection_get_handles (self->priv->conn,
- TP_HANDLE_TYPE_GROUP);
- self->priv->groups = tp_handle_set_new (self->priv->group_repo);
+ self->priv->groups = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
}
static void
@@ -606,19 +606,17 @@ tp_tests_contact_list_manager_add_to_group (TpTestsContactListManager *self,
{
TpBaseContactList *base = TP_BASE_CONTACT_LIST (self);
ContactDetails *d = ensure_contact (self, member);
- TpHandle group_handle;
- group_handle = tp_handle_ensure (self->priv->group_repo,
- group_name, NULL, NULL);
+ g_hash_table_insert (d->groups, g_strdup (group_name), GUINT_TO_POINTER (1));
- if (!tp_handle_set_is_member (self->priv->groups, group_handle))
+ if (g_hash_table_lookup (self->priv->groups, group_name) == NULL)
{
- tp_handle_set_add (self->priv->groups, group_handle);
+ g_hash_table_insert (self->priv->groups, g_strdup (group_name),
+ GUINT_TO_POINTER (1));
tp_base_contact_list_groups_created ((TpBaseContactList *) self,
&group_name, 1);
}
- tp_handle_set_add (d->groups, group_handle);
tp_base_contact_list_one_contact_groups_changed (base, member,
&group_name, 1, NULL, 0);
}
@@ -629,14 +627,12 @@ tp_tests_contact_list_manager_remove_from_group (TpTestsContactListManager *self
{
TpBaseContactList *base = TP_BASE_CONTACT_LIST (self);
ContactDetails *d = lookup_contact (self, member);
- TpHandle group_handle;
if (d == NULL)
return;
- group_handle = tp_handle_ensure (self->priv->group_repo, group_name, NULL, NULL);
+ g_hash_table_remove (d->groups, group_name);
- tp_handle_set_remove (d->groups, group_handle);
tp_base_contact_list_one_contact_groups_changed (base, member,
NULL, 0, &group_name, 1);
}
diff --git a/tests/lib/telepathy/contactlist/contact-list-manager.h b/tests/lib/telepathy/contactlist/contact-list-manager.h
index 8be787c3..bc44863c 100644
--- a/tests/lib/telepathy/contactlist/contact-list-manager.h
+++ b/tests/lib/telepathy/contactlist/contact-list-manager.h
@@ -12,7 +12,7 @@
#ifndef __TP_TESTS_CONTACT_LIST_MANAGER_H__
#define __TP_TESTS_CONTACT_LIST_MANAGER_H__
-#include <telepathy-glib/base-contact-list.h>
+#include <telepathy-glib/telepathy-glib.h>
G_BEGIN_DECLS
diff --git a/tests/lib/telepathy/contactlist/contacts-conn.c b/tests/lib/telepathy/contactlist/contacts-conn.c
index 6f308809..3ba50a20 100644
--- a/tests/lib/telepathy/contactlist/contacts-conn.c
+++ b/tests/lib/telepathy/contactlist/contacts-conn.c
@@ -15,19 +15,13 @@
#include <dbus/dbus-glib.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/errors.h>
-#include <telepathy-glib/gtypes.h>
-#include <telepathy-glib/handle-repo-dynamic.h>
-#include <telepathy-glib/util.h>
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
#include "debug.h"
static void init_aliasing (gpointer, gpointer);
static void init_avatars (gpointer, gpointer);
-static void init_location (gpointer, gpointer);
-static void init_contact_caps (gpointer, gpointer);
static void init_contact_info (gpointer, gpointer);
static void conn_avatars_properties_getter (GObject *object, GQuark interface,
GQuark name, GValue *value, gpointer getter_data);
@@ -41,13 +35,9 @@ G_DEFINE_TYPE_WITH_CODE (TpTestsContactsConnection,
init_avatars);
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_PRESENCE,
tp_presence_mixin_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
- tp_presence_mixin_simple_presence_iface_init)
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_LOCATION,
- init_location)
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_LOCATION, NULL)
G_IMPLEMENT_INTERFACE (
- TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
- init_contact_caps)
+ TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_CAPABILITIES, NULL)
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACT_INFO,
init_contact_info)
G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION_INTERFACE_CONTACTS,
@@ -402,11 +392,17 @@ constructed (GObject *object)
if (parent_impl != NULL)
parent_impl (object);
+ self->priv->list_manager = g_object_new (TP_TESTS_TYPE_CONTACT_LIST_MANAGER,
+ "connection", self, NULL);
+
tp_contacts_mixin_init (object,
G_STRUCT_OFFSET (TpTestsContactsConnection, contacts_mixin));
tp_base_connection_register_with_contacts_mixin (base);
if (self->priv->list_manager)
- tp_base_contact_list_mixin_register_with_contacts_mixin (base);
+ {
+ tp_base_contact_list_mixin_register_with_contacts_mixin (
+ TP_BASE_CONTACT_LIST (self->priv->list_manager), base);
+ }
tp_contacts_mixin_add_contact_attributes_iface (object,
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
aliasing_fill_contact_attributes);
@@ -428,7 +424,7 @@ constructed (GObject *object)
tp_presence_mixin_init (object,
G_STRUCT_OFFSET (TpTestsContactsConnection, presence_mixin));
- tp_presence_mixin_simple_presence_register_with_contacts_mixin (object);
+ tp_presence_mixin_register_with_contacts_mixin (object);
}
static const TpPresenceStatusOptionalArgumentSpec can_have_message[] = {
@@ -459,8 +455,7 @@ my_status_available (GObject *object,
static GHashTable *
my_get_contact_statuses (GObject *object,
- const GArray *contacts,
- GError **error)
+ const GArray *contacts)
{
TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (object);
GHashTable *result = g_hash_table_new_full (g_direct_hash, g_direct_equal,
@@ -529,24 +524,13 @@ my_get_maximum_status_message_length_cb (GObject *obj)
static GPtrArray *
create_channel_managers (TpBaseConnection *conn)
{
- TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (conn);
- GPtrArray *ret = g_ptr_array_sized_new (1);
-
- self->priv->list_manager = g_object_new (TP_TESTS_TYPE_CONTACT_LIST_MANAGER,
- "connection", conn, NULL);
-
- g_ptr_array_add (ret, self->priv->list_manager);
-
- return ret;
+ return g_ptr_array_new ();
}
-static void
-tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass)
+static GPtrArray *
+tp_tests_contacts_get_interfaces_always_present (TpBaseConnection *base)
{
- TpBaseConnectionClass *base_class =
- (TpBaseConnectionClass *) klass;
- GObjectClass *object_class = (GObjectClass *) klass;
- TpPresenceMixinClass *mixin_class;
+ GPtrArray *interfaces;
static const gchar *interfaces_always_present[] = {
TP_IFACE_CONNECTION_INTERFACE_ALIASING,
TP_IFACE_CONNECTION_INTERFACE_AVATARS,
@@ -554,13 +538,56 @@ tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass)
TP_IFACE_CONNECTION_INTERFACE_CONTACT_LIST,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_GROUPS,
TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
- TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
TP_IFACE_CONNECTION_INTERFACE_LOCATION,
TP_IFACE_CONNECTION_INTERFACE_CLIENT_TYPES,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_CAPABILITIES,
TP_IFACE_CONNECTION_INTERFACE_CONTACT_INFO,
- TP_IFACE_CONNECTION_INTERFACE_REQUESTS,
NULL };
+ guint i;
+
+ interfaces = TP_BASE_CONNECTION_CLASS (
+ tp_tests_contacts_connection_parent_class)->get_interfaces_always_present (base);
+
+ for (i = 0; interfaces_always_present[i] != NULL; i++)
+ g_ptr_array_add (interfaces, (gchar *) interfaces_always_present[i]);
+
+ return interfaces;
+}
+
+enum
+{
+ ALIASING_DP_ALIAS_FLAGS,
+};
+
+static void
+aliasing_get_dbus_property (GObject *object,
+ GQuark interface,
+ GQuark name,
+ GValue *value,
+ gpointer user_data)
+{
+ switch (GPOINTER_TO_UINT (user_data))
+ {
+ case ALIASING_DP_ALIAS_FLAGS:
+ g_value_set_uint (value, TP_CONNECTION_ALIAS_FLAG_USER_SET);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass)
+{
+ TpBaseConnectionClass *base_class =
+ (TpBaseConnectionClass *) klass;
+ GObjectClass *object_class = (GObjectClass *) klass;
+ TpPresenceMixinClass *mixin_class;
+ static TpDBusPropertiesMixinPropImpl aliasing_props[] = {
+ { "AliasFlags", GUINT_TO_POINTER (ALIASING_DP_ALIAS_FLAGS), NULL },
+ { NULL }
+ };
static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
{ TP_IFACE_CONNECTION_INTERFACE_AVATARS,
conn_avatars_properties_getter,
@@ -572,6 +599,11 @@ tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass)
NULL,
conn_contact_info_properties,
},
+ { TP_IFACE_CONNECTION_INTERFACE_ALIASING,
+ aliasing_get_dbus_property,
+ NULL,
+ aliasing_props,
+ },
{ NULL }
};
@@ -579,7 +611,7 @@ tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass)
object_class->finalize = finalize;
g_type_class_add_private (klass, sizeof (TpTestsContactsConnectionPrivate));
- base_class->interfaces_always_present = interfaces_always_present;
+ base_class->get_interfaces_always_present = tp_tests_contacts_get_interfaces_always_present;
base_class->create_channel_managers = create_channel_managers;
tp_contacts_mixin_class_init (object_class,
@@ -593,7 +625,7 @@ tp_tests_contacts_connection_class_init (TpTestsContactsConnectionClass *klass)
mixin_class->get_maximum_status_message_length =
my_get_maximum_status_message_length_cb;
- tp_presence_mixin_simple_presence_init_dbus_properties (object_class);
+ tp_presence_mixin_init_dbus_properties (object_class);
klass->properties_class.interfaces = prop_interfaces;
tp_dbus_properties_mixin_class_init (object_class,
@@ -623,34 +655,23 @@ tp_tests_contacts_connection_change_aliases (TpTestsContactsConnection *self,
const TpHandle *handles,
const gchar * const *aliases)
{
- GPtrArray *structs = g_ptr_array_sized_new (n);
+ GHashTable *changes = g_hash_table_new (NULL, NULL);
guint i;
for (i = 0; i < n; i++)
{
- GValueArray *pair = g_value_array_new (2);
-
DEBUG ("contact#%u -> %s", handles[i], aliases[i]);
g_hash_table_insert (self->priv->aliases,
GUINT_TO_POINTER (handles[i]), g_strdup (aliases[i]));
- g_value_array_append (pair, NULL);
- g_value_init (pair->values + 0, G_TYPE_UINT);
- g_value_set_uint (pair->values + 0, handles[i]);
-
- g_value_array_append (pair, NULL);
- g_value_init (pair->values + 1, G_TYPE_STRING);
- g_value_set_string (pair->values + 1, aliases[i]);
-
- g_ptr_array_add (structs, pair);
+ g_hash_table_insert (changes,
+ GUINT_TO_POINTER (handles[i]), (gchar *) aliases[i]);
}
- tp_svc_connection_interface_aliasing_emit_aliases_changed (self,
- structs);
+ tp_svc_connection_interface_aliasing_emit_aliases_changed (self, changes);
- g_ptr_array_foreach (structs, (GFunc) g_value_array_free, NULL);
- g_ptr_array_unref (structs);
+ g_hash_table_unref (changes);
}
void
@@ -793,60 +814,6 @@ tp_tests_contacts_connection_set_default_contact_info (
}
static void
-my_get_alias_flags (TpSvcConnectionInterfaceAliasing *aliasing,
- DBusGMethodInvocation *context)
-{
- TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
-
- TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
- tp_svc_connection_interface_aliasing_return_from_get_alias_flags (context,
- TP_CONNECTION_ALIAS_FLAG_USER_SET);
-}
-
-static void
-my_get_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
- const GArray *contacts,
- DBusGMethodInvocation *context)
-{
- TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (aliasing);
- TpBaseConnection *base = TP_BASE_CONNECTION (aliasing);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
- TP_HANDLE_TYPE_CONTACT);
- GHashTable *result;
- GError *error = NULL;
- guint i;
-
- TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
-
- if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
-
- for (i = 0; i < contacts->len; i++)
- {
- TpHandle handle = g_array_index (contacts, TpHandle, i);
- const gchar *alias = g_hash_table_lookup (self->priv->aliases,
- GUINT_TO_POINTER (handle));
-
- if (alias == NULL)
- g_hash_table_insert (result, GUINT_TO_POINTER (handle),
- (gchar *) tp_handle_inspect (contact_repo, handle));
- else
- g_hash_table_insert (result, GUINT_TO_POINTER (handle),
- (gchar *) alias);
- }
-
- tp_svc_connection_interface_aliasing_return_from_get_aliases (context,
- result);
- g_hash_table_unref (result);
-}
-
-static void
my_request_aliases (TpSvcConnectionInterfaceAliasing *aliasing,
const GArray *contacts,
DBusGMethodInvocation *context)
@@ -950,105 +917,12 @@ init_aliasing (gpointer g_iface,
#define IMPLEMENT(x) tp_svc_connection_interface_aliasing_implement_##x (\
klass, my_##x)
- IMPLEMENT(get_alias_flags);
IMPLEMENT(request_aliases);
- IMPLEMENT(get_aliases);
IMPLEMENT(set_aliases);
#undef IMPLEMENT
}
static void
-my_get_avatar_tokens (TpSvcConnectionInterfaceAvatars *avatars,
- const GArray *contacts,
- DBusGMethodInvocation *context)
-{
- TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (avatars);
- TpBaseConnection *base = TP_BASE_CONNECTION (avatars);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
- TP_HANDLE_TYPE_CONTACT);
- GError *error = NULL;
- GHashTable *result;
- guint i;
-
- TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
-
- if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
-
- for (i = 0; i < contacts->len; i++)
- {
- TpHandle handle = g_array_index (contacts, TpHandle, i);
- AvatarData *a = g_hash_table_lookup (self->priv->avatars,
- GUINT_TO_POINTER (handle));
-
- if (a == NULL || a->token == NULL)
- {
- /* we're expected to do a round-trip to the server to find out
- * their token, so we have to give some sort of result. Assume
- * no avatar, here */
- a = avatar_data_new (NULL, NULL, "");
- g_hash_table_insert (self->priv->avatars,
- GUINT_TO_POINTER (handle), a);
- tp_svc_connection_interface_avatars_emit_avatar_updated (self,
- handle, a->token);
- }
-
- g_hash_table_insert (result, GUINT_TO_POINTER (handle),
- a->token);
- }
-
- tp_svc_connection_interface_avatars_return_from_get_known_avatar_tokens (
- context, result);
- g_hash_table_unref (result);
-}
-
-static void
-my_get_known_avatar_tokens (TpSvcConnectionInterfaceAvatars *avatars,
- const GArray *contacts,
- DBusGMethodInvocation *context)
-{
- TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (avatars);
- TpBaseConnection *base = TP_BASE_CONNECTION (avatars);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
- TP_HANDLE_TYPE_CONTACT);
- GError *error = NULL;
- GHashTable *result;
- guint i;
-
- TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
-
- if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
-
- for (i = 0; i < contacts->len; i++)
- {
- TpHandle handle = g_array_index (contacts, TpHandle, i);
- AvatarData *a = g_hash_table_lookup (self->priv->avatars,
- GUINT_TO_POINTER (handle));
- const gchar *token = a ? a->token : NULL;
-
- g_hash_table_insert (result, GUINT_TO_POINTER (handle),
- (gchar *) (token != NULL ? token : ""));
- }
-
- tp_svc_connection_interface_avatars_return_from_get_known_avatar_tokens (
- context, result);
- g_hash_table_unref (result);
-}
-
-static void
my_request_avatars (TpSvcConnectionInterfaceAvatars *avatars,
const GArray *contacts,
DBusGMethodInvocation *context)
@@ -1112,8 +986,6 @@ init_avatars (gpointer g_iface,
#define IMPLEMENT(x) tp_svc_connection_interface_avatars_implement_##x (\
klass, my_##x)
/* IMPLEMENT(get_avatar_requirements); */
- IMPLEMENT(get_avatar_tokens);
- IMPLEMENT(get_known_avatar_tokens);
/* IMPLEMENT(request_avatar); */
IMPLEMENT(request_avatars);
/* IMPLEMENT(set_avatar); */
@@ -1121,113 +993,6 @@ init_avatars (gpointer g_iface,
#undef IMPLEMENT
}
-static void
-my_get_locations (TpSvcConnectionInterfaceLocation *avatars,
- const GArray *contacts,
- DBusGMethodInvocation *context)
-{
- TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (avatars);
- TpBaseConnection *base = TP_BASE_CONNECTION (avatars);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
- TP_HANDLE_TYPE_CONTACT);
- GError *error = NULL;
- GHashTable *result;
- guint i;
-
- TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
-
- if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
-
- for (i = 0; i < contacts->len; i++)
- {
- TpHandle handle = g_array_index (contacts, TpHandle, i);
- GHashTable *location = g_hash_table_lookup (self->priv->locations,
- GUINT_TO_POINTER (handle));
-
- if (location != NULL)
- {
- g_hash_table_insert (result, GUINT_TO_POINTER (handle), location);
- }
- }
-
- tp_svc_connection_interface_location_return_from_get_locations (
- context, result);
- g_hash_table_unref (result);
-}
-
-static void
-init_location (gpointer g_iface,
- gpointer iface_data)
-{
- TpSvcConnectionInterfaceLocationClass *klass = g_iface;
-
-#define IMPLEMENT(x) tp_svc_connection_interface_location_implement_##x (\
- klass, my_##x)
- IMPLEMENT(get_locations);
-#undef IMPLEMENT
-}
-
-static void
-my_get_contact_capabilities (TpSvcConnectionInterfaceContactCapabilities *obj,
- const GArray *contacts,
- DBusGMethodInvocation *context)
-{
- TpTestsContactsConnection *self = TP_TESTS_CONTACTS_CONNECTION (obj);
- TpBaseConnection *base = TP_BASE_CONNECTION (obj);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (base,
- TP_HANDLE_TYPE_CONTACT);
- GError *error = NULL;
- GHashTable *result;
- guint i;
-
- TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
-
- if (!tp_handles_are_valid (contact_repo, contacts, FALSE, &error))
- {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- result = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
-
- for (i = 0; i < contacts->len; i++)
- {
- TpHandle handle = g_array_index (contacts, TpHandle, i);
- GPtrArray *arr = g_hash_table_lookup (self->priv->capabilities,
- GUINT_TO_POINTER (handle));
-
- if (arr != NULL)
- {
- g_hash_table_insert (result, GUINT_TO_POINTER (handle), arr);
- }
- }
-
- tp_svc_connection_interface_contact_capabilities_return_from_get_contact_capabilities (
- context, result);
-
- g_hash_table_unref (result);
-}
-
-static void
-init_contact_caps (gpointer g_iface,
- gpointer iface_data)
-{
- TpSvcConnectionInterfaceContactCapabilitiesClass *klass = g_iface;
-
-#define IMPLEMENT(x) tp_svc_connection_interface_contact_capabilities_implement_##x (\
- klass, my_##x)
- IMPLEMENT(get_contact_capabilities);
-#undef IMPLEMENT
-}
-
static GPtrArray *
lookup_contact_info (TpTestsContactsConnection *self,
TpHandle handle)
@@ -1351,92 +1116,3 @@ init_contact_info (gpointer g_iface,
IMPLEMENT (set_contact_info);
#undef IMPLEMENT
}
-
-/* =============== Legacy version (no Contacts interface) ================= */
-
-G_DEFINE_TYPE (TpTestsLegacyContactsConnection,
- tp_tests_legacy_contacts_connection, TP_TESTS_TYPE_CONTACTS_CONNECTION);
-
-enum
-{
- LEGACY_PROP_HAS_IMMORTAL_HANDLES = 1
-};
-
-static void
-legacy_contacts_connection_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id)
- {
- case LEGACY_PROP_HAS_IMMORTAL_HANDLES:
- /* Pretend we don't. */
- g_value_set_boolean (value, FALSE);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-tp_tests_legacy_contacts_connection_init (TpTestsLegacyContactsConnection *self)
-{
-}
-
-static void
-tp_tests_legacy_contacts_connection_class_init (
- TpTestsLegacyContactsConnectionClass *klass)
-{
- /* Leave Contacts out of the interfaces we say are present, so clients
- * won't use it */
- static const gchar *interfaces_always_present[] = {
- TP_IFACE_CONNECTION_INTERFACE_ALIASING,
- TP_IFACE_CONNECTION_INTERFACE_AVATARS,
- TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
- TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
- TP_IFACE_CONNECTION_INTERFACE_LOCATION,
- TP_IFACE_CONNECTION_INTERFACE_REQUESTS,
- NULL };
- TpBaseConnectionClass *base_class =
- (TpBaseConnectionClass *) klass;
- GObjectClass *object_class = (GObjectClass *) klass;
-
- object_class->get_property = legacy_contacts_connection_get_property;
-
- base_class->interfaces_always_present = interfaces_always_present;
-
- g_object_class_override_property (object_class,
- LEGACY_PROP_HAS_IMMORTAL_HANDLES, "has-immortal-handles");
-}
-
-/* =============== No Requests and no ContactCapabilities ================= */
-
-G_DEFINE_TYPE (TpTestsNoRequestsConnection, tp_tests_no_requests_connection,
- TP_TESTS_TYPE_CONTACTS_CONNECTION);
-
-static void
-tp_tests_no_requests_connection_init (TpTestsNoRequestsConnection *self)
-{
-}
-
-static void
-tp_tests_no_requests_connection_class_init (
- TpTestsNoRequestsConnectionClass *klass)
-{
- static const gchar *interfaces_always_present[] = {
- TP_IFACE_CONNECTION_INTERFACE_ALIASING,
- TP_IFACE_CONNECTION_INTERFACE_AVATARS,
- TP_IFACE_CONNECTION_INTERFACE_CONTACTS,
- TP_IFACE_CONNECTION_INTERFACE_PRESENCE,
- TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
- TP_IFACE_CONNECTION_INTERFACE_LOCATION,
- NULL };
- TpBaseConnectionClass *base_class =
- (TpBaseConnectionClass *) klass;
-
- base_class->interfaces_always_present = interfaces_always_present;
- base_class->create_channel_managers = NULL;
-}
diff --git a/tests/lib/telepathy/contactlist/contacts-conn.h b/tests/lib/telepathy/contactlist/contacts-conn.h
index 64056e03..679b0eb6 100644
--- a/tests/lib/telepathy/contactlist/contacts-conn.h
+++ b/tests/lib/telepathy/contactlist/contacts-conn.h
@@ -13,9 +13,7 @@
#define __TP_TESTS_CONTACTS_CONN_H__
#include <glib-object.h>
-#include <telepathy-glib/base-connection.h>
-#include <telepathy-glib/contacts-mixin.h>
-#include <telepathy-glib/presence-mixin.h>
+#include <telepathy-glib/telepathy-glib.h>
#include "simple-conn.h"
#include "contact-list-manager.h"
@@ -113,78 +111,6 @@ void tp_tests_contacts_connection_set_default_contact_info (
TpTestsContactsConnection *self,
GPtrArray *info);
-/* Legacy version (no Contacts interface, and no immortal handles) */
-
-typedef struct _TpTestsLegacyContactsConnection TpTestsLegacyContactsConnection;
-typedef struct _TpTestsLegacyContactsConnectionClass TpTestsLegacyContactsConnectionClass;
-typedef struct _TpTestsLegacyContactsConnectionPrivate
- TpTestsLegacyContactsConnectionPrivate;
-
-struct _TpTestsLegacyContactsConnectionClass {
- TpTestsContactsConnectionClass parent_class;
-};
-
-struct _TpTestsLegacyContactsConnection {
- TpTestsContactsConnection parent;
-
- TpTestsLegacyContactsConnectionPrivate *priv;
-};
-
-GType tp_tests_legacy_contacts_connection_get_type (void);
-
-/* TYPE MACROS */
-#define TP_TESTS_TYPE_LEGACY_CONTACTS_CONNECTION \
- (tp_tests_legacy_contacts_connection_get_type ())
-#define LEGACY_TP_TESTS_CONTACTS_CONNECTION(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_LEGACY_CONTACTS_CONNECTION, \
- TpTestsLegacyContactsConnection))
-#define LEGACY_TP_TESTS_CONTACTS_CONNECTION_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_LEGACY_CONTACTS_CONNECTION, \
- TpTestsLegacyContactsConnectionClass))
-#define TP_TESTS_LEGACY_CONTACTS_IS_CONNECTION(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_LEGACY_CONTACTS_CONNECTION))
-#define TP_TESTS_LEGACY_CONTACTS_IS_CONNECTION_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_LEGACY_CONTACTS_CONNECTION))
-#define LEGACY_TP_TESTS_CONTACTS_CONNECTION_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_LEGACY_CONTACTS_CONNECTION, \
- TpTestsLegacyContactsConnectionClass))
-
-/* No Requests version */
-
-typedef struct _TpTestsNoRequestsConnection TpTestsNoRequestsConnection;
-typedef struct _TpTestsNoRequestsConnectionClass TpTestsNoRequestsConnectionClass;
-typedef struct _TpTestsNoRequestsConnectionPrivate
- TpTestsNoRequestsConnectionPrivate;
-
-struct _TpTestsNoRequestsConnectionClass {
- TpTestsContactsConnectionClass parent_class;
-};
-
-struct _TpTestsNoRequestsConnection {
- TpTestsContactsConnection parent;
-
- TpTestsNoRequestsConnectionPrivate *priv;
-};
-
-GType tp_tests_no_requests_connection_get_type (void);
-
-/* TYPE MACROS */
-#define TP_TESTS_TYPE_NO_REQUESTS_CONNECTION \
- (tp_tests_no_requests_connection_get_type ())
-#define TP_TESTS_NO_REQUESTS_CONNECTION(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_NO_REQUESTS_CONNECTION, \
- TpTestsNoRequestsConnection))
-#define TP_TESTS_NO_REQUESTS_CONNECTION_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_NO_REQUESTS_CONNECTION, \
- TpTestsNoRequestsConnectionClass))
-#define TP_TESTS_NO_REQUESTS_IS_CONNECTION(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_NO_REQUESTS_CONNECTION))
-#define TP_TESTS_NO_REQUESTS_IS_CONNECTION_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_NO_REQUESTS_CONNECTION))
-#define TP_TESTS_NO_REQUESTS_CONNECTION_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_NO_REQUESTS_CONNECTION, \
- TpTestsNoRequestsConnectionClass))
-
G_END_DECLS
#endif /* ifndef __TP_TESTS_CONTACTS_CONN_H__ */
diff --git a/tests/lib/telepathy/contactlist/dbus-tube-chan.c b/tests/lib/telepathy/contactlist/dbus-tube-chan.c
new file mode 100644
index 00000000..28e34b5c
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/dbus-tube-chan.c
@@ -0,0 +1,455 @@
+/*
+ * dbus-tube-chan.c - Simple dbus tube channel
+ *
+ * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "dbus-tube-chan.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+#include <glib/gstdio.h>
+
+#if defined(G_OS_UNIX)
+# define LISTEN_ADDRESS "unix:tmpdir=/tmp"
+#else
+# define LISTEN_ADDRESS "tcp:host=127.0.0.1"
+#endif
+
+enum
+{
+ PROP_SERVICE_NAME = 1,
+ PROP_DBUS_NAMES,
+ PROP_SUPPORTED_ACCESS_CONTROLS,
+ PROP_PARAMETERS,
+ PROP_STATE,
+};
+
+enum
+{
+ SIG_NEW_CONNECTION,
+ LAST_SIGNAL
+};
+
+static guint _signals[LAST_SIGNAL] = { 0, };
+
+struct _TpTestsDBusTubeChannelPrivate {
+ /* Controls whether the channel should become open before returning from
+ * Open/Accept, after returning, or never.
+ */
+ TpTestsDBusTubeChannelOpenMode open_mode;
+ TpTubeChannelState state;
+
+ /* TpHandle -> gchar * */
+ GHashTable *dbus_names;
+
+ GDBusServer *dbus_server;
+};
+
+static void
+tp_tests_dbus_tube_channel_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsDBusTubeChannel *self = (TpTestsDBusTubeChannel *) object;
+
+ switch (property_id)
+ {
+ case PROP_SERVICE_NAME:
+ g_value_set_string (value, "com.test.Test");
+ break;
+
+ case PROP_DBUS_NAMES:
+ g_value_set_boxed (value, self->priv->dbus_names);
+ break;
+
+ case PROP_SUPPORTED_ACCESS_CONTROLS:
+ {
+ GArray *array;
+ TpSocketAccessControl a;
+
+ array = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
+
+ a = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
+ g_array_append_val (array, a);
+
+ g_value_set_boxed (value, array);
+
+ g_array_unref (array);
+ }
+ break;
+
+ case PROP_PARAMETERS:
+ g_value_take_boxed (value, tp_asv_new (
+ "badger", G_TYPE_UINT, 42,
+ NULL));
+ break;
+
+ case PROP_STATE:
+ g_value_set_uint (value, self->priv->state);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void dbus_tube_iface_init (gpointer iface, gpointer data);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TpTestsDBusTubeChannel,
+ tp_tests_dbus_tube_channel,
+ TP_TYPE_BASE_CHANNEL,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_DBUS_TUBE,
+ dbus_tube_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_TUBE,
+ NULL);
+ )
+
+/* type definition stuff */
+
+static GPtrArray *
+tp_tests_dbus_tube_channel_get_interfaces (TpBaseChannel *self)
+{
+ GPtrArray *interfaces;
+
+ interfaces = TP_BASE_CHANNEL_CLASS (
+ tp_tests_dbus_tube_channel_parent_class)->get_interfaces (self);
+
+ g_ptr_array_add (interfaces, TP_IFACE_CHANNEL_INTERFACE_TUBE);
+ return interfaces;
+};
+
+static void
+tp_tests_dbus_tube_channel_init (TpTestsDBusTubeChannel *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
+ TP_TESTS_TYPE_DBUS_TUBE_CHANNEL, TpTestsDBusTubeChannelPrivate);
+
+ self->priv->open_mode = TP_TESTS_DBUS_TUBE_CHANNEL_OPEN_FIRST;
+ self->priv->dbus_names = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal, NULL, g_free);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object =
+ G_OBJECT_CLASS (tp_tests_dbus_tube_channel_parent_class)->constructor (
+ type, n_props, props);
+ TpTestsDBusTubeChannel *self = TP_TESTS_DBUS_TUBE_CHANNEL (object);
+
+ if (tp_base_channel_is_requested (TP_BASE_CHANNEL (self)))
+ self->priv->state = TP_TUBE_CHANNEL_STATE_NOT_OFFERED;
+ else
+ self->priv->state = TP_TUBE_CHANNEL_STATE_LOCAL_PENDING;
+
+ tp_base_channel_register (TP_BASE_CHANNEL (self));
+
+ return object;
+}
+
+static void
+dispose (GObject *object)
+{
+ TpTestsDBusTubeChannel *self = (TpTestsDBusTubeChannel *) object;
+
+ tp_clear_pointer (&self->priv->dbus_names, g_hash_table_unref);
+
+ if (self->priv->dbus_server != NULL)
+ {
+ /* FIXME: this is pretty stupid but apparently unless you start and then
+ * stop the server before freeing it, it doesn't stop listening. Calling
+ * _start() twice is a no-op.
+ *
+ * https://bugzilla.gnome.org/show_bug.cgi?id=673372
+ */
+ g_dbus_server_start (self->priv->dbus_server);
+
+ g_dbus_server_stop (self->priv->dbus_server);
+ g_clear_object (&self->priv->dbus_server);
+ }
+
+ ((GObjectClass *) tp_tests_dbus_tube_channel_parent_class)->dispose (
+ object);
+}
+
+static void
+channel_close (TpBaseChannel *channel)
+{
+ tp_base_channel_destroyed (channel);
+}
+
+static void
+fill_immutable_properties (TpBaseChannel *chan,
+ GHashTable *properties)
+{
+ TpBaseChannelClass *klass = TP_BASE_CHANNEL_CLASS (
+ tp_tests_dbus_tube_channel_parent_class);
+
+ klass->fill_immutable_properties (chan, properties);
+
+ tp_dbus_properties_mixin_fill_properties_hash (
+ G_OBJECT (chan), properties,
+ TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "ServiceName",
+ TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "SupportedAccessControls",
+ NULL);
+
+ if (!tp_base_channel_is_requested (chan))
+ {
+ /* Parameters is immutable only for incoming tubes */
+ tp_dbus_properties_mixin_fill_properties_hash (
+ G_OBJECT (chan), properties,
+ TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters",
+ NULL);
+ }
+}
+
+static void
+tp_tests_dbus_tube_channel_class_init (TpTestsDBusTubeChannelClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
+ GParamSpec *param_spec;
+ static TpDBusPropertiesMixinPropImpl dbus_tube_props[] = {
+ { "ServiceName", "service-name", NULL, },
+ { "DBusNames", "dbus-names", NULL, },
+ { "SupportedAccessControls", "supported-access-controls", NULL, },
+ { NULL }
+ };
+ static TpDBusPropertiesMixinPropImpl tube_props[] = {
+ { "Parameters", "parameters", NULL, },
+ { "State", "state", NULL, },
+ { NULL }
+ };
+
+ object_class->constructor = constructor;
+ object_class->get_property = tp_tests_dbus_tube_channel_get_property;
+ object_class->dispose = dispose;
+
+ base_class->channel_type = TP_IFACE_CHANNEL_TYPE_DBUS_TUBE;
+ base_class->get_interfaces = tp_tests_dbus_tube_channel_get_interfaces;
+ base_class->close = channel_close;
+ base_class->fill_immutable_properties = fill_immutable_properties;
+
+ /* base_class->target_handle_type is defined in subclasses */
+
+ param_spec = g_param_spec_string ("service-name", "Service Name",
+ "the service name associated with this tube object.",
+ "",
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_SERVICE_NAME, param_spec);
+
+ param_spec = g_param_spec_boxed ("dbus-names", "DBus Names",
+ "DBusTube.DBusNames",
+ TP_HASH_TYPE_DBUS_TUBE_PARTICIPANTS,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_DBUS_NAMES, param_spec);
+
+ param_spec = g_param_spec_boxed ("supported-access-controls",
+ "Supported access-controls",
+ "GArray containing supported access controls.",
+ DBUS_TYPE_G_UINT_ARRAY,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class,
+ PROP_SUPPORTED_ACCESS_CONTROLS, param_spec);
+
+ param_spec = g_param_spec_boxed (
+ "parameters", "Parameters",
+ "parameters of the tube",
+ TP_HASH_TYPE_STRING_VARIANT_MAP,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_PARAMETERS,
+ param_spec);
+
+ param_spec = g_param_spec_uint (
+ "state", "TpTubeState",
+ "state of the tube",
+ 0, TP_NUM_TUBE_CHANNEL_STATES - 1, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_STATE,
+ param_spec);
+
+ _signals[SIG_NEW_CONNECTION] = g_signal_new ("new-connection",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ g_signal_accumulator_true_handled, NULL,
+ NULL,
+ G_TYPE_BOOLEAN,
+ 1, G_TYPE_DBUS_CONNECTION);
+
+ tp_dbus_properties_mixin_implement_interface (object_class,
+ TP_IFACE_QUARK_CHANNEL_TYPE_DBUS_TUBE,
+ tp_dbus_properties_mixin_getter_gobject_properties, NULL,
+ dbus_tube_props);
+
+ tp_dbus_properties_mixin_implement_interface (object_class,
+ TP_IFACE_QUARK_CHANNEL_INTERFACE_TUBE,
+ tp_dbus_properties_mixin_getter_gobject_properties, NULL,
+ tube_props);
+
+ g_type_class_add_private (object_class,
+ sizeof (TpTestsDBusTubeChannelPrivate));
+}
+
+static void
+change_state (TpTestsDBusTubeChannel *self,
+ TpTubeChannelState state)
+{
+ self->priv->state = state;
+
+ tp_svc_channel_interface_tube_emit_tube_channel_state_changed (self, state);
+}
+
+static gboolean
+dbus_new_connection_cb (GDBusServer *server,
+ GDBusConnection *connection,
+ gpointer user_data)
+{
+ TpTestsDBusTubeChannel *self = user_data;
+ gboolean ret = FALSE;
+
+ g_signal_emit (self, _signals[SIG_NEW_CONNECTION], 0, connection, &ret);
+ return ret;
+}
+
+static void
+open_tube (TpTestsDBusTubeChannel *self)
+{
+ GError *error = NULL;
+ gchar *guid;
+
+ guid = g_dbus_generate_guid ();
+
+ self->priv->dbus_server = g_dbus_server_new_sync (LISTEN_ADDRESS,
+ G_DBUS_SERVER_FLAGS_NONE, guid, NULL, NULL, &error);
+ g_assert_no_error (error);
+
+ g_free (guid);
+
+ g_signal_connect (self->priv->dbus_server, "new-connection",
+ G_CALLBACK (dbus_new_connection_cb), self);
+}
+
+static void
+really_open_tube (TpTestsDBusTubeChannel *self)
+{
+ g_dbus_server_start (self->priv->dbus_server);
+
+ change_state (self, TP_TUBE_CHANNEL_STATE_OPEN);
+}
+
+static void
+dbus_tube_offer (TpSvcChannelTypeDBusTube *chan,
+ GHashTable *parameters,
+ guint access_control,
+ DBusGMethodInvocation *context)
+{
+ TpTestsDBusTubeChannel *self = (TpTestsDBusTubeChannel *) chan;
+
+ open_tube (self);
+
+ if (self->priv->open_mode == TP_TESTS_DBUS_TUBE_CHANNEL_OPEN_FIRST)
+ really_open_tube (self);
+
+ tp_svc_channel_type_dbus_tube_return_from_offer (context,
+ g_dbus_server_get_client_address (self->priv->dbus_server));
+
+ if (self->priv->open_mode == TP_TESTS_DBUS_TUBE_CHANNEL_OPEN_SECOND)
+ really_open_tube (self);
+ else if (self->priv->open_mode == TP_TESTS_DBUS_TUBE_CHANNEL_NEVER_OPEN)
+ tp_base_channel_close (TP_BASE_CHANNEL (self));
+}
+
+static void
+dbus_tube_accept (TpSvcChannelTypeDBusTube *chan,
+ guint access_control,
+ DBusGMethodInvocation *context)
+{
+ TpTestsDBusTubeChannel *self = (TpTestsDBusTubeChannel *) chan;
+
+ open_tube (self);
+
+ if (self->priv->open_mode == TP_TESTS_DBUS_TUBE_CHANNEL_OPEN_FIRST)
+ really_open_tube (self);
+
+ tp_svc_channel_type_dbus_tube_return_from_accept (context,
+ g_dbus_server_get_client_address (self->priv->dbus_server));
+
+ if (self->priv->open_mode == TP_TESTS_DBUS_TUBE_CHANNEL_OPEN_SECOND)
+ really_open_tube (self);
+ else if (self->priv->open_mode == TP_TESTS_DBUS_TUBE_CHANNEL_NEVER_OPEN)
+ tp_base_channel_close (TP_BASE_CHANNEL (self));
+}
+
+void
+tp_tests_dbus_tube_channel_set_open_mode (
+ TpTestsDBusTubeChannel *self,
+ TpTestsDBusTubeChannelOpenMode open_mode)
+{
+ self->priv->open_mode = open_mode;
+}
+
+static void
+dbus_tube_iface_init (gpointer iface,
+ gpointer data)
+{
+ TpSvcChannelTypeDBusTubeClass *klass = iface;
+
+#define IMPLEMENT(x) tp_svc_channel_type_dbus_tube_implement_##x (klass, dbus_tube_##x)
+ IMPLEMENT (offer);
+ IMPLEMENT (accept);
+#undef IMPLEMENT
+}
+
+/* Contact DBus Tube */
+
+G_DEFINE_TYPE (TpTestsContactDBusTubeChannel,
+ tp_tests_contact_dbus_tube_channel,
+ TP_TESTS_TYPE_DBUS_TUBE_CHANNEL)
+
+static void
+tp_tests_contact_dbus_tube_channel_init (
+ TpTestsContactDBusTubeChannel *self)
+{
+}
+
+static void
+tp_tests_contact_dbus_tube_channel_class_init (
+ TpTestsContactDBusTubeChannelClass *klass)
+{
+ TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
+
+ base_class->target_handle_type = TP_HANDLE_TYPE_CONTACT;
+}
+
+/* Room DBus Tube */
+
+G_DEFINE_TYPE (TpTestsRoomDBusTubeChannel,
+ tp_tests_room_dbus_tube_channel,
+ TP_TESTS_TYPE_DBUS_TUBE_CHANNEL)
+
+static void
+tp_tests_room_dbus_tube_channel_init (
+ TpTestsRoomDBusTubeChannel *self)
+{
+}
+
+static void
+tp_tests_room_dbus_tube_channel_class_init (
+ TpTestsRoomDBusTubeChannelClass *klass)
+{
+ TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
+
+ base_class->target_handle_type = TP_HANDLE_TYPE_ROOM;
+}
diff --git a/tests/lib/telepathy/contactlist/dbus-tube-chan.h b/tests/lib/telepathy/contactlist/dbus-tube-chan.h
new file mode 100644
index 00000000..71800970
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/dbus-tube-chan.h
@@ -0,0 +1,127 @@
+/*
+ * dbus-tube-chan.h - Simple dbus tube channel
+ *
+ * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_DBUS_TUBE_CHAN_H__
+#define __TP_DBUS_TUBE_CHAN_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+G_BEGIN_DECLS
+
+/* Base Class */
+typedef struct _TpTestsDBusTubeChannel TpTestsDBusTubeChannel;
+typedef struct _TpTestsDBusTubeChannelClass TpTestsDBusTubeChannelClass;
+typedef struct _TpTestsDBusTubeChannelPrivate TpTestsDBusTubeChannelPrivate;
+
+GType tp_tests_dbus_tube_channel_get_type (void);
+
+#define TP_TESTS_TYPE_DBUS_TUBE_CHANNEL \
+ (tp_tests_dbus_tube_channel_get_type ())
+#define TP_TESTS_DBUS_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_DBUS_TUBE_CHANNEL, \
+ TpTestsDBusTubeChannel))
+#define TP_TESTS_DBUS_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_DBUS_TUBE_CHANNEL, \
+ TpTestsDBusTubeChannelClass))
+#define TP_TESTS_IS_DBUS_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_DBUS_TUBE_CHANNEL))
+#define TP_TESTS_IS_DBUS_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_DBUS_TUBE_CHANNEL))
+#define TP_TESTS_DBUS_TUBE_CHANNEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_DBUS_TUBE_CHANNEL, \
+ TpTestsDBusTubeChannelClass))
+
+struct _TpTestsDBusTubeChannelClass {
+ TpBaseChannelClass parent_class;
+ TpDBusPropertiesMixinClass dbus_properties_class;
+};
+
+struct _TpTestsDBusTubeChannel {
+ TpBaseChannel parent;
+
+ TpTestsDBusTubeChannelPrivate *priv;
+};
+
+typedef enum {
+ TP_TESTS_DBUS_TUBE_CHANNEL_OPEN_FIRST,
+ TP_TESTS_DBUS_TUBE_CHANNEL_OPEN_SECOND,
+ TP_TESTS_DBUS_TUBE_CHANNEL_NEVER_OPEN
+} TpTestsDBusTubeChannelOpenMode;
+
+void tp_tests_dbus_tube_channel_set_open_mode (
+ TpTestsDBusTubeChannel *self,
+ TpTestsDBusTubeChannelOpenMode open_mode);
+
+/* Contact DBus Tube */
+
+typedef struct _TpTestsContactDBusTubeChannel TpTestsContactDBusTubeChannel;
+typedef struct _TpTestsContactDBusTubeChannelClass TpTestsContactDBusTubeChannelClass;
+
+GType tp_tests_contact_dbus_tube_channel_get_type (void);
+
+#define TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL \
+ (tp_tests_contact_dbus_tube_channel_get_type ())
+#define TP_TESTS_CONTACT_DBUS_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL, \
+ TpTestsContactDBusTubeChannel))
+#define TP_TESTS_CONTACT_DBUS_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL, \
+ TpTestsContactDBusTubeChannelClass))
+#define TP_TESTS_IS_CONTACT_DBUS_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL))
+#define TP_TESTS_IS_CONTACT_DBUS_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL))
+#define TP_TESTS_CONTACT_DBUS_TUBE_CHANNEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_CONTACT_DBUS_TUBE_CHANNEL, \
+ TpTestsContactDBusTubeChannelClass))
+
+struct _TpTestsContactDBusTubeChannelClass {
+ TpTestsDBusTubeChannelClass parent_class;
+};
+
+struct _TpTestsContactDBusTubeChannel {
+ TpTestsDBusTubeChannel parent;
+};
+
+/* Room DBus Tube */
+
+typedef struct _TpTestsRoomDBusTubeChannel TpTestsRoomDBusTubeChannel;
+typedef struct _TpTestsRoomDBusTubeChannelClass TpTestsRoomDBusTubeChannelClass;
+
+GType tp_tests_room_dbus_tube_channel_get_type (void);
+
+#define TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL \
+ (tp_tests_room_dbus_tube_channel_get_type ())
+#define TP_TESTS_ROOM_DBUS_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL, \
+ TpTestsRoomDBusTubeChannel))
+#define TP_TESTS_ROOM_DBUS_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL, \
+ TpTestsRoomDBusTubeChannelClass))
+#define TP_TESTS_IS_ROOM_DBUS_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL))
+#define TP_TESTS_IS_ROOM_DBUS_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL))
+#define TP_TESTS_ROOM_DBUS_TUBE_CHANNEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_ROOM_DBUS_TUBE_CHANNEL, \
+ TpTestsRoomDBusTubeChannelClass))
+
+struct _TpTestsRoomDBusTubeChannelClass {
+ TpTestsDBusTubeChannelClass parent_class;
+};
+
+struct _TpTestsRoomDBusTubeChannel {
+ TpTestsDBusTubeChannel parent;
+};
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_DBUS_TUBE_CHAN_H__ */
diff --git a/tests/lib/telepathy/contactlist/echo-chan.c b/tests/lib/telepathy/contactlist/echo-chan.c
new file mode 100644
index 00000000..868fbcf4
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/echo-chan.c
@@ -0,0 +1,223 @@
+/*
+ * chan.c - an example text channel talking to a particular
+ * contact. Similar code is used for 1-1 IM channels in many protocols
+ * (IRC private messages ("/query"), XMPP IM etc.)
+ *
+ * Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "echo-chan.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+static void destroyable_iface_init (gpointer iface, gpointer data);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsEchoChannel,
+ tp_tests_echo_channel,
+ TP_TYPE_BASE_CHANNEL,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_TEXT,
+ tp_message_mixin_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_DESTROYABLE,
+ destroyable_iface_init);
+ )
+
+/* type definition stuff */
+
+static GPtrArray *
+tp_tests_echo_channel_get_interfaces (TpBaseChannel *self)
+{
+ GPtrArray *interfaces;
+
+ interfaces = TP_BASE_CHANNEL_CLASS (tp_tests_echo_channel_parent_class)->
+ get_interfaces (self);
+
+ g_ptr_array_add (interfaces, TP_IFACE_CHANNEL_INTERFACE_DESTROYABLE);
+ return interfaces;
+};
+
+static void
+tp_tests_echo_channel_init (TpTestsEchoChannel *self)
+{
+}
+
+static void text_send (GObject *object, TpMessage *message,
+ TpMessageSendingFlags flags);
+
+static void
+constructed (GObject *object)
+{
+ TpTestsEchoChannel *self = TP_TESTS_ECHO_CHANNEL (object);
+ TpBaseConnection *conn = tp_base_channel_get_connection (TP_BASE_CHANNEL (self));
+ const TpChannelTextMessageType types[] = {
+ TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
+ TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION,
+ TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE,
+ };
+ const gchar * supported_content_types[] = {
+ "text/plain",
+ NULL
+ };
+ g_assert (conn != NULL);
+
+ G_OBJECT_CLASS (tp_tests_echo_channel_parent_class)->constructed (object);
+
+ tp_base_channel_register (TP_BASE_CHANNEL (self));
+
+ tp_message_mixin_init (object,
+ G_STRUCT_OFFSET (TpTestsEchoChannel, message),
+ conn);
+ tp_message_mixin_implement_sending (object,
+ text_send, G_N_ELEMENTS (types), types, 0, 0,
+ supported_content_types);
+}
+
+static void
+finalize (GObject *object)
+{
+ tp_message_mixin_finalize (object);
+
+ ((GObjectClass *) tp_tests_echo_channel_parent_class)->finalize (object);
+}
+
+static void
+tp_tests_echo_channel_close (TpTestsEchoChannel *self)
+{
+ GObject *object = (GObject *) self;
+ gboolean closed = tp_base_channel_is_destroyed (TP_BASE_CHANNEL (self));
+
+ if (!closed)
+ {
+ TpHandle first_sender;
+
+ /* The manager wants to be able to respawn the channel if it has pending
+ * messages. When respawned, the channel must have the initiator set
+ * to the contact who sent us those messages (if it isn't already),
+ * and the messages must be marked as having been rescued so they
+ * don't get logged twice. */
+ if (tp_message_mixin_has_pending_messages (object, &first_sender))
+ {
+ tp_base_channel_reopened (TP_BASE_CHANNEL (self), first_sender);
+ tp_message_mixin_set_rescued (object);
+ }
+ else
+ {
+ tp_base_channel_destroyed (TP_BASE_CHANNEL (self));
+ }
+ }
+}
+
+static void
+channel_close (TpBaseChannel *channel)
+{
+ TpTestsEchoChannel *self = TP_TESTS_ECHO_CHANNEL (channel);
+
+ tp_tests_echo_channel_close (self);
+}
+
+static void
+tp_tests_echo_channel_class_init (TpTestsEchoChannelClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
+
+ object_class->constructed = constructed;
+ object_class->finalize = finalize;
+
+ base_class->channel_type = TP_IFACE_CHANNEL_TYPE_TEXT;
+ base_class->target_handle_type = TP_HANDLE_TYPE_CONTACT;
+ base_class->get_interfaces = tp_tests_echo_channel_get_interfaces;
+ base_class->close = channel_close;
+
+ tp_message_mixin_init_dbus_properties (object_class);
+}
+
+
+static void
+text_send (GObject *object,
+ TpMessage *message,
+ TpMessageSendingFlags flags)
+{
+ TpTestsEchoChannel *self = TP_TESTS_ECHO_CHANNEL (object);
+ TpChannelTextMessageType type = tp_message_get_message_type (message);
+ TpChannelTextMessageType echo_type = type;
+ TpHandle target = tp_base_channel_get_target_handle (TP_BASE_CHANNEL (self));
+ gchar *echo;
+ gint64 now = time (NULL);
+ const GHashTable *part;
+ const gchar *text;
+ TpMessage *msg;
+
+ /* Pretend that the remote contact has replied. Normally, you'd
+ * call tp_text_mixin_receive or tp_text_mixin_receive_with_flags
+ * in response to network events */
+
+ part = tp_message_peek (message, 1);
+ text = tp_asv_get_string (part, "content");
+
+ switch (type)
+ {
+ case TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL:
+ echo = g_strdup_printf ("You said: %s", text);
+ break;
+ case TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION:
+ echo = g_strdup_printf ("notices that the user %s", text);
+ break;
+ case TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE:
+ echo = g_strdup_printf ("You sent a notice: %s", text);
+ break;
+ default:
+ echo = g_strdup_printf ("You sent some weird message type, %u: \"%s\"",
+ type, text);
+ echo_type = TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
+ }
+
+ tp_message_mixin_sent (object, message, 0, "", NULL);
+
+ msg = tp_cm_message_new (
+ tp_base_channel_get_connection (TP_BASE_CHANNEL (self)),
+ 2);
+
+ tp_cm_message_set_sender (msg, target);
+ tp_message_set_uint32 (msg, 0, "message-type", echo_type);
+ tp_message_set_int64 (msg, 0, "message-sent", now);
+ tp_message_set_int64 (msg, 0, "message-received", now);
+
+ tp_message_set_string (msg, 1, "content-type", "text/plain");
+ tp_message_set_string (msg, 1, "content", echo);
+
+ tp_message_mixin_take_received (object, msg);
+
+ g_free (echo);
+}
+
+static void
+destroyable_destroy (TpSvcChannelInterfaceDestroyable *iface,
+ DBusGMethodInvocation *context)
+{
+ TpTestsEchoChannel *self = TP_TESTS_ECHO_CHANNEL (iface);
+
+ tp_message_mixin_clear ((GObject *) self);
+ tp_base_channel_destroyed (TP_BASE_CHANNEL (self));
+
+ tp_svc_channel_interface_destroyable_return_from_destroy (context);
+}
+
+static void
+destroyable_iface_init (gpointer iface,
+ gpointer data)
+{
+ TpSvcChannelInterfaceDestroyableClass *klass = iface;
+
+#define IMPLEMENT(x) \
+ tp_svc_channel_interface_destroyable_implement_##x (klass, destroyable_##x)
+ IMPLEMENT (destroy);
+#undef IMPLEMENT
+}
diff --git a/tests/lib/telepathy/contactlist/echo-chan.h b/tests/lib/telepathy/contactlist/echo-chan.h
new file mode 100644
index 00000000..5fbe6ee5
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/echo-chan.h
@@ -0,0 +1,56 @@
+/*
+ * chan.h - header for an example channel
+ *
+ * Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_CHAN_H__
+#define __TP_TESTS_CHAN_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsEchoChannel TpTestsEchoChannel;
+typedef struct _TpTestsEchoChannelClass TpTestsEchoChannelClass;
+typedef struct _TpTestsEchoChannelPrivate TpTestsEchoChannelPrivate;
+
+GType tp_tests_echo_channel_get_type (void);
+
+#define TP_TESTS_TYPE_ECHO_CHANNEL \
+ (tp_tests_echo_channel_get_type ())
+#define TP_TESTS_ECHO_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_ECHO_CHANNEL, \
+ TpTestsEchoChannel))
+#define TP_TESTS_ECHO_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_ECHO_CHANNEL, \
+ TpTestsEchoChannelClass))
+#define TP_TESTS_IS_ECHO_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_ECHO_CHANNEL))
+#define TP_TESTS_IS_ECHO_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_ECHO_CHANNEL))
+#define TP_TESTS_ECHO_CHANNEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_ECHO_CHANNEL, \
+ TpTestsEchoChannelClass))
+
+struct _TpTestsEchoChannelClass {
+ TpBaseChannelClass parent_class;
+ TpDBusPropertiesMixinClass dbus_properties_class;
+};
+
+struct _TpTestsEchoChannel {
+ TpBaseChannel parent;
+ TpMessageMixin message;
+
+ TpTestsEchoChannelPrivate *priv;
+};
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_CHAN_H__ */
diff --git a/tests/lib/telepathy/contactlist/echo-conn.c b/tests/lib/telepathy/contactlist/echo-conn.c
new file mode 100644
index 00000000..e985ec67
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/echo-conn.c
@@ -0,0 +1,165 @@
+/*
+ * conn.c - an example connection
+ *
+ * Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "echo-conn.h"
+
+#include <dbus/dbus-glib.h>
+
+#include <telepathy-glib/telepathy-glib.h>
+
+#include "echo-im-manager.h"
+#include "simple-channel-manager.h"
+
+G_DEFINE_TYPE (TpTestsEchoConnection,
+ tp_tests_echo_connection,
+ TP_TESTS_TYPE_CONTACTS_CONNECTION)
+
+/* type definition stuff */
+
+enum
+{
+ PROP_CHANNEL_MANAGER = 1,
+ N_PROPS
+};
+
+struct _TpTestsEchoConnectionPrivate
+{
+ TpTestsSimpleChannelManager *channel_manager;
+};
+
+
+static void
+tp_tests_echo_connection_init (TpTestsEchoConnection *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TESTS_TYPE_ECHO_CONNECTION,
+ TpTestsEchoConnectionPrivate);
+}
+
+/* Returns the same id given in but in lowercase. If '#' is present,
+ * the normalized contact will be the lhs of it. For example:
+ *
+ * LOL -> lol
+ * Lol#foo -> lol
+ */
+static gchar *
+tp_tests_echo_normalize_contact (TpHandleRepoIface *repo,
+ const gchar *id,
+ gpointer context,
+ GError **error)
+{
+ gchar *hash;
+
+ if (id[0] == '\0')
+ {
+ g_set_error (error, TP_ERROR, TP_ERROR_INVALID_HANDLE,
+ "ID must not be empty");
+ return NULL;
+ }
+
+ hash = g_utf8_strchr (id, -1, '#');
+
+ return g_utf8_strdown (id, hash != NULL ? (hash - id) : -1);
+}
+
+static void
+create_handle_repos (TpBaseConnection *conn,
+ TpHandleRepoIface *repos[TP_NUM_HANDLE_TYPES])
+{
+ ((TpBaseConnectionClass *)
+ tp_tests_echo_connection_parent_class)->create_handle_repos (conn, repos);
+
+ /* Replace the contacts handle repo with our own, for special normalization */
+ g_assert (repos[TP_HANDLE_TYPE_CONTACT] != NULL);
+ g_object_unref (repos[TP_HANDLE_TYPE_CONTACT]);
+ repos[TP_HANDLE_TYPE_CONTACT] = tp_dynamic_handle_repo_new
+ (TP_HANDLE_TYPE_CONTACT, tp_tests_echo_normalize_contact, NULL);
+}
+
+static GPtrArray *
+create_channel_managers (TpBaseConnection *conn)
+{
+ TpTestsEchoConnection *self = TP_TESTS_ECHO_CONNECTION (conn);
+ GPtrArray *ret;
+
+ ret = ((TpBaseConnectionClass *)
+ tp_tests_echo_connection_parent_class)->create_channel_managers (conn);
+
+ if (self->priv->channel_manager == NULL)
+ {
+ self->priv->channel_manager = g_object_new (TP_TESTS_TYPE_ECHO_IM_MANAGER,
+ "connection", conn,
+ NULL);
+ }
+
+ /* tp-glib will free this for us so we don't need to worry about
+ doing it ourselves. */
+ g_ptr_array_add (ret, self->priv->channel_manager);
+
+ return ret;
+}
+
+static void
+get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *spec)
+{
+ TpTestsEchoConnection *self = TP_TESTS_ECHO_CONNECTION (object);
+
+ switch (property_id) {
+ case PROP_CHANNEL_MANAGER:
+ g_assert (self->priv->channel_manager == NULL); /* construct-only */
+ g_value_set_object (value, self->priv->channel_manager);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+ }
+}
+
+static void
+set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *spec)
+{
+ TpTestsEchoConnection *self = TP_TESTS_ECHO_CONNECTION (object);
+
+ switch (property_id) {
+ case PROP_CHANNEL_MANAGER:
+ self->priv->channel_manager = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+ }
+}
+
+static void
+tp_tests_echo_connection_class_init (TpTestsEchoConnectionClass *klass)
+{
+ TpBaseConnectionClass *base_class =
+ (TpBaseConnectionClass *) klass;
+ GObjectClass *object_class = (GObjectClass *) klass;
+ GParamSpec *param_spec;
+
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+ g_type_class_add_private (klass, sizeof (TpTestsEchoConnectionPrivate));
+
+ base_class->create_handle_repos = create_handle_repos;
+ base_class->create_channel_managers = create_channel_managers;
+
+ param_spec = g_param_spec_object ("channel-manager", "Channel manager",
+ "The channel manager", TP_TESTS_TYPE_SIMPLE_CHANNEL_MANAGER,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CHANNEL_MANAGER, param_spec);
+}
diff --git a/tests/lib/telepathy/contactlist/echo-conn.h b/tests/lib/telepathy/contactlist/echo-conn.h
new file mode 100644
index 00000000..ffc8f4d9
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/echo-conn.h
@@ -0,0 +1,56 @@
+/*
+ * conn.h - header for an example connection
+ *
+ * Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_ECHO_CONN_H__
+#define __TP_TESTS_ECHO_CONN_H__
+
+#include <glib-object.h>
+
+#include "contacts-conn.h"
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsEchoConnection TpTestsEchoConnection;
+typedef struct _TpTestsEchoConnectionClass TpTestsEchoConnectionClass;
+typedef struct _TpTestsEchoConnectionPrivate TpTestsEchoConnectionPrivate;
+
+struct _TpTestsEchoConnectionClass {
+ TpTestsContactsConnectionClass parent_class;
+};
+
+struct _TpTestsEchoConnection {
+ TpTestsContactsConnection parent;
+
+ TpTestsEchoConnectionPrivate *priv;
+};
+
+GType tp_tests_echo_connection_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_ECHO_CONNECTION \
+ (tp_tests_echo_connection_get_type ())
+#define TP_TESTS_ECHO_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_ECHO_CONNECTION, \
+ TpTestsEchoConnection))
+#define TP_TESTS_ECHO_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_ECHO_CONNECTION, \
+ TpTestsEchoConnectionClass))
+#define TP_TESTS_IS_ECHO_CONNECTION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_ECHO_CONNECTION))
+#define TP_TESTS_IS_ECHO_CONNECTION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_ECHO_CONNECTION))
+#define TP_TESTS_ECHO_CONNECTION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_ECHO_CONNECTION, \
+ TpTestsEchoConnectionClass))
+
+G_END_DECLS
+
+#endif
diff --git a/tests/lib/telepathy/contactlist/echo-im-manager.c b/tests/lib/telepathy/contactlist/echo-im-manager.c
new file mode 100644
index 00000000..8c381866
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/echo-im-manager.c
@@ -0,0 +1,382 @@
+/*
+ * im-manager.c - an example channel manager for channels talking to a
+ * particular contact. Similar code is used for 1-1 IM channels in many
+ * protocols (IRC private messages ("/query"), XMPP IM etc.)
+ *
+ * Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "echo-im-manager.h"
+
+#include <dbus/dbus-glib.h>
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#include "echo-chan.h"
+
+static void channel_manager_iface_init (gpointer, gpointer);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsEchoImManager,
+ tp_tests_echo_im_manager,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER,
+ channel_manager_iface_init))
+
+/* type definition stuff */
+
+enum
+{
+ PROP_CONNECTION = 1,
+ N_PROPS
+};
+
+struct _TpTestsEchoImManagerPrivate
+{
+ TpBaseConnection *conn;
+
+ /* GUINT_TO_POINTER (handle) => TpTestsEchoChannel */
+ GHashTable *channels;
+ gulong status_changed_id;
+};
+
+static void
+tp_tests_echo_im_manager_init (TpTestsEchoImManager *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TESTS_TYPE_ECHO_IM_MANAGER,
+ TpTestsEchoImManagerPrivate);
+
+ self->priv->channels = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, g_object_unref);
+}
+
+static void tp_tests_echo_im_manager_close_all (TpTestsEchoImManager *self);
+
+static void
+dispose (GObject *object)
+{
+ TpTestsEchoImManager *self = TP_TESTS_ECHO_IM_MANAGER (object);
+
+ tp_tests_echo_im_manager_close_all (self);
+ g_assert (self->priv->channels == NULL);
+
+ ((GObjectClass *) tp_tests_echo_im_manager_parent_class)->dispose (object);
+}
+
+static void
+get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsEchoImManager *self = TP_TESTS_ECHO_IM_MANAGER (object);
+
+ switch (property_id)
+ {
+ case PROP_CONNECTION:
+ g_value_set_object (value, self->priv->conn);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsEchoImManager *self = TP_TESTS_ECHO_IM_MANAGER (object);
+
+ switch (property_id)
+ {
+ case PROP_CONNECTION:
+ /* We don't ref the connection, because it owns a reference to the
+ * channel manager, and it guarantees that the manager's lifetime is
+ * less than its lifetime */
+ self->priv->conn = g_value_get_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+status_changed_cb (TpBaseConnection *conn,
+ guint status,
+ guint reason,
+ TpTestsEchoImManager *self)
+{
+ if (status == TP_CONNECTION_STATUS_DISCONNECTED)
+ tp_tests_echo_im_manager_close_all (self);
+}
+
+static void
+constructed (GObject *object)
+{
+ TpTestsEchoImManager *self = TP_TESTS_ECHO_IM_MANAGER (object);
+ void (*chain_up) (GObject *) =
+ ((GObjectClass *) tp_tests_echo_im_manager_parent_class)->constructed;
+
+ if (chain_up != NULL)
+ {
+ chain_up (object);
+ }
+
+ self->priv->status_changed_id = g_signal_connect (self->priv->conn,
+ "status-changed", (GCallback) status_changed_cb, self);
+}
+
+static void
+tp_tests_echo_im_manager_class_init (TpTestsEchoImManagerClass *klass)
+{
+ GParamSpec *param_spec;
+ GObjectClass *object_class = (GObjectClass *) klass;
+
+ object_class->constructed = constructed;
+ object_class->dispose = dispose;
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+
+ param_spec = g_param_spec_object ("connection", "Connection object",
+ "The connection that owns this channel manager",
+ TP_TYPE_BASE_CONNECTION,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
+
+ g_type_class_add_private (klass, sizeof (TpTestsEchoImManagerPrivate));
+}
+
+static void
+tp_tests_echo_im_manager_close_all (TpTestsEchoImManager *self)
+{
+ if (self->priv->channels != NULL)
+ {
+ GHashTable *tmp = self->priv->channels;
+
+ self->priv->channels = NULL;
+ g_hash_table_unref (tmp);
+ }
+
+ if (self->priv->status_changed_id != 0)
+ {
+ g_signal_handler_disconnect (self->priv->conn,
+ self->priv->status_changed_id);
+ self->priv->status_changed_id = 0;
+ }
+}
+
+static void
+tp_tests_echo_im_manager_foreach_channel (TpChannelManager *iface,
+ TpExportableChannelFunc callback,
+ gpointer user_data)
+{
+ TpTestsEchoImManager *self = TP_TESTS_ECHO_IM_MANAGER (iface);
+ GHashTableIter iter;
+ gpointer handle, channel;
+
+ g_hash_table_iter_init (&iter, self->priv->channels);
+
+ while (g_hash_table_iter_next (&iter, &handle, &channel))
+ {
+ callback (TP_EXPORTABLE_CHANNEL (channel), user_data);
+ }
+}
+
+static void
+channel_closed_cb (TpTestsEchoChannel *chan,
+ TpTestsEchoImManager *self)
+{
+ tp_channel_manager_emit_channel_closed_for_object (self,
+ TP_EXPORTABLE_CHANNEL (chan));
+
+ if (self->priv->channels != NULL)
+ {
+ TpHandle handle;
+ gboolean really_destroyed;
+
+ g_object_get (chan,
+ "handle", &handle,
+ "channel-destroyed", &really_destroyed,
+ NULL);
+
+ /* Re-announce the channel if it's not yet ready to go away (pending
+ * messages) */
+ if (really_destroyed)
+ {
+ g_hash_table_remove (self->priv->channels,
+ GUINT_TO_POINTER (handle));
+ }
+ else
+ {
+ tp_channel_manager_emit_new_channel (self,
+ TP_EXPORTABLE_CHANNEL (chan), NULL);
+ }
+ }
+}
+
+static void
+new_channel (TpTestsEchoImManager *self,
+ TpHandle handle,
+ TpHandle initiator,
+ gpointer request_token)
+{
+ TpTestsEchoChannel *chan;
+ gchar *object_path;
+ GSList *requests = NULL;
+
+ object_path = g_strdup_printf ("%s/EchoChannel%u",
+ tp_base_connection_get_object_path (self->priv->conn), handle);
+
+ chan = g_object_new (TP_TESTS_TYPE_ECHO_CHANNEL,
+ "connection", self->priv->conn,
+ "object-path", object_path,
+ "handle", handle,
+ "initiator-handle", initiator,
+ NULL);
+
+ g_free (object_path);
+
+ g_signal_connect (chan, "closed", (GCallback) channel_closed_cb, self);
+
+ /* self->priv->channels takes ownership of 'chan' */
+ g_hash_table_insert (self->priv->channels, GUINT_TO_POINTER (handle), chan);
+
+ if (request_token != NULL)
+ requests = g_slist_prepend (requests, request_token);
+
+ tp_channel_manager_emit_new_channel (self, TP_EXPORTABLE_CHANNEL (chan),
+ requests);
+ g_slist_free (requests);
+}
+
+static const gchar * const fixed_properties[] = {
+ TP_PROP_CHANNEL_CHANNEL_TYPE,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+ NULL
+};
+
+static const gchar * const allowed_properties[] = {
+ TP_PROP_CHANNEL_TARGET_HANDLE,
+ TP_PROP_CHANNEL_TARGET_ID,
+ NULL
+};
+
+static void
+tp_tests_echo_im_manager_foreach_channel_class (TpChannelManager *manager,
+ TpChannelManagerChannelClassFunc func,
+ gpointer user_data)
+{
+ GHashTable *table = tp_asv_new (
+ TP_PROP_CHANNEL_CHANNEL_TYPE,
+ G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, TP_HANDLE_TYPE_CONTACT,
+ NULL);
+
+
+ func (manager, table, allowed_properties, user_data);
+
+ g_hash_table_unref (table);
+}
+
+static gboolean
+tp_tests_echo_im_manager_request (TpTestsEchoImManager *self,
+ gpointer request_token,
+ GHashTable *request_properties,
+ gboolean require_new)
+{
+ TpHandle handle;
+ TpTestsEchoChannel *chan;
+ GError *error = NULL;
+
+ if (tp_strdiff (tp_asv_get_string (request_properties,
+ TP_PROP_CHANNEL_CHANNEL_TYPE),
+ TP_IFACE_CHANNEL_TYPE_TEXT))
+ {
+ return FALSE;
+ }
+
+ if (tp_asv_get_uint32 (request_properties,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, NULL) != TP_HANDLE_TYPE_CONTACT)
+ {
+ return FALSE;
+ }
+
+ handle = tp_asv_get_uint32 (request_properties,
+ TP_PROP_CHANNEL_TARGET_HANDLE, NULL);
+ g_assert (handle != 0);
+
+ if (tp_channel_manager_asv_has_unknown_properties (request_properties,
+ fixed_properties, allowed_properties, &error))
+ {
+ goto error;
+ }
+
+ chan = g_hash_table_lookup (self->priv->channels, GUINT_TO_POINTER (handle));
+
+ if (chan == NULL)
+ {
+ new_channel (self, handle,
+ tp_base_connection_get_self_handle (self->priv->conn),
+ request_token);
+ }
+ else if (require_new)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
+ "An echo channel to contact #%u already exists", handle);
+ goto error;
+ }
+ else
+ {
+ tp_channel_manager_emit_request_already_satisfied (self,
+ request_token, TP_EXPORTABLE_CHANNEL (chan));
+ }
+
+ 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
+tp_tests_echo_im_manager_create_channel (TpChannelManager *manager,
+ gpointer request_token,
+ GHashTable *request_properties)
+{
+ return tp_tests_echo_im_manager_request (TP_TESTS_ECHO_IM_MANAGER (manager),
+ request_token, request_properties, TRUE);
+}
+
+static gboolean
+tp_tests_echo_im_manager_ensure_channel (TpChannelManager *manager,
+ gpointer request_token,
+ GHashTable *request_properties)
+{
+ return tp_tests_echo_im_manager_request (TP_TESTS_ECHO_IM_MANAGER (manager),
+ request_token, request_properties, FALSE);
+}
+
+static void
+channel_manager_iface_init (gpointer g_iface,
+ gpointer iface_data G_GNUC_UNUSED)
+{
+ TpChannelManagerIface *iface = g_iface;
+
+ iface->foreach_channel = tp_tests_echo_im_manager_foreach_channel;
+ iface->foreach_channel_class = tp_tests_echo_im_manager_foreach_channel_class;
+ iface->create_channel = tp_tests_echo_im_manager_create_channel;
+ iface->ensure_channel = tp_tests_echo_im_manager_ensure_channel;
+ /* In this channel manager, Request has the same semantics as Ensure */
+ iface->request_channel = tp_tests_echo_im_manager_ensure_channel;
+}
diff --git a/tests/lib/telepathy/contactlist/echo-im-manager.h b/tests/lib/telepathy/contactlist/echo-im-manager.h
new file mode 100644
index 00000000..a33b83ef
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/echo-im-manager.h
@@ -0,0 +1,54 @@
+/*
+ * im-manager.h - header for an example channel manager
+ *
+ * Copyright (C) 2007 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_ECHO_IM_MANAGER_H__
+#define __TP_TESTS_ECHO_IM_MANAGER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsEchoImManager TpTestsEchoImManager;
+typedef struct _TpTestsEchoImManagerClass TpTestsEchoImManagerClass;
+typedef struct _TpTestsEchoImManagerPrivate TpTestsEchoImManagerPrivate;
+
+struct _TpTestsEchoImManagerClass {
+ GObjectClass parent_class;
+};
+
+struct _TpTestsEchoImManager {
+ GObject parent;
+
+ TpTestsEchoImManagerPrivate *priv;
+};
+
+GType tp_tests_echo_im_manager_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_ECHO_IM_MANAGER \
+ (tp_tests_echo_im_manager_get_type ())
+#define TP_TESTS_ECHO_IM_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_ECHO_IM_MANAGER, \
+ TpTestsEchoImManager))
+#define TP_TESTS_ECHO_IM_MANAGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_ECHO_IM_MANAGER, \
+ TpTestsEchoImManagerClass))
+#define TP_TESTS_IS_ECHO_IM_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_ECHO_IM_MANAGER))
+#define TP_TESTS_IS_ECHO_IM_MANAGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_ECHO_IM_MANAGER))
+#define TP_TESTS_ECHO_IM_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_ECHO_IM_MANAGER, \
+ TpTestsEchoImManagerClass))
+
+G_END_DECLS
+
+#endif
diff --git a/tests/lib/telepathy/contactlist/file-transfer-chan.c b/tests/lib/telepathy/contactlist/file-transfer-chan.c
new file mode 100644
index 00000000..92520f48
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/file-transfer-chan.c
@@ -0,0 +1,763 @@
+/*
+ * file-transfer-chan.c - Simple file transfer channel
+ *
+ * Copyright (C) 2010-2011 Morten Mjelva <morten.mjelva@gmail.com>
+ * Copyright (C) 2010-2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "file-transfer-chan.h"
+#include "util.h"
+#include "debug.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#include <glib/gstdio.h>
+
+static void file_transfer_iface_init (gpointer iface, gpointer data);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsFileTransferChannel,
+ tp_tests_file_transfer_channel,
+ TP_TYPE_BASE_CHANNEL,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_FILE_TRANSFER,
+ file_transfer_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA,
+ NULL);
+ )
+
+enum /* properties */
+{
+ PROP_AVAILABLE_SOCKET_TYPES = 1,
+ PROP_CONTENT_TYPE,
+ PROP_CONTENT_HASH,
+ PROP_CONTENT_HASH_TYPE,
+ PROP_DATE,
+ PROP_DESCRIPTION,
+ PROP_FILENAME,
+ PROP_INITIAL_OFFSET,
+ PROP_SIZE,
+ PROP_STATE,
+ PROP_TRANSFERRED_BYTES,
+ PROP_URI,
+ PROP_SERVICE_NAME,
+ PROP_METADATA,
+ N_PROPS,
+};
+
+struct _TpTestsFileTransferChannelPrivate {
+ /* Exposed properties */
+ gchar *content_type;
+ guint64 date;
+ gchar *description;
+ gchar *filename;
+ guint64 size;
+ TpFileTransferState state;
+ guint64 transferred_bytes;
+ gchar *uri;
+ gchar *service_name;
+ GHashTable *metadata;
+
+ /* Hidden properties */
+ TpFileHashType content_hash_type;
+ gchar *content_hash;
+ GHashTable *available_socket_types;
+ gint64 initial_offset;
+
+ /* Accepting side */
+ GSocketService *service;
+ GValue *access_control_param;
+
+ /* Offering side */
+ TpSocketAddressType address_type;
+ GValue *address;
+ gchar *unix_address;
+ gchar *unix_tmpdir;
+ guint connection_id;
+ TpSocketAccessControl access_control;
+
+ guint timer_id;
+};
+
+static void
+tp_tests_file_transfer_channel_init (TpTestsFileTransferChannel *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
+ TP_TESTS_TYPE_FILE_TRANSFER_CHANNEL, TpTestsFileTransferChannelPrivate);
+}
+
+static void
+create_available_socket_types (TpTestsFileTransferChannel *self)
+{
+ TpSocketAccessControl access_control;
+ GArray *unix_tab;
+
+ g_assert (self->priv->available_socket_types == NULL);
+ self->priv->available_socket_types = g_hash_table_new_full (NULL, NULL,
+ NULL, _tp_destroy_socket_control_list);
+
+ /* SocketAddressTypeUnix */
+ unix_tab = g_array_sized_new (FALSE, FALSE, sizeof (TpSocketAccessControl),
+ 1);
+ access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
+ g_array_append_val (unix_tab, access_control);
+
+ g_hash_table_insert (self->priv->available_socket_types,
+ GUINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_UNIX), unix_tab);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object =
+ G_OBJECT_CLASS (tp_tests_file_transfer_channel_parent_class)->constructor
+ (type, n_props, props);
+ TpTestsFileTransferChannel *self = TP_TESTS_FILE_TRANSFER_CHANNEL (object);
+
+ self->priv->state = TP_FILE_TRANSFER_STATE_PENDING;
+
+ if (self->priv->available_socket_types == NULL)
+ create_available_socket_types (self);
+
+ tp_base_channel_register (TP_BASE_CHANNEL (self));
+
+ return object;
+}
+
+static void
+dispose (GObject *object)
+{
+ TpTestsFileTransferChannel *self = TP_TESTS_FILE_TRANSFER_CHANNEL (object);
+
+ if (self->priv->timer_id != 0)
+ {
+ g_source_remove (self->priv->timer_id);
+ self->priv->timer_id = 0;
+ }
+
+ g_free (self->priv->content_hash);
+ g_free (self->priv->content_type);
+ g_free (self->priv->description);
+ g_free (self->priv->filename);
+ g_free (self->priv->uri);
+ g_free (self->priv->service_name);
+
+ tp_clear_pointer (&self->priv->address, tp_g_value_slice_free);
+ tp_clear_pointer (&self->priv->available_socket_types, g_hash_table_unref);
+ tp_clear_pointer (&self->priv->access_control_param, tp_g_value_slice_free);
+ tp_clear_pointer (&self->priv->metadata, g_hash_table_unref);
+
+ if (self->priv->unix_address != NULL)
+ g_unlink (self->priv->unix_address);
+
+ tp_clear_pointer (&self->priv->unix_address, g_free);
+
+ if (self->priv->unix_tmpdir != NULL)
+ g_rmdir (self->priv->unix_tmpdir);
+
+ tp_clear_pointer (&self->priv->unix_tmpdir, g_free);
+
+ ((GObjectClass *) tp_tests_file_transfer_channel_parent_class)->dispose (
+ object);
+}
+
+static void
+get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsFileTransferChannel *self = (TpTestsFileTransferChannel *) object;
+
+ switch (property_id)
+ {
+ case PROP_AVAILABLE_SOCKET_TYPES:
+ g_value_set_boxed (value, self->priv->available_socket_types);
+ break;
+
+ case PROP_CONTENT_HASH:
+ g_value_set_string (value, self->priv->content_hash);
+
+ case PROP_CONTENT_HASH_TYPE:
+ g_value_set_uint (value, self->priv->content_hash_type);
+ break;
+
+ case PROP_CONTENT_TYPE:
+ g_value_set_string (value, self->priv->content_type);
+ break;
+
+ case PROP_DATE:
+ g_value_set_uint64 (value, self->priv->date);
+ break;
+
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, self->priv->description);
+ break;
+
+ case PROP_FILENAME:
+ g_value_set_string (value, self->priv->filename);
+ break;
+
+ case PROP_INITIAL_OFFSET:
+ g_value_set_uint64 (value, self->priv->initial_offset);
+ break;
+
+ case PROP_SIZE:
+ g_value_set_uint64 (value, self->priv->size);
+ break;
+
+ case PROP_STATE:
+ g_value_set_uint (value, self->priv->state);
+ break;
+
+ case PROP_TRANSFERRED_BYTES:
+ g_value_set_uint64 (value, self->priv->transferred_bytes);
+ break;
+
+ case PROP_URI:
+ g_value_set_string (value, self->priv->uri);
+ break;
+
+ case PROP_SERVICE_NAME:
+ g_value_set_string (value, self->priv->service_name);
+ break;
+
+ case PROP_METADATA:
+ g_value_set_boxed (value, self->priv->metadata);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsFileTransferChannel *self = (TpTestsFileTransferChannel *) object;
+
+ switch (property_id)
+ {
+ case PROP_AVAILABLE_SOCKET_TYPES:
+ self->priv->available_socket_types = g_value_dup_boxed (value);
+ break;
+
+ case PROP_CONTENT_HASH:
+ self->priv->content_hash = g_value_dup_string (value);
+ break;
+
+ case PROP_CONTENT_HASH_TYPE:
+ break;
+
+ case PROP_CONTENT_TYPE:
+ self->priv->content_type = g_value_dup_string (value);
+ break;
+
+ case PROP_DATE:
+ self->priv->date = g_value_get_uint64 (value);
+ break;
+
+ case PROP_DESCRIPTION:
+ self->priv->description = g_value_dup_string (value);
+ break;
+
+ case PROP_FILENAME:
+ self->priv->filename = g_value_dup_string (value);
+ break;
+
+ case PROP_INITIAL_OFFSET:
+ self->priv->initial_offset = g_value_get_uint64 (value);
+ break;
+
+ case PROP_SIZE:
+ self->priv->size = g_value_get_uint64 (value);
+ break;
+
+ case PROP_STATE:
+ self->priv->state = g_value_get_uint (value);
+ break;
+
+ case PROP_TRANSFERRED_BYTES:
+ self->priv->transferred_bytes = g_value_get_uint64 (value);
+ break;
+
+ case PROP_URI:
+ self->priv->uri = g_value_dup_string (value);
+ break;
+
+ case PROP_SERVICE_NAME:
+ self->priv->service_name = g_value_dup_string (value);
+ break;
+
+ case PROP_METADATA:
+ self->priv->metadata = g_value_dup_boxed (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+channel_close (TpBaseChannel *self)
+{
+ g_print ("entered channel_close");
+ tp_base_channel_destroyed (self);
+}
+
+static void
+fill_immutable_properties (TpBaseChannel *self,
+ GHashTable *properties)
+{
+ TpBaseChannelClass *klass = TP_BASE_CHANNEL_CLASS (
+ tp_tests_file_transfer_channel_parent_class);
+
+ klass->fill_immutable_properties (self, properties);
+
+ tp_dbus_properties_mixin_fill_properties_hash (
+ G_OBJECT (self), properties,
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "AvailableSocketTypes",
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "ContentType",
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "Filename",
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "Size",
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "Description",
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "Date",
+ TP_IFACE_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA, "ServiceName",
+ TP_IFACE_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA, "Metadata",
+ NULL);
+
+ /* URI is immutable only for outgoing transfers */
+ if (tp_base_channel_is_requested (self))
+ {
+ tp_dbus_properties_mixin_fill_properties_hash (G_OBJECT (self),
+ properties,
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "URI", NULL);
+ }
+}
+
+static void
+change_state (TpTestsFileTransferChannel *self,
+ TpFileTransferState state,
+ TpFileTransferStateChangeReason reason)
+{
+ self->priv->state = state;
+
+ tp_svc_channel_type_file_transfer_emit_file_transfer_state_changed (self,
+ state, reason);
+}
+
+/* This function imitates the beginning of a filetransfer. It sets the state
+ * to open, and connects to the "incoming" signal of the GSocketService.
+ */
+static gboolean
+start_file_transfer (gpointer data)
+{
+ TpTestsFileTransferChannel *self = (TpTestsFileTransferChannel *) data;
+
+ DEBUG ("Setting TP_FILE_TRANSFER_STATE_OPEN");
+ change_state (self, TP_FILE_TRANSFER_STATE_OPEN,
+ TP_FILE_TRANSFER_STATE_CHANGE_REASON_REQUESTED);
+
+ g_object_notify ((GObject *) data, "state");
+ DEBUG ("Fired state signal");
+
+// g_signal_connect (self->priv->service, "incoming", G_CALLBACK
+// (incoming_file_transfer_cb));
+
+ self->priv->timer_id = 0;
+ return FALSE;
+}
+
+static gboolean
+check_address_type (TpTestsFileTransferChannel *self,
+ TpSocketAddressType address_type,
+ TpSocketAccessControl access_control)
+{
+ GArray *arr;
+ guint i;
+
+ arr = g_hash_table_lookup (self->priv->available_socket_types,
+ GUINT_TO_POINTER (address_type));
+ if (arr == NULL)
+ return FALSE;
+
+ for (i = 0; i < arr->len; i++)
+ {
+ if (g_array_index (arr, TpSocketAccessControl, i) == access_control)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+service_incoming_cb (GSocketService *service,
+ GSocketConnection *connection,
+ GObject *source_object,
+ gpointer user_data)
+{
+ TpTestsFileTransferChannel *self = user_data;
+ GError *error = NULL;
+
+ DEBUG ("Servicing incoming connection");
+ if (self->priv->access_control == TP_SOCKET_ACCESS_CONTROL_CREDENTIALS)
+ {
+ GCredentials *creds;
+ guchar byte;
+
+ /* TODO: Async version */
+ creds = tp_unix_connection_receive_credentials_with_byte (
+ connection, &byte, NULL, &error);
+ g_assert_no_error (error);
+
+ g_assert_cmpuint (byte, ==,
+ g_value_get_uchar (self->priv->access_control_param));
+ g_object_unref (creds);
+ }
+ else if (self->priv->access_control == TP_SOCKET_ACCESS_CONTROL_PORT)
+ {
+ GSocketAddress *addr;
+ guint16 port;
+
+ addr = g_socket_connection_get_remote_address (connection, &error);
+ g_assert_no_error (error);
+
+ port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
+
+ g_assert_cmpuint (port, ==,
+ g_value_get_uint (self->priv->access_control_param));
+
+ g_object_unref (addr);
+ }
+}
+
+static void
+file_transfer_provide_file (TpSvcChannelTypeFileTransfer *iface,
+ TpSocketAddressType address_type,
+ TpSocketAccessControl access_control,
+ const GValue *access_control_param,
+ DBusGMethodInvocation *context)
+{
+ TpTestsFileTransferChannel *self = (TpTestsFileTransferChannel *) iface;
+ TpBaseChannel *base_chan = (TpBaseChannel *) iface;
+ GError *error = NULL;
+
+ if (tp_base_channel_is_requested (base_chan) != TRUE)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "File transfer is not outgoing. Cannot offer file");
+ goto fail;
+ }
+
+ if (self->priv->state != TP_FILE_TRANSFER_STATE_PENDING &&
+ self->priv->state != TP_FILE_TRANSFER_STATE_ACCEPTED)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "File transfer is not pending or accepted. Cannot offer file");
+ goto fail;
+ }
+
+ if (self->priv->address != NULL)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
+ "ProvideFile has already been called for this channel");
+ goto fail;
+ }
+
+ if (!check_address_type (self, address_type, access_control))
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "Address type %i is not supported with access control %i",
+ address_type, access_control);
+ goto fail;
+ }
+
+ self->priv->address = _tp_create_local_socket (address_type, access_control,
+ &self->priv->service, &self->priv->unix_address,
+ &self->priv->unix_tmpdir, &error);
+
+ if (self->priv->address == NULL)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
+ "Could not set up local socket");
+ goto fail;
+ }
+
+ self->priv->address_type = address_type;
+ self->priv->access_control = access_control;
+
+ DEBUG ("Waiting 500ms and setting state to OPEN");
+ self->priv->timer_id = g_timeout_add (500, start_file_transfer, self);
+
+ // connect to self->priv->service incoming signal
+ // when the signal returns, add x bytes per n seconds using timeout
+ // then close the socket
+ // g_output_stream_write_async
+
+ tp_svc_channel_type_file_transfer_return_from_provide_file (context,
+ self->priv->address);
+
+ return;
+
+fail:
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+}
+
+static void
+file_transfer_accept_file (TpSvcChannelTypeFileTransfer *iface,
+ TpSocketAddressType address_type,
+ TpSocketAccessControl access_control,
+ const GValue *access_control_param,
+ guint64 offset,
+ DBusGMethodInvocation *context)
+{
+ TpTestsFileTransferChannel *self = (TpTestsFileTransferChannel *) iface;
+ TpBaseChannel *base_chan = (TpBaseChannel *) iface;
+ GError *error = NULL;
+ GValue *address;
+
+ if (tp_base_channel_is_requested (base_chan) == TRUE)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "File transfer is not incoming. Cannot accept file");
+ goto fail;
+ }
+
+ if (self->priv->state != TP_FILE_TRANSFER_STATE_PENDING)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "File transfer is not in the pending state");
+ goto fail;
+ }
+
+ if (!check_address_type (self, address_type, access_control))
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "Address type %i is not supported with access control %i",
+ address_type, access_control);
+ goto fail;
+ }
+
+ address = _tp_create_local_socket (address_type, access_control,
+ &self->priv->service, &self->priv->unix_address,
+ &self->priv->unix_tmpdir, &error);
+
+ tp_g_signal_connect_object (self->priv->service, "incoming",
+ G_CALLBACK (service_incoming_cb), self, 0);
+
+ self->priv->access_control = access_control;
+ self->priv->access_control_param = tp_g_value_slice_dup (
+ access_control_param);
+
+ DEBUG ("Setting TP_FILE_TRANSFER_STATE_ACCEPTED");
+ change_state (self, TP_FILE_TRANSFER_STATE_ACCEPTED,
+ TP_FILE_TRANSFER_STATE_CHANGE_REASON_REQUESTED);
+
+ DEBUG ("Waiting 500ms and setting state to OPEN");
+ self->priv->timer_id = g_timeout_add (500, start_file_transfer, self);
+
+ tp_svc_channel_type_file_transfer_return_from_accept_file (context,
+ address);
+
+ tp_clear_pointer (&address, tp_g_value_slice_free);
+
+ return;
+
+fail:
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+}
+
+static void
+tp_tests_file_transfer_channel_class_init (
+ TpTestsFileTransferChannelClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
+ GParamSpec *param_spec;
+
+ static TpDBusPropertiesMixinPropImpl file_transfer_props[] = {
+ { "AvailableSocketTypes", "available-socket-types", NULL },
+ { "ContentType", "content-type", NULL },
+ { "Date", "date", NULL },
+ { "Description", "description", NULL },
+ { "Filename", "filename", NULL },
+ { "Size", "size", NULL },
+ { "State", "state", NULL },
+ { "TransferredBytes", "transferred-bytes", NULL },
+ { "URI", "uri", NULL },
+ { NULL }
+ };
+
+ static TpDBusPropertiesMixinPropImpl metadata_props[] = {
+ { "ServiceName", "service-name", NULL },
+ { "Metadata", "metadata", NULL },
+ { NULL }
+ };
+
+ object_class->constructor = constructor;
+ object_class->get_property = get_property;
+ object_class->set_property = set_property;
+ object_class->dispose = dispose;
+
+ base_class->channel_type = TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER;
+ base_class->target_handle_type = TP_HANDLE_TYPE_CONTACT;
+
+ base_class->close = channel_close;
+ base_class->fill_immutable_properties = fill_immutable_properties;
+
+ param_spec = g_param_spec_boxed ("available-socket-types",
+ "AvailableSocketTypes",
+ "The AvailableSocketTypes property of this channel",
+ TP_HASH_TYPE_SUPPORTED_SOCKET_MAP,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_AVAILABLE_SOCKET_TYPES,
+ param_spec);
+
+ param_spec = g_param_spec_string ("content-type",
+ "ContentType",
+ "The ContentType property of this channel",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CONTENT_TYPE,
+ param_spec);
+
+ param_spec = g_param_spec_uint64 ("date",
+ "Date",
+ "The Date property of this channel",
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_DATE,
+ param_spec);
+
+ param_spec = g_param_spec_string ("description",
+ "Description",
+ "The Description property of this channel",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_DESCRIPTION,
+ param_spec);
+
+ param_spec = g_param_spec_string ("filename",
+ "Filename",
+ "The Filename property of this channel",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_FILENAME,
+ param_spec);
+
+ param_spec = g_param_spec_uint64 ("initial-offset",
+ "InitialOffset",
+ "The InitialOffset property of this channel",
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_INITIAL_OFFSET,
+ param_spec);
+
+ param_spec = g_param_spec_uint64 ("size",
+ "Size",
+ "The Size property of this channel",
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_SIZE,
+ param_spec);
+
+ param_spec = g_param_spec_uint ("state",
+ "State",
+ "The State property of this channel",
+ 0, TP_NUM_FILE_TRANSFER_STATES, TP_FILE_TRANSFER_STATE_NONE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_STATE,
+ param_spec);
+
+ param_spec = g_param_spec_uint64 ("transferred-bytes",
+ "TransferredBytes",
+ "The TransferredBytes property of this channel",
+ 0, G_MAXUINT64, 0,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_TRANSFERRED_BYTES,
+ param_spec);
+
+ param_spec = g_param_spec_string ("uri",
+ "URI",
+ "The URI property of this channel",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_URI,
+ param_spec);
+
+ param_spec = g_param_spec_string ("service-name",
+ "ServiceName",
+ "The Metadata.ServiceName property of this channel",
+ "",
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_SERVICE_NAME,
+ param_spec);
+
+ param_spec = g_param_spec_boxed ("metadata",
+ "Metadata",
+ "The Metadata.Metadata property of this channel",
+ TP_HASH_TYPE_METADATA,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_METADATA,
+ param_spec);
+
+ tp_dbus_properties_mixin_implement_interface (object_class,
+ TP_IFACE_QUARK_CHANNEL_TYPE_FILE_TRANSFER,
+ tp_dbus_properties_mixin_getter_gobject_properties, NULL,
+ file_transfer_props);
+
+ tp_dbus_properties_mixin_implement_interface (object_class,
+ TP_IFACE_QUARK_CHANNEL_INTERFACE_FILE_TRANSFER_METADATA,
+ tp_dbus_properties_mixin_getter_gobject_properties, NULL,
+ metadata_props);
+
+ g_type_class_add_private (object_class,
+ sizeof (TpTestsFileTransferChannelPrivate));
+}
+
+static void
+file_transfer_iface_init (gpointer iface, gpointer data)
+{
+ TpSvcChannelTypeFileTransferClass *klass = iface;
+
+#define IMPLEMENT(x) tp_svc_channel_type_file_transfer_implement_##x (klass, \
+ file_transfer_##x)
+ IMPLEMENT(accept_file);
+ IMPLEMENT(provide_file);
+#undef IMPLEMENT
+}
+
+/* Return the address of the file transfer's socket */
+GSocketAddress *
+tp_tests_file_transfer_channel_get_server_address (
+ TpTestsFileTransferChannel *self)
+{
+ GSocketAddress *address;
+ GError *error = NULL;
+
+ g_assert (self->priv->address != NULL);
+
+ address = tp_g_socket_address_from_variant (self->priv->address_type,
+ self->priv->address, &error);
+
+ if (error != NULL)
+ {
+ g_printf ("%s\n", error->message);
+ }
+
+ return address;
+}
diff --git a/tests/lib/telepathy/contactlist/file-transfer-chan.h b/tests/lib/telepathy/contactlist/file-transfer-chan.h
new file mode 100644
index 00000000..19d6c98a
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/file-transfer-chan.h
@@ -0,0 +1,63 @@
+/*
+ * stream-tube-chan.h - Simple stream tube channel
+ *
+ * Copyright (C) 2010-2011 Morten Mjelva <morten.mjelva@gmail.com>
+ * Copyright (C) 2010-2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_FILE_TRANSFER_CHAN_H__
+#define __TP_FILE_TRANSFER_CHAN_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsFileTransferChannel TpTestsFileTransferChannel;
+typedef struct _TpTestsFileTransferChannelClass TpTestsFileTransferChannelClass;
+typedef struct _TpTestsFileTransferChannelPrivate TpTestsFileTransferChannelPrivate;
+
+GType tp_tests_file_transfer_channel_get_type (void);
+
+#define TP_TESTS_TYPE_FILE_TRANSFER_CHANNEL \
+ (tp_tests_file_transfer_channel_get_type ())
+#define TP_TESTS_FILE_TRANSFER_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_FILE_TRANSFER_CHANNEL, \
+ TpTestsFileTransferChannel))
+#define TP_TESTS_FILE_TRANSFER_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_FILE_TRANSFER_CHANNEL, \
+ TpTestsFileTransferChannelClass))
+#define TP_TESTS_IS_FILE_TRANSFER_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_FILE_TRANSFER_CHANNEL))
+#define TP_TESTS_IS_FILE_TRANSFER_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_FILE_TRANSFER_CHANNEL))
+#define TP_TESTS_FILE_TRANSFER_CHANNEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_FILE_TRANSFER_CHANNEL, \
+ TpTestsFileTransferChannelClass))
+
+struct _TpTestsFileTransferChannelClass {
+ TpBaseChannelClass parent_class;
+ TpDBusPropertiesMixinClass dbus_properties_class;
+};
+
+struct _TpTestsFileTransferChannel {
+ TpBaseChannel parent;
+
+ TpTestsFileTransferChannelPrivate *priv;
+};
+
+void tp_tests_file_transfer_channel_close (TpTestsFileTransferChannel *self);
+
+GHashTable * tp_tests_file_transfer_channel_get_props (
+ TpTestsFileTransferChannel *self);
+
+GSocketAddress * tp_tests_file_transfer_channel_get_server_address (
+ TpTestsFileTransferChannel *self);
+
+G_END_DECLS
+
+#endif
diff --git a/tests/lib/telepathy/contactlist/my-conn-proxy.c b/tests/lib/telepathy/contactlist/my-conn-proxy.c
new file mode 100644
index 00000000..0d7723c4
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/my-conn-proxy.c
@@ -0,0 +1,364 @@
+/*
+ * my-conn-proxy.c - a simple subclass of TpConnection
+ *
+ * Copyright (C) 2010-2011 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "my-conn-proxy.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+
+G_DEFINE_TYPE (TpTestsMyConnProxy, tp_tests_my_conn_proxy,
+ TP_TYPE_CONNECTION)
+
+static void
+tp_tests_my_conn_proxy_init (TpTestsMyConnProxy *self)
+{
+}
+
+enum {
+ FEAT_CORE,
+ FEAT_A,
+ FEAT_B,
+ FEAT_WRONG_IFACE,
+ FEAT_BAD_DEP,
+ FEAT_FAIL,
+ FEAT_FAIL_DEP,
+ FEAT_RETRY,
+ FEAT_RETRY_DEP,
+ FEAT_BEFORE_CONNECTED,
+ FEAT_INTERFACE_LATER,
+ N_FEAT
+};
+
+static void
+prepare_core_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+
+ /* superclass core features are prepared first */
+ g_assert (tp_proxy_is_prepared (proxy, TP_CONNECTION_FEATURE_CORE));
+
+ result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
+ prepare_core_async);
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+static void
+prepare_a_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+
+ g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
+
+ result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
+ prepare_a_async);
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+static void
+prepare_b_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+
+ g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
+ g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_A));
+
+ result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
+ prepare_b_async);
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+static void
+cannot_be_prepared_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_assert_not_reached ();
+}
+
+static void
+prepare_fail_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+
+ g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
+
+ result = g_simple_async_result_new_error ((GObject *) proxy, callback,
+ user_data, TP_ERROR, TP_ERROR_NOT_AVAILABLE,
+ "No feature for you!");
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+static void
+prepare_retry_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ TpTestsMyConnProxy *self = (TpTestsMyConnProxy *) proxy;
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
+ prepare_retry_async);
+
+ if (!self->retry_feature_success)
+ {
+ /* Fail the first time we try to prepare the feature */
+ g_simple_async_result_set_error (result, TP_ERROR,
+ TP_ERROR_NOT_YET, "Nah");
+ }
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+static void
+prepare_retry_dep_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+
+ g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
+
+ result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
+ prepare_retry_dep_async);
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+static void
+prepare_before_connected_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ TpTestsMyConnProxy *self = (TpTestsMyConnProxy *) proxy;
+ GSimpleAsyncResult *result;
+
+ g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
+
+ result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
+ prepare_before_connected_async);
+
+ if (tp_connection_get_status (TP_CONNECTION (self), NULL) ==
+ TP_CONNECTION_STATUS_CONNECTED)
+ self->before_connected_state = BEFORE_CONNECTED_STATE_CONNECTED;
+ else
+ self->before_connected_state = BEFORE_CONNECTED_STATE_NOT_CONNECTED;
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+static void
+prepare_before_connected_before_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ TpTestsMyConnProxy *self = (TpTestsMyConnProxy *) proxy;
+ GSimpleAsyncResult *result;
+
+ g_assert (tp_proxy_is_prepared (proxy, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE));
+
+ g_assert_cmpuint (tp_connection_get_status (TP_CONNECTION (proxy), NULL), ==,
+ TP_CONNECTION_STATUS_CONNECTING);
+
+ result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
+ prepare_before_connected_before_async);
+
+ self->before_connected_state = BEFORE_CONNECTED_STATE_CONNECTED;
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+static void
+prepare_interface_later_async (TpProxy *proxy,
+ const TpProxyFeature *feature,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *result;
+
+ result = g_simple_async_result_new ((GObject *) proxy, callback, user_data,
+ prepare_interface_later_async);
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+static const TpProxyFeature *
+list_features (TpProxyClass *cls G_GNUC_UNUSED)
+{
+ static TpProxyFeature features[N_FEAT + 1] = { { 0 } };
+ static GQuark need_a[2] = {0, 0};
+ static GQuark need_channel_core[2] = {0, 0};
+ static GQuark need_wrong_iface[2] = {0, 0};
+ static GQuark need_fail[2] = {0, 0};
+ static GQuark need_retry[2] = {0, 0};
+ static GQuark need_iface_later[2] = {0, 0};
+
+ if (G_LIKELY (features[0].name != 0))
+ return features;
+
+ features[FEAT_CORE].name = TP_TESTS_MY_CONN_PROXY_FEATURE_CORE;
+ features[FEAT_CORE].core = TRUE;
+ features[FEAT_CORE].prepare_async = prepare_core_async;
+
+ features[FEAT_A].name = TP_TESTS_MY_CONN_PROXY_FEATURE_A;
+ features[FEAT_A].prepare_async = prepare_a_async;
+
+ features[FEAT_B].name = TP_TESTS_MY_CONN_PROXY_FEATURE_B;
+ features[FEAT_B].prepare_async = prepare_b_async;
+ need_a[0] = TP_TESTS_MY_CONN_PROXY_FEATURE_A;
+ features[FEAT_B].depends_on = need_a;
+
+ features[FEAT_WRONG_IFACE].name = TP_TESTS_MY_CONN_PROXY_FEATURE_WRONG_IFACE;
+ features[FEAT_WRONG_IFACE].prepare_async = cannot_be_prepared_async;
+ need_channel_core[0] = TP_CHANNEL_FEATURE_CORE;
+ features[FEAT_WRONG_IFACE].interfaces_needed = need_channel_core;
+
+ features[FEAT_BAD_DEP].name = TP_TESTS_MY_CONN_PROXY_FEATURE_BAD_DEP;
+ features[FEAT_BAD_DEP].prepare_async = cannot_be_prepared_async;
+ need_wrong_iface[0] = TP_TESTS_MY_CONN_PROXY_FEATURE_WRONG_IFACE;
+ features[FEAT_BAD_DEP].depends_on = need_wrong_iface;
+
+ features[FEAT_FAIL].name = TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL;
+ features[FEAT_FAIL].prepare_async = prepare_fail_async;
+
+ features[FEAT_FAIL_DEP].name = TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL_DEP;
+ features[FEAT_FAIL_DEP].prepare_async = cannot_be_prepared_async;
+ need_fail[0] = TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL;
+ features[FEAT_FAIL_DEP].depends_on = need_fail;
+
+ features[FEAT_RETRY].name = TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY;
+ features[FEAT_RETRY].prepare_async = prepare_retry_async;
+ features[FEAT_RETRY].can_retry = TRUE;
+
+ features[FEAT_RETRY_DEP].name = TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY_DEP;
+ need_retry[0] = TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY;
+ features[FEAT_RETRY_DEP].prepare_async = prepare_retry_dep_async;
+ features[FEAT_RETRY_DEP].depends_on = need_retry;
+
+ features[FEAT_BEFORE_CONNECTED].name =
+ TP_TESTS_MY_CONN_PROXY_FEATURE_BEFORE_CONNECTED;
+ features[FEAT_BEFORE_CONNECTED].prepare_async =
+ prepare_before_connected_async;
+ features[FEAT_BEFORE_CONNECTED].prepare_before_signalling_connected_async =
+ prepare_before_connected_before_async;
+
+ features[FEAT_INTERFACE_LATER].name =
+ TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER;
+ features[FEAT_INTERFACE_LATER].prepare_async = prepare_interface_later_async;
+ need_iface_later[0] = g_quark_from_static_string (
+ TP_TESTS_MY_CONN_PROXY_IFACE_LATER);
+ features[FEAT_INTERFACE_LATER].interfaces_needed = need_iface_later;
+
+ return features;
+}
+
+static void
+tp_tests_my_conn_proxy_class_init (TpTestsMyConnProxyClass *klass)
+{
+ TpProxyClass *proxy_class = (TpProxyClass *) klass;
+
+ proxy_class->list_features = list_features;
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_core (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-core");
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_a (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-a");
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_b (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-b");
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_wrong_iface (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-wrong_iface");
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_bad_dep (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-bad-dep");
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_fail (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-fail");
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_fail_dep (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-fail-dep");
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_retry (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-retry");
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_retry_dep (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-retry-dep");
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_before_connected (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-before-connected");
+}
+
+GQuark
+tp_tests_my_conn_proxy_get_feature_quark_interface_later (void)
+{
+ return g_quark_from_static_string ("tp-my-conn-proxy-feature-interface-later");
+}
diff --git a/tests/lib/telepathy/contactlist/my-conn-proxy.h b/tests/lib/telepathy/contactlist/my-conn-proxy.h
new file mode 100644
index 00000000..08be18b9
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/my-conn-proxy.h
@@ -0,0 +1,124 @@
+/*
+ * my-conn-proxy.h - header for a simple subclass of TpConnection
+ *
+ * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_MY_CONN_PROXY_H__
+#define __TP_TESTS_MY_CONN_PROXY_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsMyConnProxy TpTestsMyConnProxy;
+typedef struct _TpTestsMyConnProxyClass TpTestsMyConnProxyClass;
+typedef struct _TpTestsMyConnProxyPrivate TpTestsMyConnProxyPrivate;
+
+struct _TpTestsMyConnProxyClass {
+ TpConnectionClass parent_class;
+};
+
+typedef enum
+{
+ BEFORE_CONNECTED_STATE_UNPREPARED = 0,
+ BEFORE_CONNECTED_STATE_NOT_CONNECTED,
+ BEFORE_CONNECTED_STATE_CONNECTED,
+} TpTestsMyConnProxyBeforeConnectedState;
+
+
+struct _TpTestsMyConnProxy {
+ TpConnection parent;
+
+ gboolean retry_feature_success;
+ TpTestsMyConnProxyBeforeConnectedState before_connected_state;
+};
+
+GType tp_tests_my_conn_proxy_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_MY_CONN_PROXY \
+ (tp_tests_my_conn_proxy_get_type ())
+#define TP_TESTS_MY_CONN_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_MY_CONN_PROXY, \
+ TpTestsMyConnProxy))
+#define TP_TESTS_MY_CONN_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_MY_CONN_PROXY, \
+ TpTestsMyConnProxyClass))
+#define TP_TESTS_SIMPLE_IS_MY_CONN_PROXY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_MY_CONN_PROXY))
+#define TP_TESTS_SIMPLE_IS_MY_CONN_PROXY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_MY_CONN_PROXY))
+#define TP_TESTS_MY_CONN_PROXY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_MY_CONN_PROXY, \
+ TpTestsMyConnProxyClass))
+
+/* Core feature */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_CORE \
+ (tp_tests_my_conn_proxy_get_feature_quark_core ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_core (void) G_GNUC_CONST;
+
+/* No depends */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_A \
+ (tp_tests_my_conn_proxy_get_feature_quark_a ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_a (void) G_GNUC_CONST;
+
+/* Depends on A */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_B \
+ (tp_tests_my_conn_proxy_get_feature_quark_b ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_b (void) G_GNUC_CONST;
+
+/* Depends on an unimplemented iface */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_WRONG_IFACE \
+ (tp_tests_my_conn_proxy_get_feature_quark_wrong_iface ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_wrong_iface (void) G_GNUC_CONST;
+
+/* Depends on WRONG_IFACE */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_BAD_DEP \
+ (tp_tests_my_conn_proxy_get_feature_quark_bad_dep ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_bad_dep (void) G_GNUC_CONST;
+
+/* Fail during preparation */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL \
+ (tp_tests_my_conn_proxy_get_feature_quark_fail ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_fail (void) G_GNUC_CONST;
+
+/* Depends on FAIL */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL_DEP \
+ (tp_tests_my_conn_proxy_get_feature_quark_fail_dep ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_fail_dep (void) G_GNUC_CONST;
+
+/* Fail at first attempt but succeed after */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY \
+ (tp_tests_my_conn_proxy_get_feature_quark_retry ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_retry (void) G_GNUC_CONST;
+
+/* Depends on FEATURE_RETRY */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY_DEP \
+ (tp_tests_my_conn_proxy_get_feature_quark_retry_dep ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_retry_dep (void) G_GNUC_CONST;
+
+/* Can be prepared before the connection is connected and block announcing the
+ * connected state */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_BEFORE_CONNECTED \
+ (tp_tests_my_conn_proxy_get_feature_quark_before_connected ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_before_connected (void) G_GNUC_CONST;
+
+#define TP_TESTS_MY_CONN_PROXY_IFACE_LATER "org.freedesktop.Telepathy.Conncetion.Interface.Test.Later"
+
+/* Need the interface TP_TESTS_MY_CONN_PROXY_IFACE_LATER to be prepared but
+ * this interface is not in the initial set of interfaces of the connection.
+ * It is added when the connection is connected. */
+#define TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER \
+ (tp_tests_my_conn_proxy_get_feature_quark_interface_later ())
+GQuark tp_tests_my_conn_proxy_get_feature_quark_interface_later (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_MY_CONN_PROXY_H__ */
diff --git a/tests/lib/telepathy/contactlist/myassert.h b/tests/lib/telepathy/contactlist/myassert.h
new file mode 100644
index 00000000..1fd6fd3b
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/myassert.h
@@ -0,0 +1,16 @@
+#ifndef TP_TESTS_MYASSERT_H
+#define TP_TESTS_MYASSERT_H
+
+#include <glib.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+#define MYASSERT(assertion, extra_format, ...)\
+ G_STMT_START {\
+ if (!(assertion))\
+ {\
+ g_error ("\n%s:%d: Assertion failed: %s" extra_format,\
+ __FILE__, __LINE__, #assertion, ##__VA_ARGS__);\
+ }\
+ } G_STMT_END
+
+#endif
diff --git a/tests/lib/telepathy/contactlist/room-list-chan.c b/tests/lib/telepathy/contactlist/room-list-chan.c
index 49ed291a..f4db0670 100644
--- a/tests/lib/telepathy/contactlist/room-list-chan.c
+++ b/tests/lib/telepathy/contactlist/room-list-chan.c
@@ -4,8 +4,7 @@
#include "room-list-chan.h"
#include <telepathy-glib/telepathy-glib.h>
-#include <telepathy-glib/channel-iface.h>
-#include <telepathy-glib/svc-channel.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
static void room_list_iface_init (gpointer iface,
gpointer data);
diff --git a/tests/lib/telepathy/contactlist/room-list-chan.h b/tests/lib/telepathy/contactlist/room-list-chan.h
index b41be273..52dbd2e8 100644
--- a/tests/lib/telepathy/contactlist/room-list-chan.h
+++ b/tests/lib/telepathy/contactlist/room-list-chan.h
@@ -3,7 +3,7 @@
#define __TP_TESTS_ROOM_LIST_CHAN_H__
#include <glib-object.h>
-#include <telepathy-glib/base-channel.h>
+#include <telepathy-glib/telepathy-glib.h>
G_BEGIN_DECLS
diff --git a/tests/lib/telepathy/contactlist/simple-account-manager.c b/tests/lib/telepathy/contactlist/simple-account-manager.c
index e1fec674..e5bddbc1 100644
--- a/tests/lib/telepathy/contactlist/simple-account-manager.c
+++ b/tests/lib/telepathy/contactlist/simple-account-manager.c
@@ -13,12 +13,8 @@
#include "simple-account-manager.h"
-#include <telepathy-glib/account.h>
-#include <telepathy-glib/gtypes.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/svc-generic.h>
-#include <telepathy-glib/svc-account-manager.h>
-#include <telepathy-glib/util.h>
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
static void account_manager_iface_init (gpointer, gpointer);
@@ -39,14 +35,14 @@ enum
{
PROP_0,
PROP_INTERFACES,
- PROP_VALID_ACCOUNTS,
- PROP_INVALID_ACCOUNTS,
+ PROP_USABLE_ACCOUNTS,
+ PROP_UNUSABLE_ACCOUNTS,
};
struct _TpTestsSimpleAccountManagerPrivate
{
- GPtrArray *valid_accounts;
- GPtrArray *invalid_accounts;
+ GPtrArray *usable_accounts;
+ GPtrArray *unusable_accounts;
};
static void
@@ -95,8 +91,8 @@ tp_tests_simple_account_manager_init (TpTestsSimpleAccountManager *self)
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER, TpTestsSimpleAccountManagerPrivate);
- self->priv->valid_accounts = g_ptr_array_new_with_free_func (g_free);
- self->priv->invalid_accounts = g_ptr_array_new_with_free_func (g_free);
+ self->priv->usable_accounts = g_ptr_array_new_with_free_func (g_free);
+ self->priv->unusable_accounts = g_ptr_array_new_with_free_func (g_free);
}
static void
@@ -112,12 +108,12 @@ tp_tests_simple_account_manager_get_property (GObject *object,
g_value_set_boxed (value, ACCOUNT_MANAGER_INTERFACES);
break;
- case PROP_VALID_ACCOUNTS:
- g_value_set_boxed (value, self->priv->valid_accounts);
+ case PROP_USABLE_ACCOUNTS:
+ g_value_set_boxed (value, self->priv->usable_accounts);
break;
- case PROP_INVALID_ACCOUNTS:
- g_value_set_boxed (value, self->priv->invalid_accounts);
+ case PROP_UNUSABLE_ACCOUNTS:
+ g_value_set_boxed (value, self->priv->unusable_accounts);
break;
default:
@@ -131,8 +127,8 @@ tp_tests_simple_account_manager_finalize (GObject *object)
{
TpTestsSimpleAccountManager *self = SIMPLE_ACCOUNT_MANAGER (object);
- g_ptr_array_unref (self->priv->valid_accounts);
- g_ptr_array_unref (self->priv->invalid_accounts);
+ g_ptr_array_unref (self->priv->usable_accounts);
+ g_ptr_array_unref (self->priv->unusable_accounts);
tp_clear_pointer (&self->create_cm, g_free);
tp_clear_pointer (&self->create_protocol, g_free);
@@ -160,8 +156,8 @@ tp_tests_simple_account_manager_class_init (
static TpDBusPropertiesMixinPropImpl am_props[] = {
{ "Interfaces", "interfaces", NULL },
- { "ValidAccounts", "valid-accounts", NULL },
- { "InvalidAccounts", "invalid-accounts", NULL },
+ { "UsableAccounts", "usable-accounts", NULL },
+ { "UnusableAccounts", "unusable-accounts", NULL },
/*
{ "SupportedAccountProperties", "supported-account-properties", NULL },
*/
@@ -186,16 +182,16 @@ tp_tests_simple_account_manager_class_init (
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_boxed ("valid-accounts", "Valid accounts",
- "The accounts which are valid on this account. This may be a lie.",
+ param_spec = g_param_spec_boxed ("usable-accounts", "Usable accounts",
+ "The accounts which are usable on this account manager. This may be a lie.",
TP_ARRAY_TYPE_OBJECT_PATH_LIST,
G_PARAM_READABLE);
- g_object_class_install_property (object_class, PROP_VALID_ACCOUNTS, param_spec);
- param_spec = g_param_spec_boxed ("invalid-accounts", "Invalid accounts",
- "The accounts which are invalid on this account. This may be a lie.",
+ g_object_class_install_property (object_class, PROP_USABLE_ACCOUNTS, param_spec);
+ param_spec = g_param_spec_boxed ("unusable-accounts", "Unusable accounts",
+ "The accounts which are unusable on this account manager. This may be a lie.",
TP_ARRAY_TYPE_OBJECT_PATH_LIST,
G_PARAM_READABLE);
- g_object_class_install_property (object_class, PROP_INVALID_ACCOUNTS, param_spec);
+ g_object_class_install_property (object_class, PROP_UNUSABLE_ACCOUNTS, param_spec);
klass->dbus_props_class.interfaces = prop_interfaces;
tp_dbus_properties_mixin_class_init (object_class,
@@ -219,17 +215,18 @@ void
tp_tests_simple_account_manager_add_account (
TpTestsSimpleAccountManager *self,
const gchar *object_path,
- gboolean valid)
+ gboolean usable)
{
- remove_from_array (self->priv->valid_accounts, object_path);
- remove_from_array (self->priv->valid_accounts, object_path);
+ remove_from_array (self->priv->usable_accounts, object_path);
+ remove_from_array (self->priv->unusable_accounts, object_path);
- if (valid)
- g_ptr_array_add (self->priv->valid_accounts, g_strdup (object_path));
+ if (usable)
+ g_ptr_array_add (self->priv->usable_accounts, g_strdup (object_path));
else
- g_ptr_array_add (self->priv->invalid_accounts, g_strdup (object_path));
+ g_ptr_array_add (self->priv->unusable_accounts, g_strdup (object_path));
- tp_svc_account_manager_emit_account_validity_changed (self, object_path, valid);
+ tp_svc_account_manager_emit_account_usability_changed (self, object_path,
+ usable);
}
void
@@ -237,8 +234,8 @@ tp_tests_simple_account_manager_remove_account (
TpTestsSimpleAccountManager *self,
const gchar *object_path)
{
- remove_from_array (self->priv->valid_accounts, object_path);
- remove_from_array (self->priv->valid_accounts, object_path);
+ remove_from_array (self->priv->usable_accounts, object_path);
+ remove_from_array (self->priv->unusable_accounts, object_path);
tp_svc_account_manager_emit_account_removed (self, object_path);
}
diff --git a/tests/lib/telepathy/contactlist/simple-account-manager.h b/tests/lib/telepathy/contactlist/simple-account-manager.h
index d1608d51..cc65f092 100644
--- a/tests/lib/telepathy/contactlist/simple-account-manager.h
+++ b/tests/lib/telepathy/contactlist/simple-account-manager.h
@@ -13,7 +13,7 @@
#define __TP_TESTS_SIMPLE_ACCOUNT_MANAGER_H__
#include <glib-object.h>
-#include <telepathy-glib/dbus-properties-mixin.h>
+#include <telepathy-glib/telepathy-glib.h>
G_BEGIN_DECLS
@@ -61,7 +61,7 @@ GType tp_tests_simple_account_manager_get_type (void);
void tp_tests_simple_account_manager_add_account (
TpTestsSimpleAccountManager *self,
const gchar *object_path,
- gboolean valid);
+ gboolean usable);
void tp_tests_simple_account_manager_remove_account (
TpTestsSimpleAccountManager *self,
diff --git a/tests/lib/telepathy/contactlist/simple-account.c b/tests/lib/telepathy/contactlist/simple-account.c
index 6279d755..8b13268b 100644
--- a/tests/lib/telepathy/contactlist/simple-account.c
+++ b/tests/lib/telepathy/contactlist/simple-account.c
@@ -12,14 +12,8 @@
#include "simple-account.h"
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/defs.h>
-#include <telepathy-glib/enums.h>
-#include <telepathy-glib/gtypes.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/util.h>
-#include <telepathy-glib/svc-generic.h>
-#include <telepathy-glib/svc-account.h>
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
static void account_iface_init (gpointer, gpointer);
@@ -50,7 +44,7 @@ enum
PROP_INTERFACES,
PROP_DISPLAY_NAME,
PROP_ICON,
- PROP_VALID,
+ PROP_USABLE,
PROP_ENABLED,
PROP_NICKNAME,
PROP_PARAMETERS,
@@ -80,6 +74,7 @@ struct _TpTestsSimpleAccountPrivate
gchar *presence_msg;
gchar *connection_path;
gboolean enabled;
+ GPtrArray *uri_schemes;
};
static void
@@ -122,10 +117,14 @@ account_iface_init (gpointer klass,
#undef IMPLEMENT
}
+/* you may have noticed this is not entirely realistic */
+static const gchar * const uri_schemes[] = { "about", "telnet", NULL };
static void
tp_tests_simple_account_init (TpTestsSimpleAccount *self)
{
+ guint i;
+
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TESTS_TYPE_SIMPLE_ACCOUNT,
TpTestsSimpleAccountPrivate);
@@ -134,10 +133,11 @@ tp_tests_simple_account_init (TpTestsSimpleAccount *self)
self->priv->presence_msg = g_strdup ("this is my CurrentPresence");
self->priv->connection_path = g_strdup ("/");
self->priv->enabled = TRUE;
-}
-/* you may have noticed this is not entirely realistic */
-static const gchar * const uri_schemes[] = { "about", "telnet", NULL };
+ self->priv->uri_schemes = g_ptr_array_new_with_free_func (g_free);
+ for (i = 0; uri_schemes[i] != NULL; i++)
+ g_ptr_array_add (self->priv->uri_schemes, g_strdup (uri_schemes[i]));
+}
static void
tp_tests_simple_account_get_property (GObject *object,
@@ -161,7 +161,7 @@ tp_tests_simple_account_get_property (GObject *object,
case PROP_ICON:
g_value_set_string (value, "");
break;
- case PROP_VALID:
+ case PROP_USABLE:
g_value_set_boolean (value, TRUE);
break;
case PROP_ENABLED:
@@ -213,7 +213,7 @@ tp_tests_simple_account_get_property (GObject *object,
g_value_set_boolean (value, TRUE);
break;
case PROP_STORAGE_PROVIDER:
- g_value_set_string (value, "org.freedesktop.Telepathy.glib.test");
+ g_value_set_string (value, "im.telepathy1.glib.test");
break;
case PROP_STORAGE_IDENTIFIER:
g_value_set_boxed (value, &identifier);
@@ -231,7 +231,19 @@ tp_tests_simple_account_get_property (GObject *object,
TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PARAMETERS);
break;
case PROP_URI_SCHEMES:
- g_value_set_boxed (value, uri_schemes);
+ {
+ GPtrArray *arr;
+ guint i;
+
+ arr = g_ptr_array_sized_new (self->priv->uri_schemes->len + 1);
+ for (i = 0; i < self->priv->uri_schemes->len; i++)
+ g_ptr_array_add (arr,
+ g_ptr_array_index (self->priv->uri_schemes, i));
+ g_ptr_array_add (arr, NULL);
+
+ g_value_set_boxed (value, arr->pdata);
+ g_ptr_array_unref (arr);
+ }
break;
case PROP_AVATAR:
{
@@ -274,6 +286,8 @@ tp_tests_simple_account_finalize (GObject *object)
g_free (self->priv->presence_msg);
g_free (self->priv->connection_path);
+ g_ptr_array_unref (self->priv->uri_schemes);
+
G_OBJECT_CLASS (tp_tests_simple_account_parent_class)->finalize (object);
}
@@ -292,7 +306,7 @@ tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass)
{ "Interfaces", "interfaces", NULL },
{ "DisplayName", "display-name", NULL },
{ "Icon", "icon", NULL },
- { "Valid", "valid", NULL },
+ { "Usable", "usable", NULL },
{ "Enabled", "enabled", NULL },
{ "Nickname", "nickname", NULL },
{ "Parameters", "parameters", NULL },
@@ -375,11 +389,11 @@ tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_ICON, param_spec);
- param_spec = g_param_spec_boolean ("valid", "valid",
- "Valid property",
+ param_spec = g_param_spec_boolean ("usable", "usable",
+ "Usable property",
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_VALID, param_spec);
+ g_object_class_install_property (object_class, PROP_USABLE, param_spec);
param_spec = g_param_spec_boolean ("enabled", "enabled",
"Enabled property",
@@ -401,7 +415,7 @@ tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass)
param_spec = g_param_spec_boxed ("automatic-presence", "automatic presence",
"AutomaticPresence property",
- TP_STRUCT_TYPE_SIMPLE_PRESENCE,
+ TP_STRUCT_TYPE_PRESENCE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_AUTOMATIC_PRESENCE,
param_spec);
@@ -435,14 +449,14 @@ tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass)
param_spec = g_param_spec_boxed ("current-presence", "current presence",
"CurrentPresence property",
- TP_STRUCT_TYPE_SIMPLE_PRESENCE,
+ TP_STRUCT_TYPE_PRESENCE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_CURRENT_PRESENCE,
param_spec);
param_spec = g_param_spec_boxed ("requested-presence", "requested presence",
"RequestedPresence property",
- TP_STRUCT_TYPE_SIMPLE_PRESENCE,
+ TP_STRUCT_TYPE_PRESENCE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_REQUESTED_PRESENCE,
param_spec);
@@ -533,12 +547,12 @@ tp_tests_simple_account_set_presence (TpTestsSimpleAccount *self,
g_object_get (self, "current-presence", &v, NULL);
props = tp_asv_new (
- "CurrentPresence", TP_STRUCT_TYPE_SIMPLE_PRESENCE, v,
+ "CurrentPresence", TP_STRUCT_TYPE_PRESENCE, v,
NULL);
tp_svc_account_emit_account_property_changed (self, props);
- g_boxed_free (TP_STRUCT_TYPE_SIMPLE_PRESENCE, v);
+ g_boxed_free (TP_STRUCT_TYPE_PRESENCE, v);
}
void
@@ -578,3 +592,25 @@ tp_tests_simple_account_set_enabled (TpTestsSimpleAccount *self,
tp_svc_account_emit_account_property_changed (self, change);
g_hash_table_unref (change);
}
+
+void
+tp_tests_simple_account_add_uri_scheme (TpTestsSimpleAccount *self,
+ const gchar *uri_scheme)
+{
+ GHashTable *changed;
+ GStrv schemes;
+
+ g_ptr_array_add (self->priv->uri_schemes, g_strdup (uri_scheme));
+
+ g_object_get (self, "uri-schemes", &schemes, NULL);
+
+ changed = tp_asv_new (
+ "URISchemes", G_TYPE_STRV, schemes,
+ NULL);
+
+ tp_svc_dbus_properties_emit_properties_changed (self,
+ TP_IFACE_ACCOUNT_INTERFACE_ADDRESSING, changed, NULL);
+
+ g_strfreev (schemes);
+ g_hash_table_unref (changed);
+}
diff --git a/tests/lib/telepathy/contactlist/simple-account.h b/tests/lib/telepathy/contactlist/simple-account.h
index 2ce3efd1..351c6cc2 100644
--- a/tests/lib/telepathy/contactlist/simple-account.h
+++ b/tests/lib/telepathy/contactlist/simple-account.h
@@ -13,8 +13,7 @@
#include <glib-object.h>
-#include <telepathy-glib/connection.h>
-#include <telepathy-glib/dbus-properties-mixin.h>
+#include <telepathy-glib/telepathy-glib.h>
G_BEGIN_DECLS
@@ -64,6 +63,9 @@ void tp_tests_simple_account_removed (TpTestsSimpleAccount *self);
void tp_tests_simple_account_set_enabled (TpTestsSimpleAccount *self,
gboolean enabled);
+void tp_tests_simple_account_add_uri_scheme (TpTestsSimpleAccount *self,
+ const gchar * uri_scheme);
+
G_END_DECLS
#endif /* #ifndef __TP_TESTS_SIMPLE_ACCOUNT_H__ */
diff --git a/tests/lib/telepathy/contactlist/simple-channel-dispatch-operation.c b/tests/lib/telepathy/contactlist/simple-channel-dispatch-operation.c
new file mode 100644
index 00000000..82b38197
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/simple-channel-dispatch-operation.c
@@ -0,0 +1,303 @@
+/*
+ * simple-channel-dispatch-operation.c - a simple channel dispatch operation
+ * service.
+ *
+ * Copyright Ā© 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "simple-channel-dispatch-operation.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+static void channel_dispatch_operation_iface_init (gpointer, gpointer);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleChannelDispatchOperation,
+ tp_tests_simple_channel_dispatch_operation,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_DISPATCH_OPERATION,
+ channel_dispatch_operation_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+ tp_dbus_properties_mixin_iface_init)
+ )
+
+/* TP_IFACE_CHANNEL_DISPATCH_OPERATION is implied */
+static const char *CHANNEL_DISPATCH_OPERATION_INTERFACES[] = { NULL };
+
+static const gchar *CHANNEL_DISPATCH_OPERATION_POSSIBLE_HANDLERS[] = {
+ TP_CLIENT_BUS_NAME_BASE ".Badger", NULL, };
+
+enum
+{
+ PROP_0,
+ PROP_INTERFACES,
+ PROP_CONNECTION,
+ PROP_ACCOUNT,
+ PROP_CHANNELS,
+ PROP_POSSIBLE_HANDLERS,
+};
+
+struct _SimpleChannelDispatchOperationPrivate
+{
+ gchar *conn_path;
+ gchar *account_path;
+ /* Array of TpChannel */
+ GPtrArray *channels;
+};
+
+static void
+tp_tests_simple_channel_dispatch_operation_handle_with (
+ TpSvcChannelDispatchOperation *iface,
+ const gchar *handler,
+ DBusGMethodInvocation *context)
+{
+ if (!tp_strdiff (handler, "FAIL"))
+ {
+ GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Nope" };
+
+ dbus_g_method_return_error (context, &error);
+ return;
+ }
+
+ dbus_g_method_return (context);
+}
+
+static void
+tp_tests_simple_channel_dispatch_operation_claim (
+ TpSvcChannelDispatchOperation *iface,
+ DBusGMethodInvocation *context)
+{
+ tp_svc_channel_dispatch_operation_emit_finished (iface);
+
+ dbus_g_method_return (context);
+}
+
+static void
+tp_tests_simple_channel_dispatch_operation_handle_with_time (
+ TpSvcChannelDispatchOperation *iface,
+ const gchar *handler,
+ gint64 user_action_timestamp,
+ DBusGMethodInvocation *context)
+{
+ dbus_g_method_return (context);
+}
+
+static void
+channel_dispatch_operation_iface_init (gpointer klass,
+ gpointer unused G_GNUC_UNUSED)
+{
+#define IMPLEMENT(x) tp_svc_channel_dispatch_operation_implement_##x (\
+ klass, tp_tests_simple_channel_dispatch_operation_##x)
+ IMPLEMENT(handle_with);
+ IMPLEMENT(claim);
+ IMPLEMENT(handle_with_time);
+#undef IMPLEMENT
+}
+
+
+static void
+tp_tests_simple_channel_dispatch_operation_init (TpTestsSimpleChannelDispatchOperation *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCH_OPERATION,
+ TpTestsSimpleChannelDispatchOperationPrivate);
+
+ self->priv->channels = g_ptr_array_new_with_free_func (
+ (GDestroyNotify) g_object_unref);
+}
+
+static void
+tp_tests_simple_channel_dispatch_operation_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *spec)
+{
+ TpTestsSimpleChannelDispatchOperation *self =
+ TP_TESTS_SIMPLE_CHANNEL_DISPATCH_OPERATION (object);
+
+ switch (property_id) {
+ case PROP_INTERFACES:
+ g_value_set_boxed (value, CHANNEL_DISPATCH_OPERATION_INTERFACES);
+ break;
+
+ case PROP_ACCOUNT:
+ g_value_set_boxed (value, self->priv->account_path);
+ break;
+
+ case PROP_CONNECTION:
+ g_value_set_boxed (value, self->priv->conn_path);
+ break;
+
+ case PROP_CHANNELS:
+ {
+ GPtrArray *arr = g_ptr_array_new ();
+ guint i;
+
+ for (i = 0; i < self->priv->channels->len; i++)
+ {
+ TpChannel *channel = g_ptr_array_index (self->priv->channels, i);
+ GValue props_value = G_VALUE_INIT;
+ GVariant *props_variant;
+
+ /* Yay, double conversion! But this is for tests corner case */
+ props_variant = tp_channel_dup_immutable_properties (channel);
+ dbus_g_value_parse_g_variant (props_variant, &props_value);
+
+ g_ptr_array_add (arr,
+ tp_value_array_build (2,
+ DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (channel),
+ TP_HASH_TYPE_STRING_VARIANT_MAP,
+ g_value_get_boxed (&props_value),
+ G_TYPE_INVALID));
+
+ g_variant_unref (props_variant);
+ g_value_unset (&props_value);
+ }
+
+ g_value_take_boxed (value, arr);
+ }
+ break;
+
+ case PROP_POSSIBLE_HANDLERS:
+ g_value_set_boxed (value, CHANNEL_DISPATCH_OPERATION_POSSIBLE_HANDLERS);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+ break;
+ }
+}
+
+static void
+tp_tests_simple_channel_dispatch_operation_finalize (GObject *object)
+{
+ TpTestsSimpleChannelDispatchOperation *self =
+ TP_TESTS_SIMPLE_CHANNEL_DISPATCH_OPERATION (object);
+ void (*finalize) (GObject *) =
+ G_OBJECT_CLASS (tp_tests_simple_channel_dispatch_operation_parent_class)->finalize;
+
+ g_free (self->priv->conn_path);
+ g_free (self->priv->account_path);
+ g_ptr_array_unref (self->priv->channels);
+
+ if (finalize != NULL)
+ finalize (object);
+}
+
+/**
+ * This class currently only provides the minimum for
+ * tp_channel_dispatch_operation_prepare to succeed. This turns out to be only a working
+ * Properties.GetAll().
+ */
+static void
+tp_tests_simple_channel_dispatch_operation_class_init (TpTestsSimpleChannelDispatchOperationClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ GParamSpec *param_spec;
+
+ static TpDBusPropertiesMixinPropImpl a_props[] = {
+ { "Interfaces", "interfaces", NULL },
+ { "Connection", "connection", NULL },
+ { "Account", "account", NULL },
+ { "Channels", "channels", NULL },
+ { "PossibleHandlers", "possible-handlers", NULL },
+ { NULL }
+ };
+
+ static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+ { TP_IFACE_CHANNEL_DISPATCH_OPERATION,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ a_props
+ },
+ { NULL },
+ };
+
+ g_type_class_add_private (klass, sizeof (TpTestsSimpleChannelDispatchOperationPrivate));
+ object_class->get_property = tp_tests_simple_channel_dispatch_operation_get_property;
+ object_class->finalize = tp_tests_simple_channel_dispatch_operation_finalize;
+
+ param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
+ "In this case we only implement ChannelDispatchOperation, so none.",
+ 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_boxed ("connection", "connection path",
+ "Connection path",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
+
+ param_spec = g_param_spec_boxed ("account", "account path",
+ "Account path",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_ACCOUNT, param_spec);
+
+ param_spec = g_param_spec_boxed ("channels", "channel paths",
+ "Channel paths",
+ TP_ARRAY_TYPE_CHANNEL_DETAILS_LIST,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CHANNELS, param_spec);
+
+ param_spec = g_param_spec_boxed ("possible-handlers", "possible handlers",
+ "possible handles",
+ G_TYPE_STRV,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_POSSIBLE_HANDLERS,
+ param_spec);
+
+ klass->dbus_props_class.interfaces = prop_interfaces;
+ tp_dbus_properties_mixin_class_init (object_class,
+ G_STRUCT_OFFSET (TpTestsSimpleChannelDispatchOperationClass, dbus_props_class));
+}
+
+void
+tp_tests_simple_channel_dispatch_operation_set_conn_path (
+ TpTestsSimpleChannelDispatchOperation *self,
+ const gchar *conn_path)
+{
+ self->priv->conn_path = g_strdup (conn_path);
+}
+
+void
+tp_tests_simple_channel_dispatch_operation_add_channel (
+ TpTestsSimpleChannelDispatchOperation *self,
+ TpChannel *chan)
+{
+ g_ptr_array_add (self->priv->channels, g_object_ref (chan));
+}
+
+void
+tp_tests_simple_channel_dispatch_operation_lost_channel (
+ TpTestsSimpleChannelDispatchOperation *self,
+ TpChannel *chan)
+{
+ const gchar *path = tp_proxy_get_object_path (chan);
+
+ g_ptr_array_remove (self->priv->channels, chan);
+
+ tp_svc_channel_dispatch_operation_emit_channel_lost (self, path,
+ TP_ERROR_STR_NOT_AVAILABLE, "Badger");
+
+ if (self->priv->channels->len == 0)
+ {
+ /* We removed the last channel; fire Finished */
+ tp_svc_channel_dispatch_operation_emit_finished (self);
+ }
+}
+
+void
+tp_tests_simple_channel_dispatch_operation_set_account_path (
+ TpTestsSimpleChannelDispatchOperation *self,
+ const gchar *account_path)
+{
+ self->priv->account_path = g_strdup (account_path);
+}
diff --git a/tests/lib/telepathy/contactlist/simple-channel-dispatch-operation.h b/tests/lib/telepathy/contactlist/simple-channel-dispatch-operation.h
new file mode 100644
index 00000000..3e9ee934
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/simple-channel-dispatch-operation.h
@@ -0,0 +1,73 @@
+/*
+ * simple-channel-dispatch-operation.h - a simple channel dispatch operation
+ * service.
+ *
+ * Copyright Ā© 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_SIMPLE_CHANNEL_DISPATCH_OPERATION_H__
+#define __TP_TESTS_SIMPLE_CHANNEL_DISPATCH_OPERATION_H__
+
+#include <glib-object.h>
+
+#include <telepathy-glib/telepathy-glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SimpleChannelDispatchOperation TpTestsSimpleChannelDispatchOperation;
+typedef struct _SimpleChannelDispatchOperationClass TpTestsSimpleChannelDispatchOperationClass;
+typedef struct _SimpleChannelDispatchOperationPrivate TpTestsSimpleChannelDispatchOperationPrivate;
+
+struct _SimpleChannelDispatchOperationClass {
+ GObjectClass parent_class;
+ TpDBusPropertiesMixinClass dbus_props_class;
+};
+
+struct _SimpleChannelDispatchOperation {
+ GObject parent;
+
+ TpTestsSimpleChannelDispatchOperationPrivate *priv;
+};
+
+GType tp_tests_simple_channel_dispatch_operation_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCH_OPERATION \
+ (tp_tests_simple_channel_dispatch_operation_get_type ())
+#define TP_TESTS_SIMPLE_CHANNEL_DISPATCH_OPERATION(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCH_OPERATION, \
+ TpTestsSimpleChannelDispatchOperation))
+#define TP_TESTS_SIMPLE_CHANNEL_DISPATCH_OPERATION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCH_OPERATION, \
+ TpTestsSimpleChannelDispatchOperationClass))
+#define SIMPLE_IS_CHANNEL_DISPATCH_OPERATION(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCH_OPERATION))
+#define SIMPLE_IS_CHANNEL_DISPATCH_OPERATION_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCH_OPERATION))
+#define TP_TESTS_SIMPLE_CHANNEL_DISPATCH_OPERATION_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCH_OPERATION, \
+ TpTestsSimpleChannelDispatchOperationClass))
+
+void tp_tests_simple_channel_dispatch_operation_set_conn_path (
+ TpTestsSimpleChannelDispatchOperation *self,
+ const gchar *conn_path);
+
+void tp_tests_simple_channel_dispatch_operation_add_channel (
+ TpTestsSimpleChannelDispatchOperation *self,
+ TpChannel *chan);
+
+void tp_tests_simple_channel_dispatch_operation_lost_channel (
+ TpTestsSimpleChannelDispatchOperation *self,
+ TpChannel *chan);
+
+void tp_tests_simple_channel_dispatch_operation_set_account_path (
+ TpTestsSimpleChannelDispatchOperation *self,
+ const gchar *account_path);
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_SIMPLE_CHANNEL_DISPATCH_OPERATION_H__ */
diff --git a/tests/lib/telepathy/contactlist/simple-channel-dispatcher.c b/tests/lib/telepathy/contactlist/simple-channel-dispatcher.c
new file mode 100644
index 00000000..775f915e
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/simple-channel-dispatcher.c
@@ -0,0 +1,394 @@
+/*
+ * simple-channel-dispatcher.c - simple channel dispatcher service.
+ *
+ * Copyright Ā© 2010 Collabora Ltd.
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "simple-channel-dispatcher.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#include "simple-channel-request.h"
+#include "simple-conn.h"
+
+static void channel_dispatcher_iface_init (gpointer, gpointer);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleChannelDispatcher,
+ tp_tests_simple_channel_dispatcher,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_DISPATCHER,
+ channel_dispatcher_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+ tp_dbus_properties_mixin_iface_init)
+ )
+
+/* signals */
+enum {
+ CHANNEL_REQUEST_CREATED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+/* TP_IFACE_CHANNEL_DISPATCHER is implied */
+static const char *CHANNEL_DISPATCHER_INTERFACES[] = { NULL };
+
+enum
+{
+ PROP_0,
+ PROP_INTERFACES,
+ PROP_CONNECTION,
+};
+
+struct _TpTestsSimpleChannelDispatcherPrivate
+{
+ /* To keep things simpler, this CD can only create channels using one
+ * connection */
+ TpTestsSimpleConnection *conn;
+
+ /* List of reffed TpTestsSimpleChannelRequest */
+ GSList *requests;
+
+ /* Used when ensuring a channel to store its handler.
+ * If this is set we fake that the channel already exist and re-call
+ * HandleChannels() on the handler rather than creating a new channel.
+ * This is pretty stupid but good enough for our tests. */
+ gchar *old_handler;
+};
+
+static gchar *
+create_channel_request (TpTestsSimpleChannelDispatcher *self,
+ const gchar *account,
+ GHashTable *request,
+ gint64 user_action_time,
+ const gchar *preferred_handler,
+ GHashTable *hints_,
+ GHashTable **out_immutable_properties)
+{
+ TpTestsSimpleChannelRequest *chan_request;
+ GPtrArray *requests;
+ static guint count = 0;
+ gchar *path;
+ TpDBusDaemon *dbus;
+ GHashTable *hints;
+
+ requests = g_ptr_array_sized_new (1);
+ g_ptr_array_add (requests, request);
+
+ path = g_strdup_printf ("/Request%u", count++);
+
+ if (hints_ == NULL)
+ hints = g_hash_table_new (NULL, NULL);
+ else
+ hints = g_hash_table_ref (hints_);
+
+ chan_request = tp_tests_simple_channel_request_new (path,
+ self->priv->conn, account, user_action_time, preferred_handler, requests,
+ hints);
+
+ g_hash_table_unref (hints);
+
+ self->priv->requests = g_slist_append (self->priv->requests, chan_request);
+
+ g_ptr_array_unref (requests);
+
+ dbus = tp_dbus_daemon_dup (NULL);
+ g_assert (dbus != NULL);
+
+ tp_dbus_daemon_register_object (dbus, path, chan_request);
+
+ g_object_unref (dbus);
+
+ g_signal_emit (self, signals[CHANNEL_REQUEST_CREATED], 0, chan_request);
+
+ *out_immutable_properties =
+ tp_tests_simple_channel_request_dup_immutable_props (chan_request);
+
+ return path;
+}
+
+static void
+tp_tests_simple_channel_dispatcher_create_channel (
+ TpSvcChannelDispatcher *dispatcher,
+ const gchar *account,
+ GHashTable *request,
+ gint64 user_action_time,
+ const gchar *preferred_handler,
+ GHashTable *hints,
+ DBusGMethodInvocation *context)
+{
+ TpTestsSimpleChannelDispatcher *self = SIMPLE_CHANNEL_DISPATCHER (dispatcher);
+ gchar *path;
+ GHashTable *immutable_properties;
+
+ tp_clear_pointer (&self->last_request, g_hash_table_unref);
+ self->last_request = g_boxed_copy (TP_HASH_TYPE_STRING_VARIANT_MAP, request);
+ tp_clear_pointer (&self->last_hints, g_hash_table_unref);
+ self->last_hints = g_boxed_copy (TP_HASH_TYPE_STRING_VARIANT_MAP, request);
+ self->last_user_action_time = user_action_time;
+ g_free (self->last_account);
+ self->last_account = g_strdup (account);
+ g_free (self->last_preferred_handler);
+ self->last_preferred_handler = g_strdup (preferred_handler);
+
+ if (tp_asv_get_boolean (request, "CreateChannelFail", NULL))
+ {
+ /* Fail to create the channel */
+ GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "Computer says no" };
+
+ dbus_g_method_return_error (context, &error);
+ return;
+ }
+
+ path = create_channel_request (self, account, request, user_action_time,
+ preferred_handler, hints, &immutable_properties);
+
+ if (path == NULL)
+ return;
+
+ tp_svc_channel_dispatcher_return_from_create_channel (context,
+ path, immutable_properties);
+
+ g_free (path);
+ g_hash_table_unref (immutable_properties);
+}
+
+static void
+tp_tests_simple_channel_dispatcher_ensure_channel (
+ TpSvcChannelDispatcher *dispatcher,
+ const gchar *account,
+ GHashTable *request,
+ gint64 user_action_time,
+ const gchar *preferred_handler,
+ GHashTable *hints,
+ DBusGMethodInvocation *context)
+{
+ TpTestsSimpleChannelDispatcher *self = SIMPLE_CHANNEL_DISPATCHER (dispatcher);
+ gchar *path;
+ GHashTable *immutable_properties;
+
+ tp_clear_pointer (&self->last_request, g_hash_table_unref);
+ self->last_request = g_boxed_copy (TP_HASH_TYPE_STRING_VARIANT_MAP, request);
+ tp_clear_pointer (&self->last_hints, g_hash_table_unref);
+ self->last_hints = g_boxed_copy (TP_HASH_TYPE_STRING_VARIANT_MAP, request);
+ self->last_user_action_time = user_action_time;
+ g_free (self->last_account);
+ self->last_account = g_strdup (account);
+ g_free (self->last_preferred_handler);
+ self->last_preferred_handler = g_strdup (preferred_handler);
+
+ if (self->priv->old_handler != NULL)
+ {
+ /* Pretend that the channel already exists */
+ path = create_channel_request (self, account, request, user_action_time,
+ self->priv->old_handler, hints, &immutable_properties);
+ }
+ else
+ {
+ self->priv->old_handler = g_strdup (preferred_handler);
+
+ path = create_channel_request (self, account, request, user_action_time,
+ preferred_handler, hints, &immutable_properties);
+ }
+
+ tp_svc_channel_dispatcher_return_from_ensure_channel (context,
+ path, immutable_properties);
+
+ g_free (path);
+ g_hash_table_unref (immutable_properties);
+}
+
+static void
+free_not_delegated_error (gpointer data)
+{
+ g_boxed_free (TP_STRUCT_TYPE_NOT_DELEGATED_ERROR, data);
+}
+
+
+static void
+tp_tests_simple_channel_dispatcher_delegate_channels (
+ TpSvcChannelDispatcher *dispatcher,
+ const GPtrArray *channels,
+ gint64 user_action_time,
+ const gchar *preferred_handler,
+ DBusGMethodInvocation *context)
+{
+ TpTestsSimpleChannelDispatcher *self = (TpTestsSimpleChannelDispatcher *)
+ dispatcher;
+ GPtrArray *delegated;
+ GHashTable *not_delegated;
+ guint i;
+
+ delegated = g_ptr_array_new ();
+ not_delegated = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL, free_not_delegated_error);
+
+ for (i = 0; i < channels->len; i++)
+ {
+ gpointer chan_path = g_ptr_array_index (channels, i);
+ GValueArray *v;
+
+ if (!self->refuse_delegate)
+ {
+ g_ptr_array_add (delegated, chan_path);
+ continue;
+ }
+
+ v = tp_value_array_build (2,
+ G_TYPE_STRING, TP_ERROR_STR_BUSY,
+ G_TYPE_STRING, "Nah!",
+ G_TYPE_INVALID);
+
+ g_hash_table_insert (not_delegated, chan_path, v);
+ }
+
+ tp_svc_channel_dispatcher_return_from_delegate_channels (context, delegated,
+ not_delegated);
+
+ g_ptr_array_unref (delegated);
+ g_hash_table_unref (not_delegated);
+}
+
+static void
+tp_tests_simple_channel_dispatcher_present_channel (
+ TpSvcChannelDispatcher *dispatcher,
+ const gchar *channel,
+ gint64 user_action_time,
+ DBusGMethodInvocation *context)
+{
+ tp_svc_channel_dispatcher_return_from_present_channel (context);
+}
+
+static void
+channel_dispatcher_iface_init (gpointer klass,
+ gpointer unused G_GNUC_UNUSED)
+{
+#define IMPLEMENT(x) tp_svc_channel_dispatcher_implement_##x (\
+ klass, tp_tests_simple_channel_dispatcher_##x)
+ IMPLEMENT (create_channel);
+ IMPLEMENT (ensure_channel);
+ IMPLEMENT (delegate_channels);
+ IMPLEMENT (present_channel);
+#undef IMPLEMENT
+}
+
+
+static void
+tp_tests_simple_channel_dispatcher_init (TpTestsSimpleChannelDispatcher *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER,
+ TpTestsSimpleChannelDispatcherPrivate);
+}
+
+static void
+tp_tests_simple_channel_dispatcher_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *spec)
+{
+ switch (property_id) {
+ case PROP_INTERFACES:
+ g_value_set_boxed (value, CHANNEL_DISPATCHER_INTERFACES);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+ break;
+ }
+}
+
+static void
+tp_tests_simple_channel_dispatcher_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *spec)
+{
+ TpTestsSimpleChannelDispatcher *self = SIMPLE_CHANNEL_DISPATCHER (object);
+
+ switch (property_id) {
+ case PROP_CONNECTION:
+ self->priv->conn = g_value_dup_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+ break;
+ }
+}
+
+static void
+tp_tests_simple_channel_dispatcher_dispose (GObject *object)
+{
+ TpTestsSimpleChannelDispatcher *self = SIMPLE_CHANNEL_DISPATCHER (object);
+
+ tp_clear_object (&self->priv->conn);
+
+ g_slist_foreach (self->priv->requests, (GFunc) g_object_unref, NULL);
+ g_slist_free (self->priv->requests);
+
+ g_free (self->priv->old_handler);
+
+ if (G_OBJECT_CLASS (tp_tests_simple_channel_dispatcher_parent_class)->dispose != NULL)
+ G_OBJECT_CLASS (tp_tests_simple_channel_dispatcher_parent_class)->dispose (object);
+}
+
+static void
+tp_tests_simple_channel_dispatcher_class_init (
+ TpTestsSimpleChannelDispatcherClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ GParamSpec *param_spec;
+
+ static TpDBusPropertiesMixinPropImpl am_props[] = {
+ { "Interfaces", "interfaces", NULL },
+ { NULL }
+ };
+
+ static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+ { TP_IFACE_CHANNEL_DISPATCHER,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ am_props
+ },
+ { NULL },
+ };
+
+ g_type_class_add_private (klass, sizeof (TpTestsSimpleChannelDispatcherPrivate));
+ object_class->get_property = tp_tests_simple_channel_dispatcher_get_property;
+ object_class->set_property = tp_tests_simple_channel_dispatcher_set_property;
+
+ object_class->dispose = tp_tests_simple_channel_dispatcher_dispose;
+
+ param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
+ "In this case we only implement ChannelDispatcher, so none.",
+ 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_object ("connection", "TpTestsSimpleConnection",
+ "connection to use when creating channels",
+ TP_TESTS_TYPE_SIMPLE_CONNECTION,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
+
+ /* Fired when we create a new channel request object. This can be used in
+ * test to track the progression of a request. */
+ signals[CHANNEL_REQUEST_CREATED] = g_signal_new ("channel-request-created",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 1, TP_TESTS_TYPE_SIMPLE_CHANNEL_REQUEST);
+
+ klass->dbus_props_class.interfaces = prop_interfaces;
+ tp_dbus_properties_mixin_class_init (object_class,
+ G_STRUCT_OFFSET (TpTestsSimpleChannelDispatcherClass, dbus_props_class));
+}
diff --git a/tests/lib/telepathy/contactlist/simple-channel-dispatcher.h b/tests/lib/telepathy/contactlist/simple-channel-dispatcher.h
new file mode 100644
index 00000000..da214061
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/simple-channel-dispatcher.h
@@ -0,0 +1,66 @@
+/*
+ * simple-channel-dispatcher.h - header for a simple channel dispatcher service.
+ *
+ * Copyright Ā© 2010 Collabora Ltd.
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_SIMPLE_CHANNEL_DISPATCHER_H__
+#define __TP_TESTS_SIMPLE_CHANNEL_DISPATCHER_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsSimpleChannelDispatcher TpTestsSimpleChannelDispatcher;
+typedef struct _TpTestsSimpleChannelDispatcherClass TpTestsSimpleChannelDispatcherClass;
+typedef struct _TpTestsSimpleChannelDispatcherPrivate TpTestsSimpleChannelDispatcherPrivate;
+
+struct _TpTestsSimpleChannelDispatcherClass {
+ GObjectClass parent_class;
+ TpDBusPropertiesMixinClass dbus_props_class;
+};
+
+struct _TpTestsSimpleChannelDispatcher {
+ GObject parent;
+
+ /* so regression tests can verify what was asked for */
+ GHashTable *last_request;
+ gchar *last_account;
+ gint64 last_user_action_time;
+ gchar *last_preferred_handler;
+ GHashTable *last_hints;
+
+ TpTestsSimpleChannelDispatcherPrivate *priv;
+
+ gboolean refuse_delegate;
+};
+
+GType tp_tests_simple_channel_dispatcher_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER \
+ (tp_tests_simple_channel_dispatcher_get_type ())
+#define SIMPLE_CHANNEL_DISPATCHER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER, \
+ TpTestsSimpleChannelDispatcher))
+#define SIMPLE_CHANNEL_DISPATCHER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER, \
+ TpTestsSimpleChannelDispatcherClass))
+#define SIMPLE_IS_CHANNEL_DISPATCHER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER))
+#define SIMPLE_IS_CHANNEL_DISPATCHER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER))
+#define SIMPLE_CHANNEL_DISPATCHER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER, \
+ TpTestsSimpleChannelDispatcherClass))
+
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_SIMPLE_CHANNEL_DISPATCHER_H__ */
diff --git a/tests/lib/telepathy/contactlist/simple-channel-manager.c b/tests/lib/telepathy/contactlist/simple-channel-manager.c
new file mode 100644
index 00000000..ba60a9d9
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/simple-channel-manager.c
@@ -0,0 +1,95 @@
+/*
+ * simple-channel-manager.c
+ *
+ * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#include "simple-channel-manager.h"
+#include "util.h"
+#include "echo-chan.h"
+
+static void channel_manager_iface_init (gpointer, gpointer);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleChannelManager,
+ tp_tests_simple_channel_manager, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER, channel_manager_iface_init);
+ )
+
+/* signals */
+enum {
+ REQUEST,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+tp_tests_simple_channel_manager_class_init (TpTestsSimpleChannelManagerClass *klass)
+{
+ signals[REQUEST] = g_signal_new ("request",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE, 1, G_TYPE_HASH_TABLE);
+}
+
+static void
+tp_tests_simple_channel_manager_init (TpTestsSimpleChannelManager *self)
+{
+}
+
+static gboolean
+tp_tests_simple_channel_manager_request (TpChannelManager *manager,
+ gpointer request_token,
+ GHashTable *request_properties)
+{
+ TpTestsSimpleChannelManager *self =
+ TP_TESTS_SIMPLE_CHANNEL_MANAGER (manager);
+ GSList *tokens;
+ TpExportableChannel *channel;
+ TpHandle handle = tp_asv_get_uint32 (request_properties,
+ TP_PROP_CHANNEL_TARGET_HANDLE, NULL);
+ gchar *path;
+
+ g_signal_emit (manager, signals[REQUEST], 0, request_properties);
+
+ tokens = g_slist_append (NULL, request_token);
+
+ path = g_strdup_printf ("%s/Channel",
+ tp_base_connection_get_object_path (self->conn));
+
+ channel = tp_tests_object_new_static_class (
+ TP_TESTS_TYPE_ECHO_CHANNEL,
+ "connection", self->conn,
+ "object-path", path,
+ "handle", handle,
+ NULL);
+
+ tp_channel_manager_emit_new_channel (manager, channel, tokens);
+
+ g_free (path);
+ g_slist_free (tokens);
+ g_object_unref (channel);
+
+ return TRUE;
+}
+
+static void
+channel_manager_iface_init (gpointer g_iface,
+ gpointer giface_data G_GNUC_UNUSED)
+{
+ TpChannelManagerIface *iface = g_iface;
+
+ iface->create_channel = tp_tests_simple_channel_manager_request;
+ iface->ensure_channel = tp_tests_simple_channel_manager_request;
+ iface->request_channel = tp_tests_simple_channel_manager_request;
+}
diff --git a/tests/lib/telepathy/contactlist/simple-channel-manager.h b/tests/lib/telepathy/contactlist/simple-channel-manager.h
new file mode 100644
index 00000000..ad711cd5
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/simple-channel-manager.h
@@ -0,0 +1,54 @@
+/*
+ * simple-channel-manager.h
+ *
+ * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_SIMPLE_CHANNEL_MANAGER_H__
+#define __TP_TESTS_SIMPLE_CHANNEL_MANAGER_H__
+
+#include <glib-object.h>
+
+#include <telepathy-glib/telepathy-glib.h>
+
+typedef struct _TpTestsSimpleChannelManager TpTestsSimpleChannelManager;
+typedef struct _TpTestsSimpleChannelManagerClass TpTestsSimpleChannelManagerClass;
+
+struct _TpTestsSimpleChannelManager
+{
+ GObject parent;
+
+ TpBaseConnection *conn;
+};
+
+struct _TpTestsSimpleChannelManagerClass
+{
+ GObjectClass parent_class;
+};
+
+GType tp_tests_simple_channel_manager_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_SIMPLE_CHANNEL_MANAGER \
+ (tp_tests_simple_channel_manager_get_type ())
+#define TP_TESTS_SIMPLE_CHANNEL_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_MANAGER, \
+ TpTestsSimpleChannelManager))
+#define TP_TESTS_SIMPLE_CHANNEL_MANAGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_SIMPLE_CHANNEL_MANAGER, \
+ TpTestsSimpleChannelManagerClass))
+#define TP_TESTS_IS_SIMPLE_CHANNEL_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_MANAGER))
+#define TP_TESTS_IS_SIMPLE_CHANNEL_MANAGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_SIMPLE_CHANNEL_MANAGER))
+#define TP_TESTS_SIMPLE_CHANNEL_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_MANAGER, \
+ TpTestsSimpleChannelManagerClass))
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_SIMPLE_CHANNEL_MANAGER_H__ */
diff --git a/tests/lib/telepathy/contactlist/simple-channel-request.c b/tests/lib/telepathy/contactlist/simple-channel-request.c
new file mode 100644
index 00000000..4884cb02
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/simple-channel-request.c
@@ -0,0 +1,508 @@
+/*
+ * simple-channel-request.c - simple channel request service.
+ *
+ * Copyright Ā© 2010 Collabora Ltd.
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "simple-channel-request.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+#include <telepathy-glib/proxy-subclass.h>
+
+#include "tests/lib/util.h"
+
+static void channel_request_iface_init (gpointer, gpointer);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleChannelRequest,
+ tp_tests_simple_channel_request,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_REQUEST,
+ channel_request_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+ tp_dbus_properties_mixin_iface_init)
+ )
+
+
+/* TP_IFACE_CHANNEL_REQUEST is implied */
+static const char *CHANNEL_REQUEST_INTERFACES[] = { NULL };
+
+enum
+{
+ PROP_0,
+ PROP_PATH,
+ PROP_ACCOUNT,
+ PROP_USER_ACTION_TIME,
+ PROP_PREFERRED_HANDLER,
+ PROP_REQUESTS,
+ PROP_CONNECTION,
+ PROP_INTERFACES,
+ PROP_HINTS,
+};
+
+struct _TpTestsSimpleChannelRequestPrivate
+{
+ /* D-Bus properties */
+ gchar *account_path;
+ gint64 user_action_time;
+ gchar *preferred_handler;
+ GPtrArray *requests;
+ GHashTable *hints;
+
+ /* Our own path */
+ gchar *path;
+
+ /* connection used to create channels */
+ TpTestsSimpleConnection *conn;
+};
+
+static void
+handle_channels_cb (TpClient *client,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ TpTestsSimpleChannelRequest *self = SIMPLE_CHANNEL_REQUEST (weak_object);
+ TpBaseConnection *base_conn = TP_BASE_CONNECTION (self->priv->conn);
+ const gchar *chan_path = user_data;
+ GHashTable *props = tp_asv_new (NULL, NULL);
+
+ if (error != NULL)
+ {
+ tp_svc_channel_request_emit_failed (self,
+ tp_error_get_dbus_name (error->code), error->message);
+ return;
+ }
+
+ tp_svc_channel_request_emit_succeeded (self,
+ tp_base_connection_get_object_path (base_conn), props, chan_path, props);
+
+ g_hash_table_unref (props);
+}
+
+static gchar *
+add_channel (TpTestsSimpleChannelRequest *self,
+ GPtrArray *channels)
+{
+ const gchar *target_id;
+ gchar *chan_path;
+ GHashTable *request;
+ GHashTable *props;
+ const char *chan_type;
+
+ request = g_ptr_array_index (self->priv->requests, 0);
+ chan_type = tp_asv_get_string (request, TP_PROP_CHANNEL_CHANNEL_TYPE);
+
+ if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_TEXT))
+ {
+ target_id = tp_asv_get_string (request, TP_PROP_CHANNEL_TARGET_ID);
+ g_assert (target_id != NULL);
+
+ chan_path = tp_tests_simple_connection_ensure_text_chan (self->priv->conn,
+ target_id, &props);
+ }
+ else if (!tp_strdiff (chan_type, TP_IFACE_CHANNEL_TYPE_ROOM_LIST))
+ {
+ chan_path = tp_tests_simple_connection_ensure_room_list_chan (
+ self->priv->conn, tp_asv_get_string (request,
+ TP_PROP_CHANNEL_TYPE_ROOM_LIST_SERVER), &props);
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+
+ g_ptr_array_add (channels, tp_value_array_build (2,
+ DBUS_TYPE_G_OBJECT_PATH, chan_path,
+ TP_HASH_TYPE_STRING_VARIANT_MAP, props,
+ G_TYPE_INVALID));
+
+ g_hash_table_unref (props);
+
+ return chan_path;
+}
+
+static void
+free_channel_details (gpointer data,
+ gpointer user_data)
+{
+ g_boxed_free (TP_STRUCT_TYPE_CHANNEL_DETAILS, data);
+}
+
+GHashTable *
+tp_tests_simple_channel_request_dup_immutable_props (
+ TpTestsSimpleChannelRequest *self)
+{
+ return tp_asv_new (
+ TP_PROP_CHANNEL_REQUEST_ACCOUNT, DBUS_TYPE_G_OBJECT_PATH,
+ self->priv->account_path,
+ TP_PROP_CHANNEL_REQUEST_USER_ACTION_TIME, G_TYPE_INT64,
+ self->priv->user_action_time,
+ TP_PROP_CHANNEL_REQUEST_PREFERRED_HANDLER, G_TYPE_STRING,
+ self->priv->preferred_handler,
+ TP_PROP_CHANNEL_REQUEST_REQUESTS, TP_ARRAY_TYPE_CHANNEL_CLASS_LIST,
+ self->priv->requests,
+ TP_PROP_CHANNEL_REQUEST_INTERFACES, G_TYPE_STRV, NULL,
+ TP_PROP_CHANNEL_REQUEST_HINTS, TP_HASH_TYPE_STRING_VARIANT_MAP,
+ self->priv->hints,
+ NULL);
+}
+
+static void
+tp_tests_simple_channel_request_proceed (TpSvcChannelRequest *request,
+ DBusGMethodInvocation *context)
+{
+ TpTestsSimpleChannelRequest *self = SIMPLE_CHANNEL_REQUEST (request);
+ TpClient *client;
+ TpDBusDaemon *dbus;
+ gchar *client_path;
+ GPtrArray *channels;
+ GPtrArray *satisfied;
+ GHashTable *info;
+ TpBaseConnection *base_conn = (TpBaseConnection *) self->priv->conn;
+ GHashTable *req;
+ GHashTable *request_props;
+ gchar *chan_path;
+
+ req = g_ptr_array_index (self->priv->requests, 0);
+ g_assert (req != NULL);
+ if (tp_asv_get_boolean (req, "ProceedFail", NULL))
+ {
+ /* We have been asked to fail */
+ GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "Computer says no" };
+
+ dbus_g_method_return_error (context, &error);
+ return;
+ }
+
+ tp_svc_channel_request_return_from_proceed (context);
+
+ if (tp_asv_get_boolean (req, "FireFailed", NULL))
+ {
+ /* We have been asked to fire the 'Failed' signal */
+ tp_svc_channel_request_emit_failed (self, TP_ERROR_STR_INVALID_ARGUMENT,
+ "Let's fail!");
+ return;
+ }
+
+ /* We just support handling request having a preferred handler */
+ if (self->priv->preferred_handler == NULL ||
+ !tp_strdiff (self->priv->preferred_handler, ""))
+ {
+ tp_svc_channel_request_emit_failed (self, TP_ERROR_STR_NOT_AVAILABLE,
+ "ChannelRequest doesn't have a preferred handler");
+ return;
+ }
+
+ if (!tp_strdiff (self->priv->preferred_handler, "Fake"))
+ {
+ /* Pretend that the channel has been handled */
+ GHashTable *props;
+ props = g_hash_table_new (NULL, NULL);
+
+ tp_svc_channel_request_emit_succeeded (self,
+ tp_base_connection_get_object_path (base_conn),
+ props, "/chan", props);
+
+ g_hash_table_unref (props);
+ return;
+ }
+
+ /* Call HandleChannels() on the preferred handler */
+ client_path = g_strdelimit (g_strdup_printf ("/%s",
+ self->priv->preferred_handler), ".", '/');
+
+ dbus = tp_dbus_daemon_dup (NULL);
+ g_assert (dbus != NULL);
+
+ client = tp_tests_object_new_static_class (TP_TYPE_CLIENT,
+ "dbus-daemon", dbus,
+ "bus-name", self->priv->preferred_handler,
+ "object-path", client_path,
+ NULL);
+
+ tp_proxy_add_interface_by_id (TP_PROXY (client), TP_IFACE_QUARK_CLIENT);
+ tp_proxy_add_interface_by_id (TP_PROXY (client),
+ TP_IFACE_QUARK_CLIENT_HANDLER);
+
+ channels = g_ptr_array_sized_new (1);
+ chan_path = add_channel (self, channels);
+
+ satisfied = g_ptr_array_sized_new (1);
+ g_ptr_array_add (satisfied, self->priv->path);
+
+ request_props = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) g_hash_table_unref);
+
+ g_hash_table_insert (request_props, g_strdup (self->priv->path),
+ tp_tests_simple_channel_request_dup_immutable_props (self));
+
+ info = tp_asv_new (
+ "request-properties", TP_HASH_TYPE_OBJECT_IMMUTABLE_PROPERTIES_MAP,
+ request_props,
+ NULL);
+
+ tp_cli_client_handler_call_handle_channels (client, -1,
+ self->priv->account_path,
+ tp_base_connection_get_object_path (base_conn), channels,
+ satisfied, self->priv->user_action_time, info, handle_channels_cb,
+ g_strdup (chan_path), g_free, G_OBJECT (self));
+
+ g_free (chan_path);
+ g_free (client_path);
+ g_ptr_array_foreach (channels, free_channel_details, NULL);
+ g_ptr_array_unref (channels);
+ g_ptr_array_unref (satisfied);
+ g_hash_table_unref (info);
+ g_hash_table_unref (request_props);
+ g_object_unref (dbus);
+ g_object_unref (client);
+}
+
+static void
+tp_tests_simple_channel_request_cancel (TpSvcChannelRequest *request,
+ DBusGMethodInvocation *context)
+{
+ tp_svc_channel_request_emit_failed (request, TP_ERROR_STR_CANCELLED,
+ "ChannelRequest has been cancelled");
+
+ tp_svc_channel_request_return_from_cancel (context);
+}
+
+static void
+channel_request_iface_init (gpointer klass,
+ gpointer unused G_GNUC_UNUSED)
+{
+#define IMPLEMENT(x) tp_svc_channel_request_implement_##x (\
+ klass, tp_tests_simple_channel_request_##x)
+ IMPLEMENT (proceed);
+ IMPLEMENT (cancel);
+#undef IMPLEMENT
+}
+
+static void
+tp_tests_simple_channel_request_init (TpTestsSimpleChannelRequest *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ TP_TESTS_TYPE_SIMPLE_CHANNEL_REQUEST,
+ TpTestsSimpleChannelRequestPrivate);
+}
+
+static void
+tp_tests_simple_channel_request_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *spec)
+{
+ TpTestsSimpleChannelRequest *self = SIMPLE_CHANNEL_REQUEST (object);
+
+ switch (property_id) {
+ case PROP_PATH:
+ g_value_set_string (value, self->priv->path);
+ break;
+
+ case PROP_ACCOUNT:
+ g_value_set_string (value, self->priv->account_path);
+ break;
+
+ case PROP_USER_ACTION_TIME:
+ g_value_set_int64 (value, self->priv->user_action_time);
+ break;
+
+ case PROP_PREFERRED_HANDLER:
+ g_value_set_string (value, self->priv->preferred_handler);
+ break;
+
+ case PROP_REQUESTS:
+ g_value_set_boxed (value, self->priv->requests);
+ break;
+
+ case PROP_INTERFACES:
+ g_value_set_boxed (value, CHANNEL_REQUEST_INTERFACES);
+ break;
+
+ case PROP_HINTS:
+ g_value_set_boxed (value, self->priv->hints);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+ break;
+ }
+}
+
+static void
+tp_tests_simple_channel_request_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *spec)
+{
+ TpTestsSimpleChannelRequest *self = SIMPLE_CHANNEL_REQUEST (object);
+
+ switch (property_id) {
+ case PROP_PATH:
+ self->priv->path = g_value_dup_string (value);
+ break;
+
+ case PROP_ACCOUNT:
+ self->priv->account_path = g_value_dup_string (value);
+ break;
+
+ case PROP_USER_ACTION_TIME:
+ self->priv->user_action_time = g_value_get_int64 (value);
+ break;
+
+ case PROP_PREFERRED_HANDLER:
+ self->priv->preferred_handler = g_value_dup_string (value);
+ break;
+
+ case PROP_REQUESTS:
+ self->priv->requests = g_value_dup_boxed (value);
+ break;
+
+ case PROP_CONNECTION:
+ self->priv->conn = g_value_dup_object (value);
+ break;
+
+ case PROP_HINTS:
+ self->priv->hints = g_value_dup_boxed (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+ break;
+ }
+}
+
+static void
+tp_tests_simple_channel_request_dispose (GObject *object)
+{
+ TpTestsSimpleChannelRequest *self = SIMPLE_CHANNEL_REQUEST (object);
+
+ g_free (self->priv->path);
+ g_free (self->priv->account_path);
+ g_free (self->priv->preferred_handler);
+
+ if (self->priv->requests != NULL)
+ {
+ g_boxed_free (TP_ARRAY_TYPE_CHANNEL_CLASS_LIST, self->priv->requests);
+ self->priv->requests = NULL;
+ }
+
+ tp_clear_object (&self->priv->conn);
+ tp_clear_pointer (&self->priv->hints, g_hash_table_unref);
+
+ if (G_OBJECT_CLASS (tp_tests_simple_channel_request_parent_class)->dispose != NULL)
+ G_OBJECT_CLASS (tp_tests_simple_channel_request_parent_class)->dispose (object);
+}
+
+static void
+tp_tests_simple_channel_request_class_init (
+ TpTestsSimpleChannelRequestClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ GParamSpec *param_spec;
+
+ static TpDBusPropertiesMixinPropImpl am_props[] = {
+ { "Interfaces", "interfaces", NULL },
+ { "Hints", "hints", NULL },
+ { NULL }
+ };
+
+ static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+ { TP_IFACE_CHANNEL_REQUEST,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ am_props
+ },
+ { NULL },
+ };
+
+ g_type_class_add_private (klass, sizeof (TpTestsSimpleChannelRequestPrivate));
+ object_class->get_property = tp_tests_simple_channel_request_get_property;
+ object_class->set_property = tp_tests_simple_channel_request_set_property;
+
+ object_class->dispose = tp_tests_simple_channel_request_dispose;
+
+ param_spec = g_param_spec_string ("path", "Path",
+ "Path of this ChannelRequest",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_PATH, param_spec);
+
+ param_spec = g_param_spec_string ("account", "Account",
+ "Path of the Account",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_ACCOUNT, param_spec);
+
+ param_spec = g_param_spec_int64 ("user-action-time", "UserActionTime",
+ "UserActionTime",
+ G_MININT64, G_MAXINT64, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_USER_ACTION_TIME,
+ param_spec);
+
+ param_spec = g_param_spec_string ("preferred-handler", "PreferredHandler",
+ "PreferredHandler",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_PREFERRED_HANDLER,
+ param_spec);
+
+ param_spec = g_param_spec_boxed ("requests", "Requests",
+ "Requests",
+ TP_ARRAY_TYPE_CHANNEL_CLASS_LIST,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_REQUESTS, param_spec);
+
+ param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
+ "In this case we only implement ChannelRequest, so none.",
+ 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_object ("connection", "TpBaseConnection",
+ "connection to use when creating channels",
+ TP_TYPE_BASE_CONNECTION,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
+
+ param_spec = g_param_spec_boxed ("hints", "Hints",
+ "Metadata provided by the channel's requester, if any",
+ TP_HASH_TYPE_STRING_VARIANT_MAP,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_HINTS, param_spec);
+
+ klass->dbus_props_class.interfaces = prop_interfaces;
+ tp_dbus_properties_mixin_class_init (object_class,
+ G_STRUCT_OFFSET (TpTestsSimpleChannelRequestClass, dbus_props_class));
+}
+
+TpTestsSimpleChannelRequest *
+tp_tests_simple_channel_request_new (const gchar *path,
+ TpTestsSimpleConnection *conn,
+ const gchar *account_path,
+ gint64 user_action_time,
+ const gchar *preferred_handler,
+ GPtrArray *requests,
+ GHashTable *hints)
+{
+ return tp_tests_object_new_static_class (
+ TP_TESTS_TYPE_SIMPLE_CHANNEL_REQUEST,
+ "path", path,
+ "connection", conn,
+ "account", account_path,
+ "user-action-time", user_action_time,
+ "preferred-handler", preferred_handler,
+ "requests", requests,
+ "hints", hints,
+ NULL);
+}
diff --git a/tests/lib/telepathy/contactlist/simple-channel-request.h b/tests/lib/telepathy/contactlist/simple-channel-request.h
new file mode 100644
index 00000000..60ea3be6
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/simple-channel-request.h
@@ -0,0 +1,70 @@
+/*
+ * simple-channel-request.h - header for a simple channel request service.
+ *
+ * Copyright Ā© 2010 Collabora Ltd.
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_SIMPLE_CHANNEL_REQUEST_H__
+#define __TP_TESTS_SIMPLE_CHANNEL_REQUEST_H__
+
+#include <glib-object.h>
+
+#include <telepathy-glib/telepathy-glib.h>
+
+#include "simple-conn.h"
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsSimpleChannelRequest TpTestsSimpleChannelRequest;
+typedef struct _TpTestsSimpleChannelRequestClass TpTestsSimpleChannelRequestClass;
+typedef struct _TpTestsSimpleChannelRequestPrivate TpTestsSimpleChannelRequestPrivate;
+
+struct _TpTestsSimpleChannelRequestClass {
+ GObjectClass parent_class;
+ TpDBusPropertiesMixinClass dbus_props_class;
+};
+
+struct _TpTestsSimpleChannelRequest {
+ GObject parent;
+
+ TpTestsSimpleChannelRequestPrivate *priv;
+};
+
+GType tp_tests_simple_channel_request_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_SIMPLE_CHANNEL_REQUEST \
+ (tp_tests_simple_channel_request_get_type ())
+#define SIMPLE_CHANNEL_REQUEST(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_REQUEST, \
+ TpTestsSimpleChannelRequest))
+#define SIMPLE_CHANNEL_REQUEST_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_SIMPLE_CHANNEL_REQUEST, \
+ TpTestsSimpleChannelRequestClass))
+#define SIMPLE_IS_CHANNEL_REQUEST(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_REQUEST))
+#define SIMPLE_IS_CHANNEL_REQUEST_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_SIMPLE_CHANNEL_REQUEST))
+#define SIMPLE_CHANNEL_REQUEST_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_CHANNEL_REQUEST, \
+ TpTestsSimpleChannelRequestClass))
+
+TpTestsSimpleChannelRequest *
+tp_tests_simple_channel_request_new (const gchar *path,
+ TpTestsSimpleConnection *conn,
+ const gchar *account_path,
+ gint64 user_action_time,
+ const gchar *preferred_handler,
+ GPtrArray *requests,
+ GHashTable *hints);
+
+GHashTable * tp_tests_simple_channel_request_dup_immutable_props (
+ TpTestsSimpleChannelRequest *self);
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_SIMPLE_CHANNEL_REQUEST_H__ */
diff --git a/tests/lib/telepathy/contactlist/simple-client.c b/tests/lib/telepathy/contactlist/simple-client.c
new file mode 100644
index 00000000..c7431644
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/simple-client.c
@@ -0,0 +1,250 @@
+/*
+ * simple-client.c - a simple client
+ *
+ * Copyright Ā© 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "simple-client.h"
+
+#include <string.h>
+
+#include <dbus/dbus-glib.h>
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#include "tests/lib/util.h"
+
+G_DEFINE_TYPE (TpTestsSimpleClient, tp_tests_simple_client, TP_TYPE_BASE_CLIENT)
+
+static void
+simple_observe_channels (
+ TpBaseClient *client,
+ TpAccount *account,
+ TpConnection *connection,
+ GList *channels,
+ TpChannelDispatchOperation *dispatch_operation,
+ GList *requests,
+ TpObserveChannelsContext *context)
+{
+ TpTestsSimpleClient *self = TP_TESTS_SIMPLE_CLIENT (client);
+ GHashTable *info;
+ gboolean fail;
+ GList *l;
+
+ /* Fail if caller set the fake "FAIL" info */
+ g_object_get (context, "observer-info", &info, NULL);
+ fail = tp_asv_get_boolean (info, "FAIL", NULL);
+ g_hash_table_unref (info);
+
+ if (self->observe_ctx != NULL)
+ {
+ g_object_unref (self->observe_ctx);
+ self->observe_ctx = NULL;
+ }
+
+ if (fail)
+ {
+ GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "No observation for you!" };
+
+ tp_observe_channels_context_fail (context, &error);
+ return;
+ }
+
+ g_assert (TP_IS_ACCOUNT (account));
+ g_assert (tp_proxy_is_prepared (account, TP_ACCOUNT_FEATURE_CORE));
+
+ g_assert (TP_IS_CONNECTION (connection));
+ g_assert (tp_proxy_is_prepared (connection, TP_CONNECTION_FEATURE_CORE));
+
+ g_assert_cmpuint (g_list_length (channels), >, 0);
+ for (l = channels; l != NULL; l = g_list_next (l))
+ {
+ TpChannel *channel = l->data;
+
+ g_assert (TP_IS_CHANNEL (channel));
+ g_assert (tp_proxy_is_prepared (channel, TP_CHANNEL_FEATURE_CORE) ||
+ tp_proxy_get_invalidated (channel) != NULL);
+ }
+
+ if (dispatch_operation != NULL)
+ g_assert (TP_IS_CHANNEL_DISPATCH_OPERATION (dispatch_operation));
+
+ for (l = requests; l != NULL; l = g_list_next (l))
+ {
+ TpChannelRequest *request = l->data;
+
+ g_assert (TP_IS_CHANNEL_REQUEST (request));
+ }
+
+ self->observe_ctx = g_object_ref (context);
+ tp_observe_channels_context_accept (context);
+}
+
+static void
+simple_add_dispatch_operation (
+ TpBaseClient *client,
+ TpAccount *account,
+ TpConnection *connection,
+ GList *channels,
+ TpChannelDispatchOperation *dispatch_operation,
+ TpAddDispatchOperationContext *context)
+{
+ TpTestsSimpleClient *self = TP_TESTS_SIMPLE_CLIENT (client);
+ GList *l;
+
+ g_assert (TP_IS_ACCOUNT (account));
+ g_assert (tp_proxy_is_prepared (account, TP_ACCOUNT_FEATURE_CORE));
+
+ g_assert (TP_IS_CONNECTION (connection));
+ g_assert (tp_proxy_is_prepared (connection, TP_CONNECTION_FEATURE_CORE));
+
+ g_assert (TP_IS_CHANNEL_DISPATCH_OPERATION (dispatch_operation));
+ g_assert (tp_proxy_is_prepared (dispatch_operation,
+ TP_CHANNEL_DISPATCH_OPERATION_FEATURE_CORE) ||
+ tp_proxy_get_invalidated (dispatch_operation) != NULL);
+
+ if (self->add_dispatch_ctx != NULL)
+ {
+ g_object_unref (self->add_dispatch_ctx);
+ self->add_dispatch_ctx = NULL;
+ }
+
+ g_assert_cmpuint (g_list_length (channels), >, 0);
+ for (l = channels; l != NULL; l = g_list_next (l))
+ {
+ TpChannel *channel = l->data;
+
+ g_assert (TP_IS_CHANNEL (channel));
+ g_assert (tp_proxy_is_prepared (channel, TP_CHANNEL_FEATURE_CORE) ||
+ tp_proxy_get_invalidated (channel) != NULL);
+ }
+
+ self->add_dispatch_ctx = g_object_ref (context);
+ tp_add_dispatch_operation_context_accept (context);
+}
+
+static void
+simple_handle_channels (TpBaseClient *client,
+ TpAccount *account,
+ TpConnection *connection,
+ GList *channels,
+ GList *requests_satisfied,
+ gint64 user_action_time,
+ TpHandleChannelsContext *context)
+{
+ TpTestsSimpleClient *self = TP_TESTS_SIMPLE_CLIENT (client);
+ GList *l;
+
+ if (self->handle_channels_ctx != NULL)
+ {
+ g_object_unref (self->handle_channels_ctx);
+ self->handle_channels_ctx = NULL;
+ }
+
+ g_assert (TP_IS_ACCOUNT (account));
+ g_assert (tp_proxy_is_prepared (account, TP_ACCOUNT_FEATURE_CORE));
+
+ g_assert (TP_IS_CONNECTION (connection));
+ g_assert (tp_proxy_is_prepared (connection, TP_CONNECTION_FEATURE_CORE));
+
+ g_assert_cmpuint (g_list_length (channels), >, 0);
+ for (l = channels; l != NULL; l = g_list_next (l))
+ {
+ TpChannel *channel = l->data;
+
+ g_assert (TP_IS_CHANNEL (channel));
+ g_assert (tp_proxy_is_prepared (channel, TP_CHANNEL_FEATURE_CORE) ||
+ tp_proxy_get_invalidated (channel) != NULL);
+ }
+
+ for (l = requests_satisfied; l != NULL; l = g_list_next (l))
+ {
+ TpChannelRequest *request = l->data;
+
+ g_assert (TP_IS_CHANNEL_REQUEST (request));
+ }
+
+ self->handle_channels_ctx = g_object_ref (context);
+ tp_handle_channels_context_accept (context);
+}
+
+static void
+tp_tests_simple_client_init (TpTestsSimpleClient *self)
+{
+}
+
+static void
+tp_tests_simple_client_dispose (GObject *object)
+{
+ TpTestsSimpleClient *self = TP_TESTS_SIMPLE_CLIENT (object);
+ void (*dispose) (GObject *) =
+ G_OBJECT_CLASS (tp_tests_simple_client_parent_class)->dispose;
+
+ if (self->observe_ctx != NULL)
+ {
+ g_object_unref (self->observe_ctx);
+ self->observe_ctx = NULL;
+ }
+
+ if (self->add_dispatch_ctx != NULL)
+ {
+ g_object_unref (self->add_dispatch_ctx);
+ self->add_dispatch_ctx = NULL;
+ }
+
+ if (self->handle_channels_ctx != NULL)
+ {
+ g_object_unref (self->handle_channels_ctx);
+ self->handle_channels_ctx = NULL;
+ }
+
+ if (dispose != NULL)
+ dispose (object);
+}
+
+static void
+tp_tests_simple_client_class_init (TpTestsSimpleClientClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ TpBaseClientClass *base_class = TP_BASE_CLIENT_CLASS (klass);
+
+ object_class->dispose = tp_tests_simple_client_dispose;
+
+ tp_base_client_implement_observe_channels (base_class,
+ simple_observe_channels);
+
+ tp_base_client_implement_add_dispatch_operation (base_class,
+ simple_add_dispatch_operation);
+
+ tp_base_client_implement_handle_channels (base_class,
+ simple_handle_channels);
+}
+
+TpTestsSimpleClient *
+tp_tests_simple_client_new (TpClientFactory *factory,
+ const gchar *name,
+ gboolean uniquify_name)
+{
+ return tp_tests_object_new_static_class (TP_TESTS_TYPE_SIMPLE_CLIENT,
+ "factory", factory,
+ "name", name,
+ "uniquify-name", uniquify_name,
+ NULL);
+}
+
+TpTestsSimpleClient *
+tp_tests_simple_client_new_with_am (TpAccountManager *account_mgr,
+ const gchar *name,
+ gboolean uniquify_name)
+{
+ return tp_tests_simple_client_new (tp_proxy_get_factory (account_mgr),
+ name, uniquify_name);
+}
diff --git a/tests/lib/telepathy/contactlist/simple-client.h b/tests/lib/telepathy/contactlist/simple-client.h
new file mode 100644
index 00000000..b6f7b5f8
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/simple-client.h
@@ -0,0 +1,64 @@
+/*
+ * simple-client.h - header for a simple client
+ *
+ * Copyright Ā© 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_SIMPLE_CLIENT_H__
+#define __TP_TESTS_SIMPLE_CLIENT_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsSimpleClient TpTestsSimpleClient;
+typedef struct _TpTestsSimpleClientClass TpTestsSimpleClientClass;
+
+struct _TpTestsSimpleClientClass {
+ TpBaseClientClass parent_class;
+};
+
+struct _TpTestsSimpleClient {
+ TpBaseClient parent;
+
+ TpObserveChannelsContext *observe_ctx;
+ TpAddDispatchOperationContext *add_dispatch_ctx;
+ TpHandleChannelsContext *handle_channels_ctx;
+};
+
+GType tp_tests_simple_client_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_SIMPLE_CLIENT \
+ (tp_tests_simple_client_get_type ())
+#define TP_TESTS_SIMPLE_CLIENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_SIMPLE_CLIENT, \
+ TpTestsSimpleClient))
+#define TP_TESTS_SIMPLE_CLIENT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_SIMPLE_CLIENT, \
+ TpTestsSimpleClientClass))
+#define SIMPLE_IS_CLIENT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_SIMPLE_CLIENT))
+#define SIMPLE_IS_CLIENT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_SIMPLE_CLIENT))
+#define TP_TESTS_SIMPLE_CLIENT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_CLIENT, \
+ TpTestsSimpleClientClass))
+
+TpTestsSimpleClient * tp_tests_simple_client_new (TpClientFactory *factory,
+ const gchar *name,
+ gboolean uniquify_name);
+
+TpTestsSimpleClient * tp_tests_simple_client_new_with_am (
+ TpAccountManager *account_mgr,
+ const gchar *name,
+ gboolean uniquify_name);
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_SIMPLE_CONN_H__ */
diff --git a/tests/lib/telepathy/contactlist/simple-conn.c b/tests/lib/telepathy/contactlist/simple-conn.c
index e6ee214e..fa7bfdac 100644
--- a/tests/lib/telepathy/contactlist/simple-conn.c
+++ b/tests/lib/telepathy/contactlist/simple-conn.c
@@ -17,36 +17,32 @@
#include <dbus/dbus-glib.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/errors.h>
-#include <telepathy-glib/gtypes.h>
-#include <telepathy-glib/handle-repo-dynamic.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/util.h>
-
-#include "textchan-null.h"
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#include "echo-chan.h"
#include "room-list-chan.h"
#include "util.h"
-static void conn_iface_init (TpSvcConnectionClass *);
+static void props_iface_init (TpSvcDBusPropertiesClass *);
G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleConnection, tp_tests_simple_connection,
TP_TYPE_BASE_CONNECTION,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION, conn_iface_init))
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, props_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CONNECTION, NULL))
/* type definition stuff */
enum
{
PROP_ACCOUNT = 1,
- PROP_BREAK_PROPS = 2,
- PROP_DBUS_STATUS = 3,
+ PROP_DBUS_STATUS,
N_PROPS
};
enum
{
- SIGNAL_GOT_SELF_HANDLE,
+ SIGNAL_GOT_ALL,
N_SIGNALS
};
@@ -57,13 +53,10 @@ struct _TpTestsSimpleConnectionPrivate
gchar *account;
guint connect_source;
guint disconnect_source;
- gboolean break_fastpath_props;
/* TpHandle => reffed TpTestsTextChannelNull */
GHashTable *text_channels;
TpTestsRoomListChan *room_list_chan;
-
- GError *get_self_handle_error /* initially NULL */ ;
};
static void
@@ -88,16 +81,7 @@ get_property (GObject *object,
case PROP_ACCOUNT:
g_value_set_string (value, self->priv->account);
break;
- case PROP_BREAK_PROPS:
- g_value_set_boolean (value, self->priv->break_fastpath_props);
- break;
case PROP_DBUS_STATUS:
- if (self->priv->break_fastpath_props)
- {
- g_debug ("returning broken value for Connection.Status");
- g_value_set_uint (value, 0xdeadbeefU);
- }
- else
{
g_value_set_uint (value,
tp_base_connection_get_status (TP_BASE_CONNECTION (self)));
@@ -121,9 +105,6 @@ set_property (GObject *object,
g_free (self->priv->account);
self->priv->account = g_utf8_strdown (g_value_get_string (value), -1);
break;
- case PROP_BREAK_PROPS:
- self->priv->break_fastpath_props = g_value_get_boolean (value);
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
}
@@ -155,7 +136,6 @@ finalize (GObject *object)
g_source_remove (self->priv->disconnect_source);
}
- g_clear_error (&self->priv->get_self_handle_error);
g_free (self->priv->account);
G_OBJECT_CLASS (tp_tests_simple_connection_parent_class)->finalize (object);
@@ -203,7 +183,7 @@ create_handle_repos (TpBaseConnection *conn,
}
static GPtrArray *
-create_channel_factories (TpBaseConnection *conn)
+create_channel_managers (TpBaseConnection *conn)
{
return g_ptr_array_sized_new (0);
}
@@ -284,6 +264,19 @@ shut_down (TpBaseConnection *conn)
conn);
}
+static GPtrArray *
+get_interfaces_always_present (TpBaseConnection *base)
+{
+ GPtrArray *interfaces;
+
+ interfaces = TP_BASE_CONNECTION_CLASS (
+ tp_tests_simple_connection_parent_class)->get_interfaces_always_present (base);
+
+ g_ptr_array_add (interfaces, TP_IFACE_CONNECTION_INTERFACE_REQUESTS);
+
+ return interfaces;
+}
+
static void
tp_tests_simple_connection_class_init (TpTestsSimpleConnectionClass *klass)
{
@@ -291,8 +284,6 @@ tp_tests_simple_connection_class_init (TpTestsSimpleConnectionClass *klass)
(TpBaseConnectionClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
GParamSpec *param_spec;
- static const gchar *interfaces_always_present[] = {
- TP_IFACE_CONNECTION_INTERFACE_REQUESTS, NULL };
object_class->get_property = get_property;
object_class->set_property = set_property;
@@ -302,23 +293,17 @@ tp_tests_simple_connection_class_init (TpTestsSimpleConnectionClass *klass)
base_class->create_handle_repos = create_handle_repos;
base_class->get_unique_connection_name = get_unique_connection_name;
- base_class->create_channel_factories = create_channel_factories;
+ base_class->create_channel_managers = create_channel_managers;
base_class->start_connecting = start_connecting;
base_class->shut_down = shut_down;
- base_class->interfaces_always_present = interfaces_always_present;
+ base_class->get_interfaces_always_present = get_interfaces_always_present;
param_spec = g_param_spec_string ("account", "Account name",
"The username of this user", NULL,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_ACCOUNT, param_spec);
- param_spec = g_param_spec_boolean ("break-0192-properties",
- "Break 0.19.2 properties",
- "Break Connection D-Bus properties introduced in spec 0.19.2", FALSE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_BREAK_PROPS, param_spec);
-
param_spec = g_param_spec_uint ("dbus-status",
"Connection.Status",
"The connection status as visible on D-Bus (overridden so can break it)",
@@ -327,7 +312,7 @@ tp_tests_simple_connection_class_init (TpTestsSimpleConnectionClass *klass)
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (object_class, PROP_DBUS_STATUS, param_spec);
- signals[SIGNAL_GOT_SELF_HANDLE] = g_signal_new ("got-self-handle",
+ signals[SIGNAL_GOT_ALL] = g_signal_new ("got-all",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
0,
@@ -366,11 +351,10 @@ tp_tests_simple_connection_ensure_text_chan (TpTestsSimpleConnection *self,
const gchar *target_id,
GHashTable **props)
{
- TpTestsTextChannelNull *chan;
+ TpTestsEchoChannel *chan;
gchar *chan_path;
TpHandleRepoIface *contact_repo;
TpHandle handle;
- static guint count = 0;
TpBaseConnection *base_conn = (TpBaseConnection *) self;
/* Get contact handle */
@@ -382,21 +366,12 @@ tp_tests_simple_connection_ensure_text_chan (TpTestsSimpleConnection *self,
chan = g_hash_table_lookup (self->priv->text_channels,
GUINT_TO_POINTER (handle));
- if (chan != NULL)
+ if (chan == NULL)
{
- /* Channel already exist, reuse it */
- g_object_get (chan, "object-path", &chan_path, NULL);
- }
- else
- {
- chan_path = g_strdup_printf ("%s/Channel%u",
- tp_base_connection_get_object_path (base_conn), count++);
-
- chan = TP_TESTS_TEXT_CHANNEL_NULL (
+ chan = TP_TESTS_ECHO_CHANNEL (
tp_tests_object_new_static_class (
- TP_TESTS_TYPE_TEXT_CHANNEL_NULL,
+ TP_TESTS_TYPE_ECHO_CHANNEL,
"connection", self,
- "object-path", chan_path,
"handle", handle,
NULL));
@@ -404,8 +379,10 @@ tp_tests_simple_connection_ensure_text_chan (TpTestsSimpleConnection *self,
chan);
}
+ g_object_get (chan, "object-path", &chan_path, NULL);
+
if (props != NULL)
- *props = tp_tests_text_channel_get_props (chan);
+ g_object_get (chan, "channel-properties", props, NULL);
return chan_path;
}
@@ -455,44 +432,25 @@ tp_tests_simple_connection_ensure_room_list_chan (TpTestsSimpleConnection *self,
return chan_path;
}
-void
-tp_tests_simple_connection_set_get_self_handle_error (
- TpTestsSimpleConnection *self,
- GQuark domain,
- gint code,
- const gchar *message)
-{
- self->priv->get_self_handle_error = g_error_new_literal (domain, code,
- message);
-}
-
static void
-get_self_handle (TpSvcConnection *iface,
+get_all (TpSvcDBusProperties *iface,
+ const gchar *interface_name,
DBusGMethodInvocation *context)
{
- TpTestsSimpleConnection *self = TP_TESTS_SIMPLE_CONNECTION (iface);
- TpBaseConnection *base = TP_BASE_CONNECTION (iface);
-
- g_assert (TP_IS_BASE_CONNECTION (base));
-
- TP_BASE_CONNECTION_ERROR_IF_NOT_CONNECTED (base, context);
-
- if (self->priv->get_self_handle_error != NULL)
- {
- dbus_g_method_return_error (context, self->priv->get_self_handle_error);
- return;
- }
+ GHashTable *values = tp_dbus_properties_mixin_dup_all (G_OBJECT (iface),
+ interface_name);
- tp_svc_connection_return_from_get_self_handle (context,
- tp_base_connection_get_self_handle (base));
- g_signal_emit (self, signals[SIGNAL_GOT_SELF_HANDLE], 0);
+ tp_svc_dbus_properties_return_from_get_all (context, values);
+ g_hash_table_unref (values);
+ g_signal_emit (iface, signals[SIGNAL_GOT_ALL],
+ g_quark_from_string (interface_name));
}
static void
-conn_iface_init (TpSvcConnectionClass *iface)
+props_iface_init (TpSvcDBusPropertiesClass *iface)
{
-#define IMPLEMENT(prefix,x) \
- tp_svc_connection_implement_##x (iface, prefix##x)
- IMPLEMENT(,get_self_handle);
+#define IMPLEMENT(x) \
+ tp_svc_dbus_properties_implement_##x (iface, x)
+ IMPLEMENT (get_all);
#undef IMPLEMENT
}
diff --git a/tests/lib/telepathy/contactlist/simple-conn.h b/tests/lib/telepathy/contactlist/simple-conn.h
index 837400bc..ffe5778d 100644
--- a/tests/lib/telepathy/contactlist/simple-conn.h
+++ b/tests/lib/telepathy/contactlist/simple-conn.h
@@ -13,7 +13,7 @@
#define __TP_TESTS_SIMPLE_CONN_H__
#include <glib-object.h>
-#include <telepathy-glib/base-connection.h>
+#include <telepathy-glib/telepathy-glib.h>
G_BEGIN_DECLS
@@ -66,12 +66,6 @@ gchar * tp_tests_simple_connection_ensure_text_chan (
const gchar *target_id,
GHashTable **props);
-void tp_tests_simple_connection_set_get_self_handle_error (
- TpTestsSimpleConnection *self,
- GQuark domain,
- gint code,
- const gchar *message);
-
gchar * tp_tests_simple_connection_ensure_room_list_chan (
TpTestsSimpleConnection *self,
const gchar *server,
diff --git a/tests/lib/telepathy/contactlist/stream-tube-chan.c b/tests/lib/telepathy/contactlist/stream-tube-chan.c
new file mode 100644
index 00000000..e1184af8
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/stream-tube-chan.c
@@ -0,0 +1,650 @@
+/*
+ * stream-tube-chan.c - Simple stream tube channel
+ *
+ * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "config.h"
+
+#include "stream-tube-chan.h"
+#include "util.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#ifdef HAVE_GIO_UNIX
+#include <gio/gunixsocketaddress.h>
+#include <gio/gunixconnection.h>
+#endif
+
+#include <glib/gstdio.h>
+
+enum
+{
+ PROP_SERVICE = 1,
+ PROP_SUPPORTED_SOCKET_TYPES,
+ PROP_PARAMETERS,
+ PROP_STATE,
+};
+
+enum
+{
+ SIG_INCOMING_CONNECTION,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0, };
+
+
+struct _TpTestsStreamTubeChannelPrivate {
+ TpTubeChannelState state;
+ GHashTable *supported_socket_types;
+
+ /* Accepting side */
+ GSocketService *service;
+ GValue *access_control_param;
+
+ /* Offering side */
+ TpSocketAddressType address_type;
+ GValue *address;
+ gchar *unix_address;
+ gchar *unix_tmpdir;
+ guint connection_id;
+
+ TpSocketAccessControl access_control;
+};
+
+static void
+create_supported_socket_types (TpTestsStreamTubeChannel *self)
+{
+ TpSocketAccessControl access_control;
+ GArray *unix_tab;
+
+ g_assert (self->priv->supported_socket_types == NULL);
+ self->priv->supported_socket_types = g_hash_table_new_full (NULL, NULL,
+ NULL, _tp_destroy_socket_control_list);
+
+ /* Socket_Address_Type_Unix */
+ unix_tab = g_array_sized_new (FALSE, FALSE, sizeof (TpSocketAccessControl),
+ 1);
+ access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
+ g_array_append_val (unix_tab, access_control);
+
+ g_hash_table_insert (self->priv->supported_socket_types,
+ GUINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_UNIX), unix_tab);
+}
+
+static void
+tp_tests_stream_tube_channel_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsStreamTubeChannel *self = (TpTestsStreamTubeChannel *) object;
+
+ switch (property_id)
+ {
+ case PROP_SERVICE:
+ g_value_set_string (value, "test-service");
+ break;
+
+ case PROP_SUPPORTED_SOCKET_TYPES:
+ g_value_set_boxed (value,
+ self->priv->supported_socket_types);
+ break;
+
+ case PROP_PARAMETERS:
+ g_value_take_boxed (value, tp_asv_new (
+ "badger", G_TYPE_UINT, 42,
+ NULL));
+ break;
+
+ case PROP_STATE:
+ g_value_set_uint (value, self->priv->state);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+tp_tests_stream_tube_channel_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsStreamTubeChannel *self = (TpTestsStreamTubeChannel *) object;
+
+ switch (property_id)
+ {
+ case PROP_SUPPORTED_SOCKET_TYPES:
+ self->priv->supported_socket_types = g_value_dup_boxed (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void stream_tube_iface_init (gpointer iface, gpointer data);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (TpTestsStreamTubeChannel,
+ tp_tests_stream_tube_channel,
+ TP_TYPE_BASE_CHANNEL,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_STREAM_TUBE,
+ stream_tube_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_TUBE,
+ NULL);
+ )
+
+/* type definition stuff */
+
+static GPtrArray *
+tp_tests_stream_tube_channel_get_interfaces (TpBaseChannel *self)
+{
+ GPtrArray *interfaces;
+
+ interfaces = TP_BASE_CHANNEL_CLASS (
+ tp_tests_stream_tube_channel_parent_class)->get_interfaces (self);
+
+ g_ptr_array_add (interfaces, TP_IFACE_CHANNEL_INTERFACE_TUBE);
+ return interfaces;
+};
+
+static void
+tp_tests_stream_tube_channel_init (TpTestsStreamTubeChannel *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
+ TP_TESTS_TYPE_STREAM_TUBE_CHANNEL, TpTestsStreamTubeChannelPrivate);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_props,
+ GObjectConstructParam *props)
+{
+ GObject *object =
+ G_OBJECT_CLASS (tp_tests_stream_tube_channel_parent_class)->constructor (
+ type, n_props, props);
+ TpTestsStreamTubeChannel *self = TP_TESTS_STREAM_TUBE_CHANNEL (object);
+
+ if (tp_base_channel_is_requested (TP_BASE_CHANNEL (self)))
+ self->priv->state = TP_TUBE_CHANNEL_STATE_NOT_OFFERED;
+ else
+ self->priv->state = TP_TUBE_CHANNEL_STATE_LOCAL_PENDING;
+
+ if (self->priv->supported_socket_types == NULL)
+ create_supported_socket_types (self);
+
+ tp_base_channel_register (TP_BASE_CHANNEL (self));
+
+ return object;
+}
+
+static void
+dispose (GObject *object)
+{
+ TpTestsStreamTubeChannel *self = (TpTestsStreamTubeChannel *) object;
+
+ if (self->priv->service != NULL)
+ {
+ g_socket_service_stop (self->priv->service);
+ tp_clear_object (&self->priv->service);
+ }
+
+ tp_clear_pointer (&self->priv->address, tp_g_value_slice_free);
+ tp_clear_pointer (&self->priv->supported_socket_types, g_hash_table_unref);
+ tp_clear_pointer (&self->priv->access_control_param, tp_g_value_slice_free);
+
+ if (self->priv->unix_address != NULL)
+ g_unlink (self->priv->unix_address);
+
+ tp_clear_pointer (&self->priv->unix_address, g_free);
+
+ if (self->priv->unix_tmpdir != NULL)
+ g_rmdir (self->priv->unix_tmpdir);
+
+ tp_clear_pointer (&self->priv->unix_tmpdir, g_free);
+
+ ((GObjectClass *) tp_tests_stream_tube_channel_parent_class)->dispose (
+ object);
+}
+
+static void
+channel_close (TpBaseChannel *channel)
+{
+ tp_base_channel_destroyed (channel);
+}
+
+static void
+fill_immutable_properties (TpBaseChannel *chan,
+ GHashTable *properties)
+{
+ TpBaseChannelClass *klass = TP_BASE_CHANNEL_CLASS (
+ tp_tests_stream_tube_channel_parent_class);
+
+ klass->fill_immutable_properties (chan, properties);
+
+ tp_dbus_properties_mixin_fill_properties_hash (
+ G_OBJECT (chan), properties,
+ TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, "Service",
+ TP_IFACE_CHANNEL_TYPE_STREAM_TUBE, "SupportedSocketTypes",
+ NULL);
+
+ if (!tp_base_channel_is_requested (chan))
+ {
+ /* Parameters is immutable only for incoming tubes */
+ tp_dbus_properties_mixin_fill_properties_hash (
+ G_OBJECT (chan), properties,
+ TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters",
+ NULL);
+ }
+}
+
+static void
+tp_tests_stream_tube_channel_class_init (TpTestsStreamTubeChannelClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
+ GParamSpec *param_spec;
+ static TpDBusPropertiesMixinPropImpl stream_tube_props[] = {
+ { "Service", "service", NULL, },
+ { "SupportedSocketTypes", "supported-socket-types", NULL },
+ { NULL }
+ };
+ static TpDBusPropertiesMixinPropImpl tube_props[] = {
+ { "Parameters", "parameters", NULL, },
+ { "State", "state", NULL, },
+ { NULL }
+ };
+
+ object_class->constructor = constructor;
+ object_class->get_property = tp_tests_stream_tube_channel_get_property;
+ object_class->set_property = tp_tests_stream_tube_channel_set_property;
+ object_class->dispose = dispose;
+
+ base_class->channel_type = TP_IFACE_CHANNEL_TYPE_STREAM_TUBE;
+ base_class->get_interfaces = tp_tests_stream_tube_channel_get_interfaces;
+ base_class->close = channel_close;
+ base_class->fill_immutable_properties = fill_immutable_properties;
+
+ /* base_class->target_handle_type is defined in subclasses */
+
+ param_spec = g_param_spec_string ("service", "service name",
+ "the service associated with this tube object.",
+ "",
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_SERVICE, param_spec);
+
+ param_spec = g_param_spec_boxed (
+ "supported-socket-types", "Supported socket types",
+ "GHashTable containing supported socket types.",
+ TP_HASH_TYPE_SUPPORTED_SOCKET_MAP,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_SUPPORTED_SOCKET_TYPES,
+ param_spec);
+
+ param_spec = g_param_spec_boxed (
+ "parameters", "Parameters",
+ "parameters of the tube",
+ TP_HASH_TYPE_STRING_VARIANT_MAP,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_PARAMETERS,
+ param_spec);
+
+ param_spec = g_param_spec_uint (
+ "state", "TpTubeState",
+ "state of the tube",
+ 0, TP_NUM_TUBE_CHANNEL_STATES - 1, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_STATE,
+ param_spec);
+
+ signals[SIG_INCOMING_CONNECTION] = g_signal_new ("incoming-connection",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 1, G_TYPE_IO_STREAM);
+
+ tp_dbus_properties_mixin_implement_interface (object_class,
+ TP_IFACE_QUARK_CHANNEL_TYPE_STREAM_TUBE,
+ tp_dbus_properties_mixin_getter_gobject_properties, NULL,
+ stream_tube_props);
+
+ tp_dbus_properties_mixin_implement_interface (object_class,
+ TP_IFACE_QUARK_CHANNEL_INTERFACE_TUBE,
+ tp_dbus_properties_mixin_getter_gobject_properties, NULL,
+ tube_props);
+
+ g_type_class_add_private (object_class,
+ sizeof (TpTestsStreamTubeChannelPrivate));
+}
+
+static void
+change_state (TpTestsStreamTubeChannel *self,
+ TpTubeChannelState state)
+{
+ self->priv->state = state;
+
+ tp_svc_channel_interface_tube_emit_tube_channel_state_changed (self, state);
+}
+
+/* Return the address of the socket which has been shared over the tube */
+GSocketAddress *
+tp_tests_stream_tube_channel_get_server_address (TpTestsStreamTubeChannel *self)
+{
+ return tp_g_socket_address_from_variant (self->priv->address_type,
+ self->priv->address, NULL);
+}
+
+static gboolean
+check_address_type (TpTestsStreamTubeChannel *self,
+ TpSocketAddressType address_type,
+ TpSocketAccessControl access_control)
+{
+ GArray *arr;
+ guint i;
+
+ arr = g_hash_table_lookup (self->priv->supported_socket_types,
+ GUINT_TO_POINTER (address_type));
+ if (arr == NULL)
+ return FALSE;
+
+ for (i = 0; i < arr->len; i++)
+ {
+ if (g_array_index (arr, TpSocketAccessControl, i) == access_control)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+stream_tube_offer (TpSvcChannelTypeStreamTube *iface,
+ guint address_type,
+ const GValue *address,
+ guint access_control,
+ GHashTable *parameters,
+ DBusGMethodInvocation *context)
+{
+ TpTestsStreamTubeChannel *self = (TpTestsStreamTubeChannel *) iface;
+ GError *error = NULL;
+
+ if (self->priv->state != TP_TUBE_CHANNEL_STATE_NOT_OFFERED)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "Tube is not in the not offered state");
+ goto fail;
+ }
+
+ if (!check_address_type (self, address_type, access_control))
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "Address type not supported with this access control");
+ goto fail;
+ }
+
+ self->priv->address_type = address_type;
+ self->priv->address = tp_g_value_slice_dup (address);
+ self->priv->access_control = access_control;
+
+ change_state (self, TP_TUBE_CHANNEL_STATE_REMOTE_PENDING);
+
+ tp_svc_channel_type_stream_tube_return_from_offer (context);
+ return;
+
+fail:
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+}
+
+static void
+service_incoming_cb (GSocketService *service,
+ GSocketConnection *connection,
+ GObject *source_object,
+ gpointer user_data)
+{
+ TpTestsStreamTubeChannel *self = user_data;
+ GError *error = NULL;
+
+ if (self->priv->access_control == TP_SOCKET_ACCESS_CONTROL_CREDENTIALS)
+ {
+#ifdef HAVE_GIO_UNIX
+ GCredentials *creds;
+ guchar byte;
+
+ /* FIXME: we should an async version of this API (bgo #629503) */
+ creds = tp_unix_connection_receive_credentials_with_byte (
+ connection, &byte, NULL, &error);
+ g_assert_no_error (error);
+
+ g_assert_cmpuint (byte, ==,
+ g_value_get_uchar (self->priv->access_control_param));
+ g_object_unref (creds);
+#else
+ /* Tests shouldn't use this if not supported */
+ g_assert_not_reached ();
+#endif
+ }
+ else if (self->priv->access_control == TP_SOCKET_ACCESS_CONTROL_PORT)
+ {
+ GSocketAddress *addr;
+ guint16 port;
+
+ addr = g_socket_connection_get_remote_address (connection, &error);
+ g_assert_no_error (error);
+
+ port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
+
+ g_assert_cmpuint (port, ==,
+ g_value_get_uint (self->priv->access_control_param));
+
+ g_object_unref (addr);
+ }
+
+ tp_svc_channel_type_stream_tube_emit_new_local_connection (self,
+ self->priv->connection_id);
+
+ self->priv->connection_id++;
+
+ g_signal_emit (self, signals[SIG_INCOMING_CONNECTION], 0, connection);
+}
+
+static void
+stream_tube_accept (TpSvcChannelTypeStreamTube *iface,
+ TpSocketAddressType address_type,
+ TpSocketAccessControl access_control,
+ const GValue *access_control_param,
+ DBusGMethodInvocation *context)
+{
+ TpTestsStreamTubeChannel *self = (TpTestsStreamTubeChannel *) iface;
+ GError *error = NULL;
+ GValue *address;
+
+ if (self->priv->state != TP_TUBE_CHANNEL_STATE_LOCAL_PENDING)
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "Tube is not in the local pending state");
+ goto fail;
+ }
+
+ if (!check_address_type (self, address_type, access_control))
+ {
+ g_set_error (&error, TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "Address type not supported with this access control");
+ goto fail;
+ }
+
+ address = _tp_create_local_socket (address_type, access_control,
+ &self->priv->service, &self->priv->unix_address,
+ &self->priv->unix_tmpdir, &error);
+ tp_g_signal_connect_object (self->priv->service, "incoming",
+ G_CALLBACK (service_incoming_cb), self, 0);
+
+ self->priv->access_control = access_control;
+ self->priv->access_control_param = tp_g_value_slice_dup (
+ access_control_param);
+
+ change_state (self, TP_TUBE_CHANNEL_STATE_OPEN);
+
+ tp_svc_channel_type_stream_tube_return_from_accept (context, address);
+
+ tp_g_value_slice_free (address);
+ return;
+
+fail:
+ dbus_g_method_return_error (context, error);
+ g_error_free (error);
+}
+
+static void
+stream_tube_iface_init (gpointer iface,
+ gpointer data)
+{
+ TpSvcChannelTypeStreamTubeClass *klass = iface;
+
+#define IMPLEMENT(x) tp_svc_channel_type_stream_tube_implement_##x (klass, stream_tube_##x)
+ IMPLEMENT(offer);
+ IMPLEMENT(accept);
+#undef IMPLEMENT
+}
+
+/* Called to emulate a peer connecting to an offered tube */
+void
+tp_tests_stream_tube_channel_peer_connected (TpTestsStreamTubeChannel *self,
+ GIOStream *stream,
+ TpHandle handle)
+{
+ GValue *connection_param;
+ TpBaseChannel *base = (TpBaseChannel *) self;
+ TpBaseConnection *conn = tp_base_channel_get_connection (base);
+ TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (conn,
+ TP_HANDLE_TYPE_CONTACT);
+
+ if (self->priv->state == TP_TUBE_CHANNEL_STATE_REMOTE_PENDING)
+ change_state (self, TP_TUBE_CHANNEL_STATE_OPEN);
+
+ g_assert (self->priv->state == TP_TUBE_CHANNEL_STATE_OPEN);
+
+ switch (self->priv->access_control)
+ {
+ case TP_SOCKET_ACCESS_CONTROL_LOCALHOST:
+ connection_param = tp_g_value_slice_new_static_string ("dummy");
+ break;
+
+ case TP_SOCKET_ACCESS_CONTROL_CREDENTIALS:
+ {
+#ifdef HAVE_GIO_UNIX
+ GError *error = NULL;
+ guchar byte = g_random_int_range (0, G_MAXUINT8);
+
+ /* FIXME: we should an async version of this API (bgo #629503) */
+ tp_unix_connection_send_credentials_with_byte (
+ G_SOCKET_CONNECTION (stream), byte, NULL, &error);
+ g_assert_no_error (error);
+
+ connection_param = tp_g_value_slice_new_byte (byte);
+#else
+ /* Tests shouldn't use this if not supported */
+ g_assert_not_reached ();
+#endif
+ }
+ break;
+
+ case TP_SOCKET_ACCESS_CONTROL_PORT:
+ {
+ GSocketAddress *addr;
+ GError *error = NULL;
+
+ addr = g_socket_connection_get_local_address (
+ G_SOCKET_CONNECTION (stream), &error);
+ g_assert_no_error (error);
+
+ connection_param = tp_g_value_slice_new_take_boxed (
+ TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4,
+ dbus_g_type_specialized_construct (
+ TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4));
+
+ dbus_g_type_struct_set (connection_param,
+ 0, "badger",
+ 1, g_inet_socket_address_get_port (
+ G_INET_SOCKET_ADDRESS (addr)),
+ G_MAXUINT);
+
+ g_object_unref (addr);
+ }
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ tp_svc_channel_type_stream_tube_emit_new_remote_connection (self, handle,
+ tp_handle_inspect (contact_repo, handle), connection_param,
+ self->priv->connection_id);
+
+ self->priv->connection_id++;
+
+ tp_g_value_slice_free (connection_param);
+}
+
+void
+tp_tests_stream_tube_channel_last_connection_disconnected (
+ TpTestsStreamTubeChannel *self,
+ const gchar *error)
+{
+ tp_svc_channel_type_stream_tube_emit_connection_closed (self,
+ self->priv->connection_id - 1, error, "kaboum");
+}
+
+/* Contact Stream Tube */
+
+G_DEFINE_TYPE (TpTestsContactStreamTubeChannel,
+ tp_tests_contact_stream_tube_channel,
+ TP_TESTS_TYPE_STREAM_TUBE_CHANNEL)
+
+static void
+tp_tests_contact_stream_tube_channel_init (
+ TpTestsContactStreamTubeChannel *self)
+{
+}
+
+static void
+tp_tests_contact_stream_tube_channel_class_init (
+ TpTestsContactStreamTubeChannelClass *klass)
+{
+ TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
+
+ base_class->target_handle_type = TP_HANDLE_TYPE_CONTACT;
+}
+
+/* Room Stream Tube */
+
+G_DEFINE_TYPE (TpTestsRoomStreamTubeChannel,
+ tp_tests_room_stream_tube_channel,
+ TP_TESTS_TYPE_STREAM_TUBE_CHANNEL)
+
+static void
+tp_tests_room_stream_tube_channel_init (
+ TpTestsRoomStreamTubeChannel *self)
+{
+}
+
+static void
+tp_tests_room_stream_tube_channel_class_init (
+ TpTestsRoomStreamTubeChannelClass *klass)
+{
+ TpBaseChannelClass *base_class = TP_BASE_CHANNEL_CLASS (klass);
+
+ base_class->target_handle_type = TP_HANDLE_TYPE_ROOM;
+}
diff --git a/tests/lib/telepathy/contactlist/stream-tube-chan.h b/tests/lib/telepathy/contactlist/stream-tube-chan.h
new file mode 100644
index 00000000..26729127
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/stream-tube-chan.h
@@ -0,0 +1,129 @@
+/*
+ * stream-tube-chan.h - Simple stream tube channel
+ *
+ * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_STREAM_TUBE_CHAN_H__
+#define __TP_STREAM_TUBE_CHAN_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+G_BEGIN_DECLS
+
+/* Base Class */
+typedef struct _TpTestsStreamTubeChannel TpTestsStreamTubeChannel;
+typedef struct _TpTestsStreamTubeChannelClass TpTestsStreamTubeChannelClass;
+typedef struct _TpTestsStreamTubeChannelPrivate TpTestsStreamTubeChannelPrivate;
+
+GType tp_tests_stream_tube_channel_get_type (void);
+
+#define TP_TESTS_TYPE_STREAM_TUBE_CHANNEL \
+ (tp_tests_stream_tube_channel_get_type ())
+#define TP_TESTS_STREAM_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_STREAM_TUBE_CHANNEL, \
+ TpTestsStreamTubeChannel))
+#define TP_TESTS_STREAM_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_STREAM_TUBE_CHANNEL, \
+ TpTestsStreamTubeChannelClass))
+#define TP_TESTS_IS_STREAM_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_STREAM_TUBE_CHANNEL))
+#define TP_TESTS_IS_STREAM_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_STREAM_TUBE_CHANNEL))
+#define TP_TESTS_STREAM_TUBE_CHANNEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_STREAM_TUBE_CHANNEL, \
+ TpTestsStreamTubeChannelClass))
+
+struct _TpTestsStreamTubeChannelClass {
+ TpBaseChannelClass parent_class;
+ TpDBusPropertiesMixinClass dbus_properties_class;
+};
+
+struct _TpTestsStreamTubeChannel {
+ TpBaseChannel parent;
+
+ TpTestsStreamTubeChannelPrivate *priv;
+};
+
+GSocketAddress * tp_tests_stream_tube_channel_get_server_address (
+ TpTestsStreamTubeChannel *self);
+
+void tp_tests_stream_tube_channel_peer_connected (
+ TpTestsStreamTubeChannel *self,
+ GIOStream *stream,
+ TpHandle handle);
+
+void tp_tests_stream_tube_channel_last_connection_disconnected (
+ TpTestsStreamTubeChannel *self,
+ const gchar *error);
+
+/* Contact Stream Tube */
+
+typedef struct _TpTestsContactStreamTubeChannel TpTestsContactStreamTubeChannel;
+typedef struct _TpTestsContactStreamTubeChannelClass TpTestsContactStreamTubeChannelClass;
+
+GType tp_tests_contact_stream_tube_channel_get_type (void);
+
+#define TP_TESTS_TYPE_CONTACT_STREAM_TUBE_CHANNEL \
+ (tp_tests_contact_stream_tube_channel_get_type ())
+#define TP_TESTS_CONTACT_STREAM_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_CONTACT_STREAM_TUBE_CHANNEL, \
+ TpTestsContactStreamTubeChannel))
+#define TP_TESTS_CONTACT_STREAM_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_CONTACT_STREAM_TUBE_CHANNEL, \
+ TpTestsContactStreamTubeChannelClass))
+#define TP_TESTS_IS_CONTACT_STREAM_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_CONTACT_STREAM_TUBE_CHANNEL))
+#define TP_TESTS_IS_CONTACT_STREAM_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_CONTACT_STREAM_TUBE_CHANNEL))
+#define TP_TESTS_CONTACT_STREAM_TUBE_CHANNEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_CONTACT_STREAM_TUBE_CHANNEL, \
+ TpTestsContactStreamTubeChannelClass))
+
+struct _TpTestsContactStreamTubeChannelClass {
+ TpTestsStreamTubeChannelClass parent_class;
+};
+
+struct _TpTestsContactStreamTubeChannel {
+ TpTestsStreamTubeChannel parent;
+};
+
+/* Room Stream Tube */
+
+typedef struct _TpTestsRoomStreamTubeChannel TpTestsRoomStreamTubeChannel;
+typedef struct _TpTestsRoomStreamTubeChannelClass TpTestsRoomStreamTubeChannelClass;
+
+GType tp_tests_room_stream_tube_channel_get_type (void);
+
+#define TP_TESTS_TYPE_ROOM_STREAM_TUBE_CHANNEL \
+ (tp_tests_room_stream_tube_channel_get_type ())
+#define TP_TESTS_ROOM_STREAM_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_ROOM_STREAM_TUBE_CHANNEL, \
+ TpTestsRoomStreamTubeChannel))
+#define TP_TESTS_ROOM_STREAM_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_ROOM_STREAM_TUBE_CHANNEL, \
+ TpTestsRoomStreamTubeChannelClass))
+#define TP_TESTS_IS_ROOM_STREAM_TUBE_CHANNEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_ROOM_STREAM_TUBE_CHANNEL))
+#define TP_TESTS_IS_ROOM_STREAM_TUBE_CHANNEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_ROOM_STREAM_TUBE_CHANNEL))
+#define TP_TESTS_ROOM_STREAM_TUBE_CHANNEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_ROOM_STREAM_TUBE_CHANNEL, \
+ TpTestsRoomStreamTubeChannelClass))
+
+struct _TpTestsRoomStreamTubeChannelClass {
+ TpTestsStreamTubeChannelClass parent_class;
+};
+
+struct _TpTestsRoomStreamTubeChannel {
+ TpTestsStreamTubeChannel parent;
+};
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_STREAM_TUBE_CHAN_H__ */
diff --git a/tests/lib/telepathy/contactlist/stub-object.c b/tests/lib/telepathy/contactlist/stub-object.c
new file mode 100644
index 00000000..14828768
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/stub-object.c
@@ -0,0 +1,68 @@
+#include "config.h"
+
+#include "stub-object.h"
+
+G_DEFINE_TYPE (TpTestsStubObject, tp_tests_stub_object, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_NAME,
+ N_PROPS
+};
+
+static void
+stub_object_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *param_spec)
+{
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ g_value_set_string (value, "Bruce");
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, param_spec);
+ break;
+ }
+}
+
+static void
+stub_object_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *param_spec)
+{
+ switch (prop_id)
+ {
+ case PROP_NAME:
+ /* do nothing */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, param_spec);
+ break;
+ }
+}
+
+static void
+tp_tests_stub_object_class_init (TpTestsStubObjectClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+
+ object_class->get_property = stub_object_get_property;
+ object_class->set_property = stub_object_set_property;
+
+ g_object_class_install_property (object_class, PROP_NAME,
+ g_param_spec_string ("name",
+ "Name",
+ "The name of the stub object",
+ "Bruce",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE));
+}
+
+static void
+tp_tests_stub_object_init (TpTestsStubObject *self)
+{
+}
diff --git a/tests/lib/telepathy/contactlist/stub-object.h b/tests/lib/telepathy/contactlist/stub-object.h
new file mode 100644
index 00000000..ccdb0940
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/stub-object.h
@@ -0,0 +1,11 @@
+#ifndef __TP_TESTS_STUB_OBJECT_H__
+#define __TP_TESTS_STUB_OBJECT_H__
+
+#include <glib-object.h>
+
+typedef struct { GObject p; } TpTestsStubObject;
+typedef struct { GObjectClass p; } TpTestsStubObjectClass;
+
+GType tp_tests_stub_object_get_type (void);
+
+#endif /* #ifndef __TP_TESTS_STUB_OBJECT_H__ */
diff --git a/tests/lib/telepathy/contactlist/textchan-group.c b/tests/lib/telepathy/contactlist/textchan-group.c
new file mode 100644
index 00000000..3b9b1797
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/textchan-group.c
@@ -0,0 +1,329 @@
+/*
+ * a stub anonymous MUC
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "textchan-group.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+static void password_iface_init (gpointer iface, gpointer data);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsTextChannelGroup,
+ tp_tests_text_channel_group, TP_TYPE_BASE_CHANNEL,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_TEXT,
+ tp_message_mixin_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
+ tp_group_mixin_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_PASSWORD,
+ password_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+ tp_dbus_properties_mixin_iface_init))
+
+static GPtrArray *
+text_channel_group_get_interfaces (TpBaseChannel *self)
+{
+ GPtrArray *interfaces;
+
+ interfaces = TP_BASE_CHANNEL_CLASS (
+ tp_tests_text_channel_group_parent_class)->get_interfaces (self);
+
+ g_ptr_array_add (interfaces, TP_IFACE_CHANNEL_INTERFACE_GROUP);
+ g_ptr_array_add (interfaces, TP_IFACE_CHANNEL_INTERFACE_PASSWORD);
+ return interfaces;
+};
+
+/* type definition stuff */
+
+struct _TpTestsTextChannelGroupPrivate
+{
+ gboolean closed;
+ gboolean disposed;
+
+ gchar *password;
+};
+
+
+static gboolean
+add_member (GObject *obj,
+ TpHandle handle,
+ const gchar *message,
+ GError **error)
+{
+ TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (obj);
+ TpIntset *add = tp_intset_new ();
+ GHashTable *details = tp_asv_new (
+ "actor", G_TYPE_UINT, tp_base_connection_get_self_handle (self->conn),
+ "change-reason", G_TYPE_UINT, TP_CHANNEL_GROUP_CHANGE_REASON_NONE,
+ "message", G_TYPE_STRING, message,
+ NULL);
+
+ tp_intset_add (add, handle);
+ tp_group_mixin_change_members (obj, add, NULL, NULL, NULL, details);
+ tp_intset_destroy (add);
+
+ g_hash_table_unref (details);
+
+ return TRUE;
+}
+
+static gboolean
+remove_with_reason (GObject *obj,
+ TpHandle handle,
+ const gchar *message,
+ guint reason,
+ GError **error)
+{
+ TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (obj);
+ TpGroupMixin *group = TP_GROUP_MIXIN (self);
+
+ tp_clear_pointer (&self->removed_message, g_free);
+
+ self->removed_handle = handle;
+ self->removed_message = g_strdup (message);
+ self->removed_reason = reason;
+
+ if (handle == group->self_handle)
+ {
+ /* User wants to leave */
+ if (!self->priv->closed)
+ {
+ self->priv->closed = TRUE;
+ tp_svc_channel_emit_closed (self);
+ }
+
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+static void
+tp_tests_text_channel_group_init (TpTestsTextChannelGroup *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ TP_TESTS_TYPE_TEXT_CHANNEL_GROUP, TpTestsTextChannelGroupPrivate);
+}
+
+static void
+text_send (GObject *object,
+ TpMessage *message,
+ TpMessageSendingFlags flags)
+{
+ /* silently swallow the message */
+ tp_message_mixin_sent (object, message, 0, "", NULL);
+}
+
+static void
+constructed (GObject *object)
+{
+ TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (object);
+ TpHandleRepoIface *contact_repo;
+ TpChannelGroupFlags flags = 0;
+ TpBaseChannel *base = TP_BASE_CHANNEL (self);
+ const TpChannelTextMessageType types[] = {
+ TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
+ TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION,
+ TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE,
+ };
+ const gchar * supported_content_types[] = {
+ "text/plain",
+ NULL
+ };
+
+ G_OBJECT_CLASS (tp_tests_text_channel_group_parent_class)->constructed (
+ object);
+
+ self->conn = tp_base_channel_get_connection (base);
+
+ contact_repo = tp_base_connection_get_handles (self->conn,
+ TP_HANDLE_TYPE_CONTACT);
+
+ tp_base_channel_register (base);
+
+ tp_message_mixin_init (object,
+ G_STRUCT_OFFSET (TpTestsTextChannelGroup, message),
+ self->conn);
+
+ tp_message_mixin_implement_sending (object,
+ text_send, G_N_ELEMENTS (types), types, 0, 0,
+ supported_content_types);
+
+ flags |= TP_CHANNEL_GROUP_FLAG_CAN_ADD;
+
+ tp_group_mixin_init (object, G_STRUCT_OFFSET (TpTestsTextChannelGroup, group),
+ contact_repo,
+ tp_base_connection_get_self_handle (self->conn));
+
+ tp_group_mixin_change_flags (object, flags, 0);
+}
+
+static void
+dispose (GObject *object)
+{
+ TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (object);
+
+ if (self->priv->disposed)
+ return;
+
+ self->priv->disposed = TRUE;
+
+ if (!self->priv->closed)
+ {
+ tp_svc_channel_emit_closed (self);
+ }
+
+ ((GObjectClass *) tp_tests_text_channel_group_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+ TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (object);
+
+ tp_message_mixin_finalize (object);
+ tp_group_mixin_finalize (object);
+
+ tp_clear_pointer (&self->priv->password, g_free);
+
+ ((GObjectClass *) tp_tests_text_channel_group_parent_class)->finalize (object);
+}
+
+static void
+channel_close (TpBaseChannel *base)
+{
+ TpTestsTextChannelGroup *self = TP_TESTS_TEXT_CHANNEL_GROUP (base);
+
+ if (!self->priv->closed)
+ {
+ self->priv->closed = TRUE;
+ tp_svc_channel_emit_closed (self);
+ }
+}
+
+static void
+tp_tests_text_channel_group_class_init (TpTestsTextChannelGroupClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ TpBaseChannelClass *base_class = (TpBaseChannelClass *) klass;
+
+ g_type_class_add_private (klass, sizeof (TpTestsTextChannelGroupPrivate));
+
+ object_class->constructed = constructed;
+ object_class->dispose = dispose;
+ object_class->finalize = finalize;
+
+ base_class->channel_type = TP_IFACE_CHANNEL_TYPE_TEXT;
+ base_class->target_handle_type = TP_HANDLE_TYPE_NONE;
+ base_class->get_interfaces = text_channel_group_get_interfaces;
+ base_class->close = channel_close;
+
+ tp_group_mixin_class_init (object_class,
+ G_STRUCT_OFFSET (TpTestsTextChannelGroupClass, group_class), add_member,
+ NULL);
+
+ tp_group_mixin_class_set_remove_with_reason_func (object_class,
+ remove_with_reason);
+
+ tp_group_mixin_class_allow_self_removal (object_class);
+
+ tp_dbus_properties_mixin_class_init (object_class,
+ G_STRUCT_OFFSET (TpTestsTextChannelGroupClass, dbus_properties_class));
+
+ tp_group_mixin_init_dbus_properties (object_class);
+
+ tp_message_mixin_init_dbus_properties (object_class);
+}
+
+void
+tp_tests_text_channel_group_join (TpTestsTextChannelGroup *self)
+{
+ TpIntset *add, *empty;
+ GHashTable *details = tp_asv_new (
+ "actor", G_TYPE_UINT, 0,
+ "change-reason", G_TYPE_UINT, 0,
+ "message", G_TYPE_STRING, "",
+ NULL);
+
+ /* Add ourself as a member */
+ add = tp_intset_new_containing (
+ tp_base_connection_get_self_handle (self->conn));
+ empty = tp_intset_new ();
+
+ tp_group_mixin_change_members ((GObject *) self, add, empty,
+ empty, empty, details);
+
+ tp_intset_destroy (add);
+ tp_intset_destroy (empty);
+ g_hash_table_unref (details);
+}
+
+void
+tp_tests_text_channel_set_password (TpTestsTextChannelGroup *self,
+ const gchar *password)
+{
+ gboolean pass_was_needed, pass_needed;
+
+ pass_was_needed = (self->priv->password != NULL);
+
+ tp_clear_pointer (&self->priv->password, g_free);
+
+ self->priv->password = g_strdup (password);
+
+ pass_needed = (self->priv->password != NULL);
+
+ if (pass_needed == pass_was_needed)
+ return;
+
+ if (pass_needed)
+ tp_svc_channel_interface_password_emit_password_flags_changed (self,
+ TP_CHANNEL_PASSWORD_FLAG_PROVIDE, 0);
+ else
+ tp_svc_channel_interface_password_emit_password_flags_changed (self,
+ 0, TP_CHANNEL_PASSWORD_FLAG_PROVIDE);
+}
+
+static void
+password_get_password_flags (TpSvcChannelInterfacePassword *chan,
+ DBusGMethodInvocation *context)
+{
+ TpTestsTextChannelGroup *self = (TpTestsTextChannelGroup *) chan;
+ TpChannelPasswordFlags flags = 0;
+
+ if (self->priv->password != NULL)
+ flags |= TP_CHANNEL_PASSWORD_FLAG_PROVIDE;
+
+ tp_svc_channel_interface_password_return_from_get_password_flags (context,
+ flags);
+}
+
+static void
+password_provide_password (TpSvcChannelInterfacePassword *chan,
+ const gchar *password,
+ DBusGMethodInvocation *context)
+{
+ TpTestsTextChannelGroup *self = (TpTestsTextChannelGroup *) chan;
+
+ tp_svc_channel_interface_password_return_from_provide_password (context,
+ !tp_strdiff (password, self->priv->password));
+}
+
+static void
+password_iface_init (gpointer iface, gpointer data)
+{
+ TpSvcChannelInterfacePasswordClass *klass = iface;
+
+#define IMPLEMENT(x) tp_svc_channel_interface_password_implement_##x (klass, password_##x)
+ IMPLEMENT (get_password_flags);
+ IMPLEMENT (provide_password);
+#undef IMPLEMENT
+}
diff --git a/tests/lib/telepathy/contactlist/textchan-group.h b/tests/lib/telepathy/contactlist/textchan-group.h
new file mode 100644
index 00000000..810e0048
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/textchan-group.h
@@ -0,0 +1,72 @@
+/*
+ * a stub anonymous MUC
+ *
+ * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TEST_TEXT_CHANNEL_GROUP_H__
+#define __TEST_TEXT_CHANNEL_GROUP_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsTextChannelGroup TpTestsTextChannelGroup;
+typedef struct _TpTestsTextChannelGroupClass TpTestsTextChannelGroupClass;
+typedef struct _TpTestsTextChannelGroupPrivate TpTestsTextChannelGroupPrivate;
+
+GType tp_tests_text_channel_group_get_type (void);
+
+#define TP_TESTS_TYPE_TEXT_CHANNEL_GROUP \
+ (tp_tests_text_channel_group_get_type ())
+#define TP_TESTS_TEXT_CHANNEL_GROUP(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_TEXT_CHANNEL_GROUP, \
+ TpTestsTextChannelGroup))
+#define TP_TESTS_TEXT_CHANNEL_GROUP_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_TEXT_CHANNEL_GROUP, \
+ TpTestsTextChannelGroupClass))
+#define TEST_IS_TEXT_CHANNEL_GROUP(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_TEXT_CHANNEL_GROUP))
+#define TEST_IS_TEXT_CHANNEL_GROUP_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_TEXT_CHANNEL_GROUP))
+#define TP_TESTS_TEXT_CHANNEL_GROUP_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_TEXT_CHANNEL_GROUP, \
+ TpTestsTextChannelGroupClass))
+
+struct _TpTestsTextChannelGroupClass {
+ TpBaseChannelClass parent_class;
+
+ TpGroupMixinClass group_class;
+ TpDBusPropertiesMixinClass dbus_properties_class;
+};
+
+struct _TpTestsTextChannelGroup {
+ TpBaseChannel parent;
+
+ TpBaseConnection *conn;
+
+ TpMessageMixin message;
+ TpGroupMixin group;
+
+ TpHandle removed_handle;
+ gchar *removed_message;
+ TpChannelGroupChangeReason removed_reason;
+
+ TpTestsTextChannelGroupPrivate *priv;
+};
+
+
+void tp_tests_text_channel_group_join (TpTestsTextChannelGroup *self);
+
+void tp_tests_text_channel_set_password (TpTestsTextChannelGroup *self,
+ const gchar *password);
+
+G_END_DECLS
+
+#endif /* #ifndef __TEST_TEXT_CHANNEL_GROUP_H__ */
diff --git a/tests/lib/telepathy/contactlist/textchan-null.c b/tests/lib/telepathy/contactlist/textchan-null.c
deleted file mode 100644
index bbeb0c71..00000000
--- a/tests/lib/telepathy/contactlist/textchan-null.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
- * /dev/null as a text channel
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * Copying and distribution of this file, with or without modification,
- * are permitted in any medium without royalty provided the copyright
- * notice and this notice are preserved.
- */
-
-#include "config.h"
-
-#include "textchan-null.h"
-
-#include <telepathy-glib/base-connection.h>
-#include <telepathy-glib/channel-iface.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/dbus-properties-mixin.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/svc-channel.h>
-#include <telepathy-glib/svc-generic.h>
-
-/* This is for text-mixin unit tests, others should be using ExampleEcho2Channel
- * which uses newer TpMessageMixin */
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-
-static void text_iface_init (gpointer iface, gpointer data);
-static void channel_iface_init (gpointer iface, gpointer data);
-
-G_DEFINE_TYPE_WITH_CODE (TpTestsTextChannelNull,
- tp_tests_text_channel_null,
- G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_TEXT, text_iface_init);
- G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL))
-
-G_DEFINE_TYPE_WITH_CODE (TpTestsPropsTextChannel,
- tp_tests_props_text_channel,
- TP_TESTS_TYPE_TEXT_CHANNEL_NULL,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
- tp_dbus_properties_mixin_iface_init))
-
-G_DEFINE_TYPE_WITH_CODE (TpTestsPropsGroupTextChannel,
- tp_tests_props_group_text_channel,
- TP_TESTS_TYPE_PROPS_TEXT_CHANNEL,
- G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_GROUP,
- tp_group_mixin_iface_init))
-
-static const char *tp_tests_text_channel_null_interfaces[] = { NULL };
-
-/* type definition stuff */
-
-enum
-{
- PROP_OBJECT_PATH = 1,
- PROP_CHANNEL_TYPE,
- PROP_HANDLE_TYPE,
- PROP_HANDLE,
- PROP_TARGET_ID,
- PROP_CONNECTION,
- PROP_INTERFACES,
- PROP_REQUESTED,
- PROP_INITIATOR_HANDLE,
- PROP_INITIATOR_ID,
- N_PROPS
-};
-
-struct _TpTestsTextChannelNullPrivate
-{
- TpBaseConnection *conn;
- gchar *object_path;
- TpHandle handle;
-
- unsigned closed:1;
- unsigned disposed:1;
-};
-
-static void
-tp_tests_text_channel_null_init (TpTestsTextChannelNull *self)
-{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
- TP_TESTS_TYPE_TEXT_CHANNEL_NULL, TpTestsTextChannelNullPrivate);
-}
-
-static void
-tp_tests_props_text_channel_init (TpTestsPropsTextChannel *self)
-{
- self->dbus_property_interfaces_retrieved = g_hash_table_new (NULL, NULL);
-}
-
-static GObject *
-constructor (GType type,
- guint n_props,
- GObjectConstructParam *props)
-{
- GObject *object =
- G_OBJECT_CLASS (tp_tests_text_channel_null_parent_class)->constructor (type,
- n_props, props);
- TpTestsTextChannelNull *self = TP_TESTS_TEXT_CHANNEL_NULL (object);
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles
- (self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- tp_handle_ref (contact_repo, self->priv->handle);
-
- tp_dbus_daemon_register_object (
- tp_base_connection_get_dbus_daemon (self->priv->conn),
- self->priv->object_path, self);
-
- tp_text_mixin_init (object, G_STRUCT_OFFSET (TpTestsTextChannelNull, text),
- contact_repo);
-
- tp_text_mixin_set_message_types (object,
- TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL,
- TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION,
- TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE,
- G_MAXUINT);
-
- return object;
-}
-
-static void
-get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- TpTestsTextChannelNull *self = TP_TESTS_TEXT_CHANNEL_NULL (object);
-
- switch (property_id)
- {
- case PROP_OBJECT_PATH:
- g_value_set_string (value, self->priv->object_path);
- break;
- case PROP_CHANNEL_TYPE:
- g_value_set_static_string (value, TP_IFACE_CHANNEL_TYPE_TEXT);
- break;
- case PROP_HANDLE_TYPE:
- g_value_set_uint (value, TP_HANDLE_TYPE_CONTACT);
- break;
- case PROP_HANDLE:
- g_value_set_uint (value, self->priv->handle);
- break;
- case PROP_TARGET_ID:
- {
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- g_value_set_string (value,
- tp_handle_inspect (contact_repo, self->priv->handle));
- }
- break;
- case PROP_REQUESTED:
- g_value_set_boolean (value, TRUE);
- break;
- case PROP_INITIATOR_HANDLE:
- g_value_set_uint (value, tp_base_connection_get_self_handle (
- self->priv->conn));
- break;
- case PROP_INITIATOR_ID:
- {
- TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
- self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- g_value_set_string (value,
- tp_handle_inspect (contact_repo,
- tp_base_connection_get_self_handle (self->priv->conn)));
- }
- break;
- case PROP_INTERFACES:
- g_value_set_boxed (value, tp_tests_text_channel_null_interfaces);
- break;
- case PROP_CONNECTION:
- g_value_set_object (value, self->priv->conn);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- TpTestsTextChannelNull *self = TP_TESTS_TEXT_CHANNEL_NULL (object);
-
- switch (property_id)
- {
- case PROP_OBJECT_PATH:
- g_free (self->priv->object_path);
- self->priv->object_path = g_value_dup_string (value);
- break;
- case PROP_HANDLE:
- /* we don't ref it here because we don't necessarily have access to the
- * contact repo yet - instead we ref it in the constructor.
- */
- self->priv->handle = g_value_get_uint (value);
- break;
- case PROP_HANDLE_TYPE:
- 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:
- self->priv->conn = g_value_get_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-void
-tp_tests_text_channel_null_close (TpTestsTextChannelNull *self)
-{
- if (!self->priv->closed)
- {
- self->priv->closed = TRUE;
- tp_svc_channel_emit_closed (self);
- tp_dbus_daemon_unregister_object (
- tp_base_connection_get_dbus_daemon (self->priv->conn), self);
- }
-}
-
-static void
-dispose (GObject *object)
-{
- TpTestsTextChannelNull *self = TP_TESTS_TEXT_CHANNEL_NULL (object);
-
- if (self->priv->disposed)
- return;
-
- self->priv->disposed = TRUE;
- tp_tests_text_channel_null_close (self);
-
- ((GObjectClass *) tp_tests_text_channel_null_parent_class)->dispose (object);
-}
-
-static void
-finalize (GObject *object)
-{
- TpTestsTextChannelNull *self = TP_TESTS_TEXT_CHANNEL_NULL (object);
- TpHandleRepoIface *contact_handles = tp_base_connection_get_handles
- (self->priv->conn, TP_HANDLE_TYPE_CONTACT);
-
- tp_handle_unref (contact_handles, self->priv->handle);
- g_free (self->priv->object_path);
-
- tp_text_mixin_finalize (object);
-
- ((GObjectClass *) tp_tests_text_channel_null_parent_class)->finalize (object);
-}
-
-static void
-tp_tests_text_channel_null_class_init (TpTestsTextChannelNullClass *klass)
-{
- GObjectClass *object_class = (GObjectClass *) klass;
- GParamSpec *param_spec;
-
- g_type_class_add_private (klass, sizeof (TpTestsTextChannelNullPrivate));
-
- object_class->constructor = constructor;
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->dispose = dispose;
- object_class->finalize = 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");
-
- param_spec = g_param_spec_object ("connection", "TpBaseConnection object",
- "Connection object that owns this channel",
- TP_TYPE_BASE_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_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 ("target-id", "Peer's ID",
- "The string obtained by inspecting the target handle",
- 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 ("initiator-handle", "Initiator's handle",
- "The contact who initiated the channel",
- 0, G_MAXUINT32, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIATOR_HANDLE,
- param_spec);
-
- param_spec = g_param_spec_string ("initiator-id", "Initiator's ID",
- "The string obtained by inspecting the initiator-handle",
- NULL,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_INITIATOR_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);
-
- tp_text_mixin_class_init (object_class,
- G_STRUCT_OFFSET (TpTestsTextChannelNullClass, text_class));
-}
-
-static void
-tp_tests_props_text_channel_getter_gobject_properties (GObject *object,
- GQuark interface,
- GQuark name,
- GValue *value,
- gpointer getter_data)
-{
- TpTestsPropsTextChannel *self = TP_TESTS_PROPS_TEXT_CHANNEL (object);
-
- g_hash_table_insert (self->dbus_property_interfaces_retrieved,
- GUINT_TO_POINTER (interface), GUINT_TO_POINTER (interface));
-
- tp_dbus_properties_mixin_getter_gobject_properties (object, interface, name,
- value, getter_data);
-}
-
-static void
-props_finalize (GObject *object)
-{
- TpTestsPropsTextChannel *self = TP_TESTS_PROPS_TEXT_CHANNEL (object);
-
- g_hash_table_unref (self->dbus_property_interfaces_retrieved);
-
- ((GObjectClass *) tp_tests_props_text_channel_parent_class)->finalize (object);
-}
-
-static void
-tp_tests_props_text_channel_class_init (TpTestsPropsTextChannelClass *klass)
-{
- GObjectClass *object_class = (GObjectClass *) klass;
- static TpDBusPropertiesMixinPropImpl channel_props[] = {
- { "TargetHandleType", "handle-type", NULL },
- { "TargetHandle", "handle", NULL },
- { "ChannelType", "channel-type", NULL },
- { "Interfaces", "interfaces", NULL },
- { "TargetID", "target-id", NULL },
- { "Requested", "requested", NULL },
- { "InitiatorHandle", "initiator-handle", NULL },
- { "InitiatorID", "initiator-id", NULL },
- { NULL }
- };
- static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
- { TP_IFACE_CHANNEL,
- tp_tests_props_text_channel_getter_gobject_properties,
- NULL,
- channel_props,
- },
- { NULL }
- };
-
- object_class->finalize = props_finalize;
-
- klass->dbus_properties_class.interfaces = prop_interfaces;
- tp_dbus_properties_mixin_class_init (object_class,
- G_STRUCT_OFFSET (TpTestsPropsTextChannelClass, dbus_properties_class));
-}
-
-static void
-tp_tests_props_group_text_channel_init (TpTestsPropsGroupTextChannel *self)
-{
-}
-
-static void
-group_constructed (GObject *self)
-{
- TpBaseConnection *conn = TP_TESTS_TEXT_CHANNEL_NULL (self)->priv->conn;
- void (*chain_up) (GObject *) =
- ((GObjectClass *) tp_tests_props_group_text_channel_parent_class)->constructed;
-
- if (chain_up != NULL)
- chain_up (self);
-
- tp_group_mixin_init (self,
- G_STRUCT_OFFSET (TpTestsPropsGroupTextChannel, group),
- tp_base_connection_get_handles (conn, TP_HANDLE_TYPE_CONTACT),
- tp_base_connection_get_self_handle (conn));
- tp_group_mixin_change_flags (self, TP_CHANNEL_GROUP_FLAG_PROPERTIES, 0);
-}
-
-static void
-group_finalize (GObject *self)
-{
- tp_group_mixin_finalize (self);
-
- ((GObjectClass *) tp_tests_props_group_text_channel_parent_class)->finalize (self);
-}
-
-static gboolean
-dummy_add_remove_member (GObject *obj,
- TpHandle handle,
- const gchar *message,
- GError **error)
-{
- return TRUE;
-}
-
-static void
-group_iface_props_getter (GObject *object,
- GQuark interface,
- GQuark name,
- GValue *value,
- gpointer getter_data)
-{
- TpTestsPropsTextChannel *self = TP_TESTS_PROPS_TEXT_CHANNEL (object);
-
- g_hash_table_insert (self->dbus_property_interfaces_retrieved,
- GUINT_TO_POINTER (interface), GUINT_TO_POINTER (interface));
-
- tp_group_mixin_get_dbus_property (object, interface, name, value, getter_data);
-}
-
-static void
-tp_tests_props_group_text_channel_class_init (TpTestsPropsGroupTextChannelClass *klass)
-{
- GObjectClass *object_class = (GObjectClass *) klass;
- static TpDBusPropertiesMixinPropImpl group_props[] = {
- { "GroupFlags", NULL, NULL },
- { "HandleOwners", NULL, NULL },
- { "LocalPendingMembers", NULL, NULL },
- { "Members", NULL, NULL },
- { "RemotePendingMembers", NULL, NULL },
- { "SelfHandle", NULL, NULL },
- { NULL }
- };
-
- object_class->constructed = group_constructed;
- object_class->finalize = group_finalize;
-
- tp_group_mixin_class_init (object_class,
- G_STRUCT_OFFSET (TpTestsPropsGroupTextChannelClass, group_class),
- dummy_add_remove_member,
- dummy_add_remove_member);
- tp_dbus_properties_mixin_implement_interface (object_class,
- TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP, group_iface_props_getter, NULL,
- group_props);
-}
-
-static void
-channel_close (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- TpTestsTextChannelNull *self = TP_TESTS_TEXT_CHANNEL_NULL (iface);
-
- tp_tests_text_channel_null_close (self);
- tp_svc_channel_return_from_close (context);
-}
-
-static void
-channel_get_channel_type (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- TpTestsTextChannelNull *self = TP_TESTS_TEXT_CHANNEL_NULL (iface);
-
- self->get_channel_type_called++;
-
- tp_svc_channel_return_from_get_channel_type (context,
- TP_IFACE_CHANNEL_TYPE_TEXT);
-}
-
-static void
-channel_get_handle (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- TpTestsTextChannelNull *self = TP_TESTS_TEXT_CHANNEL_NULL (iface);
-
- self->get_handle_called++;
-
- tp_svc_channel_return_from_get_handle (context, TP_HANDLE_TYPE_CONTACT,
- self->priv->handle);
-}
-
-static void
-channel_get_interfaces (TpSvcChannel *iface,
- DBusGMethodInvocation *context)
-{
- TpTestsTextChannelNull *self = TP_TESTS_TEXT_CHANNEL_NULL (iface);
-
- self->get_interfaces_called++;
-
- tp_svc_channel_return_from_get_interfaces (context,
- tp_tests_text_channel_null_interfaces);
-}
-
-static void
-channel_iface_init (gpointer iface,
- gpointer data)
-{
- TpSvcChannelClass *klass = iface;
-
-#define IMPLEMENT(x) tp_svc_channel_implement_##x (klass, channel_##x)
- IMPLEMENT (close);
- IMPLEMENT (get_channel_type);
- IMPLEMENT (get_handle);
- IMPLEMENT (get_interfaces);
-#undef IMPLEMENT
-}
-
-static void
-text_send (TpSvcChannelTypeText *iface,
- guint type,
- const gchar *text,
- DBusGMethodInvocation *context)
-{
- /* silently swallow the message */
- tp_svc_channel_type_text_return_from_send (context);
-}
-
-static void
-text_iface_init (gpointer iface,
- gpointer data)
-{
- TpSvcChannelTypeTextClass *klass = iface;
-
- tp_text_mixin_iface_init (iface, data);
-#define IMPLEMENT(x) tp_svc_channel_type_text_implement_##x (klass, text_##x)
- IMPLEMENT (send);
-#undef IMPLEMENT
-}
-
-GHashTable *
-tp_tests_text_channel_get_props (TpTestsTextChannelNull *self)
-{
- GHashTable *props;
- TpHandleType handle_type;
- TpHandle handle;
- gchar *target_id;
- gboolean requested;
- TpHandle initiator_handle;
- gchar *initiator_id;
- GStrv interfaces;
-
- g_object_get (self,
- "handle-type", &handle_type,
- "handle", &handle,
- "target-id", &target_id,
- "requested", &requested,
- "initiator-handle", &initiator_handle,
- "initiator-id", &initiator_id,
- "interfaces", &interfaces,
- NULL);
-
- props = tp_asv_new (
- TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT,
- TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, G_TYPE_UINT, handle_type,
- TP_PROP_CHANNEL_TARGET_HANDLE, G_TYPE_UINT, handle,
- TP_PROP_CHANNEL_TARGET_ID, G_TYPE_STRING, target_id,
- TP_PROP_CHANNEL_REQUESTED, G_TYPE_BOOLEAN, requested,
- TP_PROP_CHANNEL_INITIATOR_HANDLE, G_TYPE_UINT, initiator_handle,
- TP_PROP_CHANNEL_INITIATOR_ID, G_TYPE_STRING, initiator_id,
- TP_PROP_CHANNEL_INTERFACES, G_TYPE_STRV, interfaces,
- NULL);
-
- g_free (target_id);
- g_free (initiator_id);
- g_strfreev (interfaces);
- return props;
-}
-
-G_GNUC_END_IGNORE_DEPRECATIONS
diff --git a/tests/lib/telepathy/contactlist/textchan-null.h b/tests/lib/telepathy/contactlist/textchan-null.h
deleted file mode 100644
index 583bec57..00000000
--- a/tests/lib/telepathy/contactlist/textchan-null.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * /dev/null as a text channel
- *
- * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
- * Copyright (C) 2008 Nokia Corporation
- *
- * Copying and distribution of this file, with or without modification,
- * are permitted in any medium without royalty provided the copyright
- * notice and this notice are preserved.
- */
-
-#ifndef __TP_TESTS_TEXT_CHANNEL_NULL_H__
-#define __TP_TESTS_TEXT_CHANNEL_NULL_H__
-
-#include <glib-object.h>
-#include <telepathy-glib/base-connection.h>
-#include <telepathy-glib/text-mixin.h>
-#include <telepathy-glib/group-mixin.h>
-
-G_BEGIN_DECLS
-
-typedef struct _TpTestsTextChannelNull TpTestsTextChannelNull;
-typedef struct _TpTestsTextChannelNullClass TpTestsTextChannelNullClass;
-typedef struct _TpTestsTextChannelNullPrivate TpTestsTextChannelNullPrivate;
-
-GType tp_tests_text_channel_null_get_type (void);
-
-#define TP_TESTS_TYPE_TEXT_CHANNEL_NULL \
- (tp_tests_text_channel_null_get_type ())
-#define TP_TESTS_TEXT_CHANNEL_NULL(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_TEXT_CHANNEL_NULL, \
- TpTestsTextChannelNull))
-#define TP_TESTS_TEXT_CHANNEL_NULL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_TEXT_CHANNEL_NULL, \
- TpTestsTextChannelNullClass))
-#define TP_TESTS_IS_TEXT_CHANNEL_NULL(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_TEXT_CHANNEL_NULL))
-#define TP_TESTS_IS_TEXT_CHANNEL_NULL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_TEXT_CHANNEL_NULL))
-#define TP_TESTS_TEXT_CHANNEL_NULL_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_TEXT_CHANNEL_NULL, \
- TpTestsTextChannelNullClass))
-
-struct _TpTestsTextChannelNullClass {
- GObjectClass parent_class;
-
- TpTextMixinClass text_class;
-};
-
-struct _TpTestsTextChannelNull {
- GObject parent;
- TpTextMixin text;
-
- guint get_handle_called;
- guint get_interfaces_called;
- guint get_channel_type_called;
-
- TpTestsTextChannelNullPrivate *priv;
-};
-
-/* Subclass with D-Bus properties */
-
-typedef struct _TestPropsTextChannel TpTestsPropsTextChannel;
-typedef struct _TestPropsTextChannelClass TpTestsPropsTextChannelClass;
-
-struct _TestPropsTextChannel {
- TpTestsTextChannelNull parent;
-
- GHashTable *dbus_property_interfaces_retrieved;
-};
-
-struct _TestPropsTextChannelClass {
- TpTestsTextChannelNullClass parent;
-
- TpDBusPropertiesMixinClass dbus_properties_class;
-};
-
-GType tp_tests_props_text_channel_get_type (void);
-
-#define TP_TESTS_TYPE_PROPS_TEXT_CHANNEL \
- (tp_tests_props_text_channel_get_type ())
-#define TP_TESTS_PROPS_TEXT_CHANNEL(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_PROPS_TEXT_CHANNEL, \
- TpTestsPropsTextChannel))
-#define TP_TESTS_PROPS_TEXT_CHANNEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_PROPS_TEXT_CHANNEL, \
- TpTestsPropsTextChannelClass))
-#define TP_TESTS_IS_PROPS_TEXT_CHANNEL(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_PROPS_TEXT_CHANNEL))
-#define TP_TESTS_IS_PROPS_TEXT_CHANNEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_PROPS_TEXT_CHANNEL))
-#define TP_TESTS_PROPS_TEXT_CHANNEL_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_PROPS_TEXT_CHANNEL, \
- TpTestsPropsTextChannelClass))
-
-/* Subclass with D-Bus properties and Group */
-
-typedef struct _TestPropsGroupTextChannel TpTestsPropsGroupTextChannel;
-typedef struct _TestPropsGroupTextChannelClass TpTestsPropsGroupTextChannelClass;
-
-struct _TestPropsGroupTextChannel {
- TpTestsPropsTextChannel parent;
-
- TpGroupMixin group;
-};
-
-struct _TestPropsGroupTextChannelClass {
- TpTestsPropsTextChannelClass parent;
-
- TpGroupMixinClass group_class;
-};
-
-GType tp_tests_props_group_text_channel_get_type (void);
-
-#define TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL \
- (tp_tests_props_group_text_channel_get_type ())
-#define TP_TESTS_PROPS_GROUP_TEXT_CHANNEL(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL, \
- TpTestsPropsGroupTextChannel))
-#define TP_TESTS_PROPS_GROUP_TEXT_CHANNEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL, \
- TpTestsPropsGroupTextChannelClass))
-#define TP_TESTS_IS_PROPS_GROUP_TEXT_CHANNEL(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL))
-#define TP_TESTS_IS_PROPS_GROUP_TEXT_CHANNEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL))
-#define TP_TESTS_PROPS_GROUP_TEXT_CHANNEL_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_PROPS_GROUP_TEXT_CHANNEL, \
- TpTestsPropsGroupTextChannelClass))
-
-void tp_tests_text_channel_null_close (TpTestsTextChannelNull *self);
-
-GHashTable * tp_tests_text_channel_get_props (TpTestsTextChannelNull *self);
-
-G_END_DECLS
-
-#endif /* #ifndef __TP_TESTS_TEXT_CHANNEL_NULL_H__ */
diff --git a/tests/lib/telepathy/contactlist/tls-certificate.c b/tests/lib/telepathy/contactlist/tls-certificate.c
new file mode 100644
index 00000000..0da16456
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/tls-certificate.c
@@ -0,0 +1,350 @@
+/*
+ * tls-certificate.c - Source for TpTestsTLSCertificate
+ * Copyright (C) 2010 Collabora Ltd.
+ * @author Cosimo Cecchi <cosimo.cecchi@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 "tls-certificate.h"
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#define DEBUG_FLAG TP_TESTS_DEBUG_TLS
+#include "debug.h"
+
+static void
+tls_certificate_iface_init (gpointer g_iface, gpointer iface_data);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsTLSCertificate,
+ tp_tests_tls_certificate,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_AUTHENTICATION_TLS_CERTIFICATE,
+ tls_certificate_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+ tp_dbus_properties_mixin_iface_init);)
+
+struct _TpTestsTLSCertificatePrivate {
+ gchar *object_path;
+
+ gchar *cert_type;
+ TpTLSCertificateState cert_state;
+
+ GPtrArray *rejections;
+ GPtrArray *cert_data;
+
+ TpDBusDaemon *daemon;
+
+ gboolean dispose_has_run;
+};
+
+enum {
+ PROP_OBJECT_PATH = 1,
+ PROP_STATE,
+ PROP_REJECTIONS,
+ PROP_CERTIFICATE_TYPE,
+ PROP_CERTIFICATE_CHAIN_DATA,
+
+ /* not exported */
+ PROP_DBUS_DAEMON,
+
+ NUM_PROPERTIES
+};
+
+static void
+tp_tests_tls_certificate_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsTLSCertificate *self = TP_TESTS_TLS_CERTIFICATE (object);
+
+ switch (property_id)
+ {
+ case PROP_OBJECT_PATH:
+ g_value_set_string (value, self->priv->object_path);
+ break;
+ case PROP_STATE:
+ g_value_set_uint (value, self->priv->cert_state);
+ break;
+ case PROP_REJECTIONS:
+ g_value_set_boxed (value, self->priv->rejections);
+ break;
+ case PROP_CERTIFICATE_TYPE:
+ g_value_set_string (value, self->priv->cert_type);
+ break;
+ case PROP_CERTIFICATE_CHAIN_DATA:
+ g_value_set_boxed (value, self->priv->cert_data);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+tp_tests_tls_certificate_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsTLSCertificate *self = TP_TESTS_TLS_CERTIFICATE (object);
+
+ switch (property_id)
+ {
+ case PROP_OBJECT_PATH:
+ self->priv->object_path = g_value_dup_string (value);
+ break;
+ case PROP_CERTIFICATE_TYPE:
+ self->priv->cert_type = g_value_dup_string (value);
+ break;
+ case PROP_CERTIFICATE_CHAIN_DATA:
+ self->priv->cert_data = g_value_dup_boxed (value);
+ break;
+ case PROP_DBUS_DAEMON:
+ self->priv->daemon = g_value_dup_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, value);
+ break;
+ }
+}
+
+static void
+tp_tests_tls_certificate_finalize (GObject *object)
+{
+ TpTestsTLSCertificate *self = TP_TESTS_TLS_CERTIFICATE (object);
+
+ tp_clear_boxed (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
+ &self->priv->rejections);
+
+ g_free (self->priv->object_path);
+ g_free (self->priv->cert_type);
+ g_ptr_array_unref (self->priv->cert_data);
+
+ G_OBJECT_CLASS (tp_tests_tls_certificate_parent_class)->finalize (object);
+}
+
+static void
+tp_tests_tls_certificate_dispose (GObject *object)
+{
+ TpTestsTLSCertificate *self = TP_TESTS_TLS_CERTIFICATE (object);
+
+ if (self->priv->dispose_has_run)
+ return;
+
+ self->priv->dispose_has_run = TRUE;
+
+ tp_clear_object (&self->priv->daemon);
+
+ G_OBJECT_CLASS (tp_tests_tls_certificate_parent_class)->dispose (object);
+}
+
+static void
+tp_tests_tls_certificate_constructed (GObject *object)
+{
+ TpTestsTLSCertificate *self = TP_TESTS_TLS_CERTIFICATE (object);
+ void (*chain_up) (GObject *) =
+ G_OBJECT_CLASS (tp_tests_tls_certificate_parent_class)->constructed;
+
+ if (chain_up != NULL)
+ chain_up (object);
+
+ /* register the certificate on the bus */
+ tp_dbus_daemon_register_object (self->priv->daemon,
+ self->priv->object_path, self);
+}
+
+static void
+tp_tests_tls_certificate_init (TpTestsTLSCertificate *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ TP_TESTS_TYPE_TLS_CERTIFICATE, TpTestsTLSCertificatePrivate);
+ self->priv->rejections = g_ptr_array_new ();
+}
+
+static void
+tp_tests_tls_certificate_class_init (TpTestsTLSCertificateClass *klass)
+{
+ static TpDBusPropertiesMixinPropImpl object_props[] = {
+ { "State", "state", NULL },
+ { "Rejections", "rejections", NULL },
+ { "CertificateType", "certificate-type", NULL },
+ { "CertificateChainData", "certificate-chain-data", NULL },
+ { NULL }
+ };
+ static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+ { TP_IFACE_AUTHENTICATION_TLS_CERTIFICATE,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ object_props,
+ },
+ { NULL }
+ };
+ GObjectClass *oclass = G_OBJECT_CLASS (klass);
+ GParamSpec *pspec;
+
+ g_type_class_add_private (klass, sizeof (TpTestsTLSCertificatePrivate));
+
+ oclass->finalize = tp_tests_tls_certificate_finalize;
+ oclass->dispose = tp_tests_tls_certificate_dispose;
+ oclass->set_property = tp_tests_tls_certificate_set_property;
+ oclass->get_property = tp_tests_tls_certificate_get_property;
+ oclass->constructed = tp_tests_tls_certificate_constructed;
+
+ pspec = 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_STRINGS);
+ g_object_class_install_property (oclass, PROP_OBJECT_PATH, pspec);
+
+ pspec = g_param_spec_uint ("state",
+ "State of this certificate",
+ "The state of this TLS certificate.",
+ 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);
+
+ pspec = g_param_spec_boxed ("rejections",
+ "The reject reasons",
+ "The reasons why this TLS certificate has been rejected",
+ TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (oclass, PROP_REJECTIONS, pspec);
+
+ pspec = g_param_spec_string ("certificate-type",
+ "The certificate type",
+ "The type of this certificate.",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (oclass, PROP_CERTIFICATE_TYPE, pspec);
+
+ pspec = g_param_spec_boxed ("certificate-chain-data",
+ "The certificate chain data",
+ "The raw PEM-encoded trust chain of this certificate.",
+ TP_ARRAY_TYPE_UCHAR_ARRAY_LIST,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (oclass, PROP_CERTIFICATE_CHAIN_DATA, pspec);
+
+ pspec = g_param_spec_object ("dbus-daemon",
+ "The DBus daemon connection",
+ "The connection to the DBus daemon owning the CM",
+ TP_TYPE_DBUS_DAEMON,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (oclass, PROP_DBUS_DAEMON, pspec);
+
+ klass->dbus_props_class.interfaces = prop_interfaces;
+ tp_dbus_properties_mixin_class_init (oclass,
+ G_STRUCT_OFFSET (TpTestsTLSCertificateClass, dbus_props_class));
+}
+
+static void
+tp_tests_tls_certificate_accept (TpSvcAuthenticationTLSCertificate *cert,
+ DBusGMethodInvocation *context)
+{
+ TpTestsTLSCertificate *self = TP_TESTS_TLS_CERTIFICATE (cert);
+
+ DEBUG ("Accept() called on the TLS certificate; current state %u",
+ self->priv->cert_state);
+
+ if (self->priv->cert_state != TP_TLS_CERTIFICATE_STATE_PENDING)
+ {
+ GError error =
+ { TP_ERROR,
+ TP_ERROR_INVALID_ARGUMENT,
+ "Calling Accept() on a certificate with state != PENDING "
+ "doesn't make sense."
+ };
+
+ dbus_g_method_return_error (context, &error);
+ return;
+ }
+
+ self->priv->cert_state = TP_TLS_CERTIFICATE_STATE_ACCEPTED;
+ tp_svc_authentication_tls_certificate_emit_accepted (self);
+
+ tp_svc_authentication_tls_certificate_return_from_accept (context);
+}
+
+static void
+tp_tests_tls_certificate_reject (TpSvcAuthenticationTLSCertificate *cert,
+ const GPtrArray *rejections,
+ DBusGMethodInvocation *context)
+{
+ TpTestsTLSCertificate *self = TP_TESTS_TLS_CERTIFICATE (cert);
+
+ DEBUG ("Reject() called on the TLS certificate with rejections %p, "
+ "length %u; current state %u", rejections, rejections->len,
+ self->priv->cert_state);
+
+ if (rejections->len < 1)
+ {
+ GError error = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT,
+ "Calling Reject() with a zero-length rejection list." };
+
+ dbus_g_method_return_error (context, &error);
+ return;
+ }
+
+ if (self->priv->cert_state != TP_TLS_CERTIFICATE_STATE_PENDING)
+ {
+ GError error =
+ { TP_ERROR,
+ TP_ERROR_INVALID_ARGUMENT,
+ "Calling Reject() on a certificate with state != PENDING "
+ "doesn't make sense."
+ };
+
+ dbus_g_method_return_error (context, &error);
+ return;
+ }
+
+ tp_clear_boxed (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
+ &self->priv->rejections);
+
+ self->priv->rejections =
+ g_boxed_copy (TP_ARRAY_TYPE_TLS_CERTIFICATE_REJECTION_LIST,
+ rejections);
+ self->priv->cert_state = TP_TLS_CERTIFICATE_STATE_REJECTED;
+
+ tp_svc_authentication_tls_certificate_emit_rejected (
+ self, self->priv->rejections);
+
+ tp_svc_authentication_tls_certificate_return_from_reject (context);
+}
+
+static void
+tls_certificate_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ TpSvcAuthenticationTLSCertificateClass *klass = g_iface;
+
+#define IMPLEMENT(x) \
+ tp_svc_authentication_tls_certificate_implement_##x ( \
+ klass, tp_tests_tls_certificate_##x)
+ IMPLEMENT (accept);
+ IMPLEMENT (reject);
+#undef IMPLEMENT
+}
+
+void
+tp_tests_tls_certificate_clear_rejection (TpTestsTLSCertificate *self)
+{
+ g_ptr_array_set_size (self->priv->rejections, 0);
+}
diff --git a/tests/lib/telepathy/contactlist/tls-certificate.h b/tests/lib/telepathy/contactlist/tls-certificate.h
new file mode 100644
index 00000000..1de31927
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/tls-certificate.h
@@ -0,0 +1,68 @@
+/*
+ * tls-certificate.h - Header for TpTestsTLSCertificate
+ * Copyright (C) 2010 Collabora Ltd.
+ * @author Cosimo Cecchi <cosimo.cecchi@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
+ */
+
+#ifndef __TP_TESTS_TLS_CERTIFICATE_H__
+#define __TP_TESTS_TLS_CERTIFICATE_H__
+
+#include <glib-object.h>
+
+#include <telepathy-glib/telepathy-glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsTLSCertificate TpTestsTLSCertificate;
+typedef struct _TpTestsTLSCertificateClass TpTestsTLSCertificateClass;
+typedef struct _TpTestsTLSCertificatePrivate TpTestsTLSCertificatePrivate;
+
+struct _TpTestsTLSCertificateClass {
+ GObjectClass parent_class;
+
+ TpDBusPropertiesMixinClass dbus_props_class;
+};
+
+struct _TpTestsTLSCertificate {
+ GObject parent;
+
+ TpTestsTLSCertificatePrivate *priv;
+};
+
+GType tp_tests_tls_certificate_get_type (void);
+
+#define TP_TESTS_TYPE_TLS_CERTIFICATE \
+ (tp_tests_tls_certificate_get_type ())
+#define TP_TESTS_TLS_CERTIFICATE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_TLS_CERTIFICATE, \
+ TpTestsTLSCertificate))
+#define TP_TESTS_TLS_CERTIFICATE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_TLS_CERTIFICATE, \
+ TpTestsTLSCertificateClass))
+#define TP_TESTS_IS_TLS_CERTIFICATE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_TLS_CERTIFICATE))
+#define TP_TESTS_IS_TLS_CERTIFICATE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_TLS_CERTIFICATE))
+#define TP_TESTS_TLS_CERTIFICATE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_TLS_CERTIFICATE, \
+ TpTestsTLSCertificateClass))
+
+void tp_tests_tls_certificate_clear_rejection (TpTestsTLSCertificate *self);
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_TLS_CERTIFICATE_H__*/
diff --git a/tests/lib/telepathy/contactlist/tp-test-contactlist.deps b/tests/lib/telepathy/contactlist/tp-test-contactlist.deps
index 0d850c28..6e998cee 100644
--- a/tests/lib/telepathy/contactlist/tp-test-contactlist.deps
+++ b/tests/lib/telepathy/contactlist/tp-test-contactlist.deps
@@ -2,4 +2,4 @@ gio-2.0
dbus-glib-1
gobject-2.0
gio-2.0
-telepathy-glib
+telepathy-glib-1
diff --git a/tests/lib/telepathy/contactlist/util.c b/tests/lib/telepathy/contactlist/util.c
index 21d38550..792afb9b 100644
--- a/tests/lib/telepathy/contactlist/util.c
+++ b/tests/lib/telepathy/contactlist/util.c
@@ -12,7 +12,8 @@
#include "util.h"
-#include <telepathy-glib/connection.h>
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
#include <glib/gstdio.h>
#include <string.h>
@@ -176,6 +177,26 @@ _tp_tests_assert_strv_equals (const char *file,
}
void
+_tp_tests_assert_bytes_equal (const gchar *file, int line,
+ GBytes *actual, gconstpointer expected_data,
+ gsize expected_length)
+{
+ if (expected_length != g_bytes_get_size (actual))
+ {
+ g_error ("%s:%d: assertion failed: expected %"G_GSIZE_FORMAT
+ " bytes, got %"G_GSIZE_FORMAT,
+ file, line, expected_length, g_bytes_get_size (actual));
+ }
+ else if (memcmp (g_bytes_get_data (actual, NULL),
+ expected_data, expected_length) != 0)
+ {
+ g_error (
+ "%s:%d: assertion failed: expected data didn't match the actual data",
+ file, line);
+ }
+}
+
+void
tp_tests_create_conn (GType conn_type,
const gchar *account,
gboolean connect,
@@ -183,7 +204,6 @@ tp_tests_create_conn (GType conn_type,
TpConnection **client_conn)
{
TpDBusDaemon *dbus;
- TpSimpleClientFactory *factory;
gchar *name;
gchar *conn_path;
GError *error = NULL;
@@ -192,7 +212,6 @@ tp_tests_create_conn (GType conn_type,
g_assert (client_conn != NULL);
dbus = tp_tests_dbus_daemon_dup_or_die ();
- factory = (TpSimpleClientFactory *) tp_automatic_client_factory_new (dbus);
*service_conn = tp_tests_object_new_static_class (
conn_type,
@@ -205,8 +224,7 @@ tp_tests_create_conn (GType conn_type,
&name, &conn_path, &error));
g_assert_no_error (error);
- *client_conn = tp_simple_client_factory_ensure_connection (factory,
- conn_path, NULL, &error);
+ *client_conn = tp_tests_connection_new (dbus, NULL, conn_path, &error);
g_assert (*client_conn != NULL);
g_assert_no_error (error);
@@ -222,7 +240,6 @@ tp_tests_create_conn (GType conn_type,
g_free (conn_path);
g_object_unref (dbus);
- g_object_unref (factory);
}
void
@@ -318,6 +335,7 @@ _tp_create_local_socket (TpSocketAddressType address_type,
TpSocketAccessControl access_control,
GSocketService **service,
gchar **unix_address,
+ gchar **unix_tmpdir,
GError **error)
{
gboolean success;
@@ -343,7 +361,20 @@ _tp_create_local_socket (TpSocketAddressType address_type,
#ifdef HAVE_GIO_UNIX
case TP_SOCKET_ADDRESS_TYPE_UNIX:
{
- address = g_unix_socket_address_new (tmpnam (NULL));
+ GError *e = NULL;
+ gchar *dir = g_dir_make_tmp ("tp-glib-tests.XXXXXX", &e);
+ gchar *name;
+
+ g_assert_no_error (e);
+
+ name = g_build_filename (dir, "s", NULL);
+ address = g_unix_socket_address_new (name);
+ g_free (name);
+
+ if (unix_tmpdir != NULL)
+ *unix_tmpdir = dir;
+ else
+ g_free (dir);
break;
}
#endif
@@ -450,12 +481,11 @@ one_contact_cb (GObject *object,
TpContact *
tp_tests_connection_run_until_contact_by_id (TpConnection *connection,
const gchar *id,
- guint n_features,
- const TpContactFeature *features)
+ const GQuark *features)
{
TpContact *contact = NULL;
- tp_connection_dup_contact_by_id_async (connection, id, n_features, features,
+ tp_connection_dup_contact_by_id_async (connection, id, features,
one_contact_cb, &contact);
while (contact == NULL)
@@ -463,3 +493,160 @@ tp_tests_connection_run_until_contact_by_id (TpConnection *connection,
return contact;
}
+
+void
+tp_tests_channel_assert_expect_members (TpChannel *channel,
+ TpIntset *expected_members)
+{
+ GPtrArray *contacts;
+ TpIntset *members;
+ guint i;
+
+ members = tp_intset_new ();
+ contacts = tp_channel_group_dup_members (channel);
+ if (contacts != NULL)
+ {
+ for (i = 0; i < contacts->len; i++)
+ {
+ TpContact *contact = g_ptr_array_index (contacts, i);
+ tp_intset_add (members, tp_contact_get_handle (contact));
+ }
+ }
+
+ g_assert (tp_intset_is_equal (members, expected_members));
+
+ g_ptr_array_unref (contacts);
+ tp_intset_destroy (members);
+}
+
+TpConnection *
+tp_tests_connection_new (TpDBusDaemon *dbus,
+ const gchar *bus_name,
+ const gchar *object_path,
+ GError **error)
+{
+ TpClientFactory *factory;
+ gchar *dup_path = NULL;
+ TpConnection *ret = NULL;
+
+ g_return_val_if_fail (TP_IS_DBUS_DAEMON (dbus), NULL);
+ g_return_val_if_fail (object_path != NULL ||
+ (bus_name != NULL && bus_name[0] != ':'), NULL);
+
+ if (object_path == NULL)
+ {
+ dup_path = g_strdelimit (g_strdup_printf ("/%s", bus_name), ".", '/');
+ object_path = dup_path;
+ }
+
+ if (!tp_dbus_check_valid_object_path (object_path, error))
+ goto finally;
+
+ factory = tp_automatic_client_factory_new (dbus);
+ ret = tp_client_factory_ensure_connection (factory,
+ object_path, NULL, error);
+ g_object_unref (factory);
+
+finally:
+ g_free (dup_path);
+
+ return ret;
+}
+
+TpAccount *
+tp_tests_account_new (TpDBusDaemon *dbus,
+ const gchar *object_path,
+ GError **error)
+{
+ TpClientFactory *factory;
+ TpAccount *ret;
+
+ if (!tp_dbus_check_valid_object_path (object_path, error))
+ return NULL;
+
+ factory = tp_automatic_client_factory_new (dbus);
+ ret = tp_client_factory_ensure_account (factory,
+ object_path, NULL, error);
+ g_object_unref (factory);
+
+ return ret;
+}
+
+TpChannel *
+tp_tests_channel_new (TpConnection *conn,
+ const gchar *object_path,
+ const gchar *optional_channel_type,
+ TpHandleType optional_handle_type,
+ TpHandle optional_handle,
+ GError **error)
+{
+ TpChannel *ret;
+ GHashTable *asv;
+
+ asv = tp_asv_new (NULL, NULL);
+
+ if (optional_channel_type != NULL)
+ {
+ tp_asv_set_string (asv,
+ TP_PROP_CHANNEL_CHANNEL_TYPE, optional_channel_type);
+ }
+ if (optional_handle_type != TP_HANDLE_TYPE_NONE)
+ {
+ tp_asv_set_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE_TYPE, optional_handle_type);
+ }
+ if (optional_handle != 0)
+ {
+ tp_asv_set_uint32 (asv,
+ TP_PROP_CHANNEL_TARGET_HANDLE, optional_handle);
+ }
+
+ ret = tp_tests_channel_new_from_properties (conn, object_path, asv, error);
+
+ g_hash_table_unref (asv);
+
+ return ret;
+}
+
+TpChannel *
+tp_tests_channel_new_from_properties (TpConnection *conn,
+ const gchar *object_path,
+ const GHashTable *immutable_properties,
+ GError **error)
+{
+ TpClientFactory *factory;
+
+ if (!tp_dbus_check_valid_object_path (object_path, error))
+ return NULL;
+
+ factory = tp_proxy_get_factory (conn);
+ return tp_client_factory_ensure_channel (factory, conn,
+ object_path, immutable_properties, error);
+}
+
+void
+tp_tests_add_channel_to_ptr_array (GPtrArray *arr,
+ TpChannel *channel)
+{
+ GValueArray *tmp;
+ GVariant *variant;
+ GValue v = G_VALUE_INIT;
+ GHashTable *asv;
+
+ g_assert (arr != NULL);
+ g_assert (channel != NULL);
+
+ variant = tp_channel_dup_immutable_properties (channel);
+ dbus_g_value_parse_g_variant (variant, &v);
+ asv = g_value_get_boxed (&v);
+
+ tmp = tp_value_array_build (2,
+ DBUS_TYPE_G_OBJECT_PATH, tp_proxy_get_object_path (channel),
+ TP_HASH_TYPE_STRING_VARIANT_MAP, asv,
+ G_TYPE_INVALID);
+
+ g_ptr_array_add (arr, tmp);
+ g_variant_unref (variant);
+ g_value_unset (&v);
+}
+
diff --git a/tests/lib/telepathy/contactlist/util.h b/tests/lib/telepathy/contactlist/util.h
index d58138ea..3797f854 100644
--- a/tests/lib/telepathy/contactlist/util.h
+++ b/tests/lib/telepathy/contactlist/util.h
@@ -12,7 +12,6 @@
#define __TP_TESTS_LIB_UTIL_H__
#include <telepathy-glib/telepathy-glib.h>
-#include <telepathy-glib/base-connection.h>
TpDBusDaemon *tp_tests_dbus_daemon_dup_or_die (void);
@@ -36,6 +35,12 @@ void _tp_tests_assert_strv_equals (const char *file, int line,
const char *actual_desc, gconstpointer actual_strv,
const char *expected_desc, gconstpointer expected_strv);
+#define tp_tests_assert_bytes_equals(actual, expected, expected_length) \
+ _tp_tests_assert_bytes_equal (__FILE__, __LINE__, \
+ actual, expected, expected_length)
+void _tp_tests_assert_bytes_equal (const gchar *file, int line,
+ GBytes *actual, gconstpointer expected_data, gsize expected_length);
+
void tp_tests_create_conn (GType conn_type,
const gchar *account,
gboolean connect,
@@ -63,6 +68,7 @@ GValue *_tp_create_local_socket (TpSocketAddressType address_type,
TpSocketAccessControl access_control,
GSocketService **service,
gchar **unix_address,
+ gchar **unix_tmpdir,
GError **error);
void _tp_destroy_socket_control_list (gpointer data);
@@ -72,7 +78,33 @@ void tp_tests_connection_assert_disconnect_succeeds (TpConnection *connection);
TpContact *tp_tests_connection_run_until_contact_by_id (
TpConnection *connection,
const gchar *id,
- guint n_features,
- const TpContactFeature *features);
+ const GQuark *features);
+
+void tp_tests_channel_assert_expect_members (TpChannel *channel,
+ TpIntset *expected_members);
+
+TpConnection *tp_tests_connection_new (TpDBusDaemon *dbus,
+ const gchar *bus_name,
+ const gchar *object_path,
+ GError **error);
+
+TpAccount *tp_tests_account_new (TpDBusDaemon *dbus,
+ const gchar *object_path,
+ GError **error);
+
+TpChannel *tp_tests_channel_new (TpConnection *conn,
+ const gchar *object_path,
+ const gchar *optional_channel_type,
+ TpHandleType optional_handle_type,
+ TpHandle optional_handle,
+ GError **error);
+
+TpChannel *tp_tests_channel_new_from_properties (TpConnection *conn,
+ const gchar *object_path,
+ const GHashTable *immutable_properties,
+ GError **error);
+
+void tp_tests_add_channel_to_ptr_array (GPtrArray *arr,
+ TpChannel *channel);
#endif /* #ifndef __TP_TESTS_LIB_UTIL_H__ */
diff --git a/tests/lib/telepathy/tpf-test.deps b/tests/lib/telepathy/tpf-test.deps
index 1bce19e6..87e45fca 100644
--- a/tests/lib/telepathy/tpf-test.deps
+++ b/tests/lib/telepathy/tpf-test.deps
@@ -3,5 +3,5 @@ gobject-2.0
gio-2.0
gee-0.8
folks
-telepathy-glib
+telepathy-glib-1
tp-test-contactlist
diff --git a/tests/telepathy/Makefile.am b/tests/telepathy/Makefile.am
index 5eda26d5..f7abebed 100644
--- a/tests/telepathy/Makefile.am
+++ b/tests/telepathy/Makefile.am
@@ -52,7 +52,7 @@ AM_VALAFLAGS += \
--pkg gio-2.0 \
--pkg gee-0.8 \
--pkg gmodule-2.0 \
- --pkg telepathy-glib \
+ --pkg telepathy-glib-1 \
--pkg folks \
--pkg folks-telepathy \
--pkg folks-test \
diff --git a/tests/telepathy/individual-properties.vala b/tests/telepathy/individual-properties.vala
index 5351824e..2d8215a9 100644
--- a/tests/telepathy/individual-properties.vala
+++ b/tests/telepathy/individual-properties.vala
@@ -29,7 +29,7 @@ public class IndividualPropertiesTests : TpfTest.TestCase
private HashSet<string>? _changes_pending = null;
private static string iid_prefix =
- "telepathy:/org/freedesktop/Telepathy/Account/cm/protocol/account:";
+ "telepathy:/im/telepathy1/Account/cm/protocol/account:";
private string olivier_sha1 = Checksum.compute_for_string (ChecksumType.SHA1,
iid_prefix + "olivier@example.com");
diff --git a/tests/telepathy/individual-retrieval.vala b/tests/telepathy/individual-retrieval.vala
index 5908c058..8a629a51 100644
--- a/tests/telepathy/individual-retrieval.vala
+++ b/tests/telepathy/individual-retrieval.vala
@@ -29,7 +29,7 @@ public class IndividualRetrievalTests : TpfTest.TestCase
private HashSet<string> default_individuals;
private static string iid_prefix =
- "telepathy:/org/freedesktop/Telepathy/Account/cm/protocol/account:";
+ "telepathy:/im/telepathy1/Account/cm/protocol/account:";
public IndividualRetrievalTests ()
{
diff --git a/tests/tools/manager-file.py b/tests/tools/manager-file.py
index 45f64040..a97a1660 100755
--- a/tests/tools/manager-file.py
+++ b/tests/tools/manager-file.py
@@ -88,8 +88,8 @@ gflags = {
def write_manager(f, manager, protos):
# pointless backwards compat section
print >> f, '[ConnectionManager]'
- print >> f, 'BusName=org.freedesktop.Telepathy.ConnectionManager.' + manager
- print >> f, 'ObjectPath=/org/freedesktop/Telepathy/ConnectionManager/' + manager
+ print >> f, 'BusName=im.telepathy1.ConnectionManager.' + manager
+ print >> f, 'ObjectPath=/im/telepathy1/ConnectionManager/' + manager
# protocols
for proto, params in protos.iteritems():
diff --git a/tools/import-pidgin.vala b/tools/import-pidgin.vala
index f09e6939..cbb25a26 100644
--- a/tools/import-pidgin.vala
+++ b/tools/import-pidgin.vala
@@ -273,7 +273,7 @@ public class Folks.Importers.Pidgin : Folks.Importer
* http://telepathy.freedesktop.org/spec/Connection_Manager.html#Protocol
* and http://developer.pidgin.im/wiki/prpl_id. */
if (tp_protocol == "bonjour")
- tp_protocol = "local-xmpp";
+ tp_protocol = "local_xmpp";
else if (tp_protocol == "novell")
tp_protocol = "groupwise";
else if (tp_protocol == "gg")