summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2009-06-01 19:28:18 +0100
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2009-06-01 19:28:18 +0100
commit78b6f03003fd70a18b8b2a3998dfccae95b36bff (patch)
tree9d525bbed988a7f95a2edb1eb0769936f194be28
parent24adf9f6a8cc2e71facac99e968f7a0d3723ceca (diff)
McdConnection: fetch the initial self-presence on connection
This should mean that the previous hack (assuming that SetStatus set exactly the requested status) is no longer necessary - by downloading the initial state, we've caught up with any missed signal emissions. This requires some alterations to account-manager/auto-away.py to make its Presence implementation more realistic. While there, alter it to assert that the initial presence (available with no message) is correctly signalled. Some minor alterations to other presence-related tests were also needed.
-rw-r--r--src/mcd-connection.c50
-rw-r--r--test/twisted/account-manager/auto-away.py69
-rw-r--r--test/twisted/account-manager/auto-connect.py8
-rw-r--r--test/twisted/account-manager/presence.py13
-rw-r--r--test/twisted/mctest.py39
5 files changed, 107 insertions, 72 deletions
diff --git a/src/mcd-connection.c b/src/mcd-connection.c
index 682680a2..2d7bed2a 100644
--- a/src/mcd-connection.c
+++ b/src/mcd-connection.c
@@ -191,28 +191,6 @@ presence_set_status_cb (TpConnection *proxy, const GError *error,
G_STRFUNC, mcd_account_get_unique_name (priv->account),
error->message);
}
- /* We rely on the PresenceChanged signal to update our presence, but:
- * - it is not emitted if the presence doesn't change
- * - we miss a few emissions, while we wait for the readiness
- *
- * For this reasons, until we don't get the first PresenceChanged for our
- * self handle, just copy the account requested presence as current
- * presence.
- * FIXME: remove this code is things in things in SimplePresence interface
- * are changed.
- */
- if (!priv->got_presences_changed)
- {
- TpConnectionPresenceType presence;
- const gchar *status, *message;
-
- /* this is not really correct, as the requested presence might have
- * been changed -- but we hope it didn't */
- mcd_account_get_requested_presence (priv->account,
- &presence, &status, &message);
- g_signal_emit (weak_object, signals[SELF_PRESENCE_CHANGED], 0,
- presence, status, message);
- }
}
static gboolean
@@ -385,13 +363,41 @@ on_presences_changed (TpConnection *proxy, GHashTable *presences,
}
static void
+mcd_connection_initial_presence_cb (TpConnection *proxy,
+ GHashTable *presences,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ DEBUG ("GetPresences([SelfHandle]) failed: %s", error->message);
+ return;
+ }
+
+ on_presences_changed (proxy, presences, user_data, weak_object);
+}
+
+static void
_mcd_connection_setup_presence (McdConnection *connection)
{
McdConnectionPrivate *priv = connection->priv;
+ GArray *self_handle_array;
+ guint self_handle;
tp_cli_connection_interface_simple_presence_connect_to_presences_changed
(priv->tp_conn, on_presences_changed, priv, NULL,
(GObject *)connection, NULL);
+
+ self_handle_array = g_array_new (FALSE, FALSE, sizeof (guint));
+ self_handle = tp_connection_get_self_handle (priv->tp_conn);
+ g_array_append_val (self_handle_array, self_handle);
+ tp_cli_connection_interface_simple_presence_call_get_presences
+ (priv->tp_conn, -1, self_handle_array,
+ mcd_connection_initial_presence_cb, priv, NULL,
+ (GObject *) connection);
+ g_array_free (self_handle_array, TRUE);
+
tp_cli_dbus_properties_call_get
(priv->tp_conn, -1, TP_IFACE_CONNECTION_INTERFACE_SIMPLE_PRESENCE,
"Statuses", presence_get_statuses_cb, priv, NULL,
diff --git a/test/twisted/account-manager/auto-away.py b/test/twisted/account-manager/auto-away.py
index 6c00ea28..98fc0953 100644
--- a/test/twisted/account-manager/auto-away.py
+++ b/test/twisted/account-manager/auto-away.py
@@ -6,11 +6,6 @@ from mctest import exec_test, SimulatedConnection, create_fakecm_account,\
SimulatedChannel
import constants as cs
-class PresenceConnection(SimulatedConnection):
- def GetInterfaces(self, e):
- self.q.dbus_return(e.message, [cs.CONN_IFACE_REQUESTS,
- cs.CONN_IFACE_SIMPLE_PRESENCE], signature='as')
-
def test(q, bus, mc):
cm_name_ref = dbus.service.BusName(
tp_name_prefix + '.ConnectionManager.fakecm', bus=bus)
@@ -65,8 +60,14 @@ def test(q, bus, mc):
interface=tp_name_prefix + '.ConnectionManager',
handled=False)
- conn = PresenceConnection(q, bus, 'fakecm', 'fakeprotocol', '_',
- 'myself')
+ conn = SimulatedConnection(q, bus, 'fakecm', 'fakeprotocol', '_',
+ 'myself', has_presence=True)
+ conn.statuses = dbus.Dictionary({
+ 'available': (cs.PRESENCE_TYPE_AVAILABLE, True, True),
+ 'away': (cs.PRESENCE_TYPE_AWAY, True, True),
+ 'busy': (cs.PRESENCE_TYPE_BUSY, True, True),
+ 'offline': (cs.PRESENCE_TYPE_OFFLINE, False, False),
+ }, signature='s(ubb)')
q.dbus_return(e.message, conn.bus_name, conn.object_path, signature='so')
@@ -77,34 +78,35 @@ def test(q, bus, mc):
# Connect succeeds
conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE)
+ conn.presence = dbus.Struct((cs.PRESENCE_TYPE_AVAILABLE, 'available', ''),
+ signature='uss')
# MC does some setup, including fetching the list of Channels
- _, get_statuses = q.expect_many(
- EventPattern('dbus-method-call',
- interface=cs.PROPERTIES_IFACE, method='GetAll',
- args=[cs.CONN_IFACE_REQUESTS],
- path=conn.object_path, handled=True),
+ get_statuses = q.expect('dbus-method-call',
+ interface=cs.PROPERTIES_IFACE, method='Get',
+ args=[cs.CONN_IFACE_SIMPLE_PRESENCE, 'Statuses'],
+ path=conn.object_path, handled=True)
+
+ call, signal = q.expect_many(
EventPattern('dbus-method-call',
- interface=cs.PROPERTIES_IFACE, method='Get',
- args=[cs.CONN_IFACE_SIMPLE_PRESENCE, 'Statuses'],
- path=conn.object_path, handled=False),
+ path=conn.object_path,
+ interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence',
+ args=['available', 'staring at the sea'],
+ handled=True),
+ EventPattern('dbus-signal',
+ path=account.object_path,
+ interface=cs.ACCOUNT, signal='AccountPropertyChanged',
+ predicate = lambda e: 'CurrentPresence' in e.args[0]),
)
- q.dbus_return(get_statuses.message,
- dbus.Dictionary({
- 'available': (cs.PRESENCE_TYPE_AVAILABLE, True, True),
- 'away': (cs.PRESENCE_TYPE_AWAY, True, True),
- 'busy': (cs.PRESENCE_TYPE_BUSY, True, True),
- 'offline': (cs.PRESENCE_TYPE_OFFLINE, False, False),
- }, signature='s(ubb)'),
- signature='v')
+ assert signal.args[0]['CurrentPresence'] == (cs.PRESENCE_TYPE_AVAILABLE,
+ 'available', '')
- e = q.expect('dbus-method-call',
- path=conn.object_path,
- interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence',
- args=['available', 'staring at the sea'],
- handled=False)
- q.dbus_return(e.message, signature='')
+ e = q.expect('dbus-signal',
+ path=account.object_path,
+ interface=cs.ACCOUNT, signal='AccountPropertyChanged',
+ predicate = lambda e: 'CurrentPresence' in e.args[0])
+ assert e.args[0]['CurrentPresence'] == requested_presence
# Check the requested presence is online
properties = account.GetAll(cs.ACCOUNT,
@@ -126,8 +128,7 @@ def test(q, bus, mc):
path=conn.object_path,
interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence',
args=['away', ''],
- handled=False)
- q.dbus_return(e.message, signature='')
+ handled=True)
# Unset the idle flag
secret_debug_api.ChangeSystemFlags(dbus.UInt32(0),
@@ -139,8 +140,7 @@ def test(q, bus, mc):
path=conn.object_path,
interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence',
args=['available', 'staring at the sea'],
- handled=False)
- q.dbus_return(e.message, signature='')
+ handled=True)
# Go to a non-Available status
requested_presence = dbus.Struct((dbus.UInt32(cs.PRESENCE_TYPE_BUSY),
@@ -152,8 +152,7 @@ def test(q, bus, mc):
path=conn.object_path,
interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence',
args=['busy', 'in the great below'],
- handled=False)
- q.dbus_return(e.message, signature='')
+ handled=True)
forbidden = [EventPattern('dbus-method-call',
path=conn.object_path,
diff --git a/test/twisted/account-manager/auto-connect.py b/test/twisted/account-manager/auto-connect.py
index 90abbae6..7e20dbd4 100644
--- a/test/twisted/account-manager/auto-connect.py
+++ b/test/twisted/account-manager/auto-connect.py
@@ -83,7 +83,7 @@ def test(q, bus, mc):
handled=False),
EventPattern('dbus-method-call', path=conn.object_path,
interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence',
- handled=False),
+ handled=True),
EventPattern('dbus-signal', signal='AccountPropertyChanged',
path=account_path, interface=cs.ACCOUNT,
predicate=lambda e: 'ConnectionStatus' in e.args[0]),
@@ -91,11 +91,11 @@ def test(q, bus, mc):
assert e.args[0]['ConnectionStatus'] == cs.CONN_STATUS_CONNECTED
- q.dbus_return(set_presence.message, signature='')
-
e = q.expect('dbus-signal', signal='AccountPropertyChanged',
path=account_path, interface=cs.ACCOUNT,
- predicate=lambda e: 'CurrentPresence' in e.args[0])
+ predicate=lambda e: 'CurrentPresence' in e.args[0]
+ and e.args[0]['CurrentPresence'][2] != '')
+
assert e.args[0]['CurrentPresence'] == (cs.PRESENCE_TYPE_AVAILABLE,
'available', 'My vision is augmented')
diff --git a/test/twisted/account-manager/presence.py b/test/twisted/account-manager/presence.py
index c7967da7..b68cff04 100644
--- a/test/twisted/account-manager/presence.py
+++ b/test/twisted/account-manager/presence.py
@@ -28,10 +28,9 @@ def test(q, bus, mc):
interface=cs.CONN_IFACE_SIMPLE_PRESENCE,
method='SetPresence',
args=list(presence[1:]),
- handled=False),
+ handled=True),
])
- q.dbus_return(e.message, signature='')
q.dbus_emit(conn.object_path, cs.CONN_IFACE_SIMPLE_PRESENCE,
'PresencesChanged', {conn.self_handle: presence},
signature='a{u(uss)}')
@@ -49,15 +48,7 @@ def test(q, bus, mc):
e = q.expect('dbus-method-call',
interface=cs.CONN_IFACE_SIMPLE_PRESENCE, method='SetPresence',
args=list(presence[1:]),
- handled=False)
-
- # Set returns immediately; the change happens asynchronously
- q.expect('dbus-return', method='Set')
-
- q.dbus_return(e.message, signature='')
- q.dbus_emit(conn.object_path, cs.CONN_IFACE_SIMPLE_PRESENCE,
- 'PresencesChanged', {conn.self_handle: presence},
- signature='a{u(uss)}')
+ handled=True)
q.expect('dbus-signal', path=account.object_path,
interface=cs.ACCOUNT, signal='AccountPropertyChanged',
diff --git a/test/twisted/mctest.py b/test/twisted/mctest.py
index 0ad08d3a..5c88df05 100644
--- a/test/twisted/mctest.py
+++ b/test/twisted/mctest.py
@@ -192,6 +192,12 @@ class SimulatedConnection(object):
method='ListChannels')
if has_presence:
+ q.add_dbus_method_impl(self.SetPresence, path=self.object_path,
+ interface=cs.CONN_IFACE_SIMPLE_PRESENCE,
+ method='SetPresence')
+ q.add_dbus_method_impl(self.GetPresences, path=self.object_path,
+ interface=cs.CONN_IFACE_SIMPLE_PRESENCE,
+ method='GetPresences')
q.add_dbus_method_impl(self.Get_SimplePresenceStatuses,
path=self.object_path, interface=cs.PROPERTIES_IFACE,
method='Get',
@@ -225,6 +231,8 @@ class SimulatedConnection(object):
'error': (cs.PRESENCE_TYPE_ERROR, False, False),
'unknown': (cs.PRESENCE_TYPE_UNKNOWN, False, False),
}, signature='s(ubb)')
+ self.presence = dbus.Struct((cs.PRESENCE_TYPE_OFFLINE, 'offline', ''),
+ signature='uss')
# not actually very relevant for MC so hard-code 0 for now
def GetAliasFlags(self, e):
@@ -246,6 +254,35 @@ class SimulatedConnection(object):
'MaximumAvatarBytes': 8192,
}, signature='a{sv}')
+ def GetPresences(self, e):
+ ret = dbus.Dictionary(signature='u(uss)')
+ contacts = e.args[0]
+ for contact in contacts:
+ if contact == self.self_handle:
+ ret[contact] = self.presence
+ else:
+ # stub - MC doesn't care
+ ret[contact] = dbus.Struct(
+ (cs.PRESENCE_TYPE_UNKNOWN, 'unknown', ''),
+ signature='uss')
+ self.q.dbus_return(e.message, ret, signature='a{u(uss)}')
+
+ def SetPresence(self, e):
+ if e.args[0] in self.statuses:
+ presence = dbus.Struct((self.statuses[e.args[0]][0],
+ e.args[0], e.args[1]), signature='uss')
+
+ if presence != self.presence:
+ self.presence = presence
+ self.q.dbus_emit(self.object_path,
+ cs.CONN_IFACE_SIMPLE_PRESENCE, 'PresencesChanged',
+ { self.self_handle : presence },
+ signature='a{u(uss)}')
+
+ self.q.dbus_return(e.message, signature='')
+ else:
+ self.q.dbus_raise(cs.INVALID_ARGUMENT, 'Unknown status')
+
def Get_SimplePresenceStatuses(self, e):
self.q.dbus_return(e.message, self.statuses, signature='v')
@@ -639,6 +676,8 @@ def enable_fakecm_account(q, bus, mc, account, expected_params,
q.expect('dbus-method-call', method='Connect',
path=conn.object_path, handled=True)
conn.StatusChanged(cs.CONN_STATUS_CONNECTED, cs.CONN_STATUS_REASON_NONE)
+ conn.presence = dbus.Struct((cs.PRESENCE_TYPE_AVAILABLE, 'available', ''),
+ signature='uss')
expect_after_connect = list(expect_after_connect)