diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2009-06-01 19:28:18 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2009-06-01 19:28:18 +0100 |
commit | 78b6f03003fd70a18b8b2a3998dfccae95b36bff (patch) | |
tree | 9d525bbed988a7f95a2edb1eb0769936f194be28 | |
parent | 24adf9f6a8cc2e71facac99e968f7a0d3723ceca (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.c | 50 | ||||
-rw-r--r-- | test/twisted/account-manager/auto-away.py | 69 | ||||
-rw-r--r-- | test/twisted/account-manager/auto-connect.py | 8 | ||||
-rw-r--r-- | test/twisted/account-manager/presence.py | 13 | ||||
-rw-r--r-- | test/twisted/mctest.py | 39 |
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) |