From ae852d45ecb8365b3a7a0c390e45306b467680fd Mon Sep 17 00:00:00 2001 From: Ed Page Date: Sat, 6 Feb 2010 21:23:12 -0600 Subject: [PATCH] Added detection of missed/rejected calls --- hand_tests/dbus_signals.py | 138 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 134 insertions(+), 4 deletions(-) diff --git a/hand_tests/dbus_signals.py b/hand_tests/dbus_signals.py index d80ba2f..08698f3 100755 --- a/hand_tests/dbus_signals.py +++ b/hand_tests/dbus_signals.py @@ -10,6 +10,7 @@ import dbus import dbus.mainloop.glib import telepathy +import util.go_utils as gobject_utils import gtk_toolbox @@ -31,6 +32,7 @@ class AutoAcceptCall(object): self._initiatorID = None self._targetHandle = None self._targetID = None + self._requested = None self._pendingHandles = None self._chan[DBUS_PROPERTIES].GetAll( @@ -56,6 +58,7 @@ class AutoAcceptCall(object): self._outstandingRequests.append(self._on_got_pending_members) def is_inbound(self): + return not self._requested isInbound = self._targetHandle == self._initiatorHandle return isInbound @@ -113,6 +116,7 @@ class AutoAcceptCall(object): self._targetHandle, self._targetID, self._pendingHandles, + self._requested, ) self._on_success(self) @@ -123,6 +127,7 @@ class AutoAcceptCall(object): self._initiatorHandle = properties["InitiatorHandle"] self._targetID = properties["InitiatorID"] self._targetHandle = properties["InitiatorHandle"] + self._requested = properties["Requested"] self._report_callback_done(self._on_got_all) @@ -136,6 +141,100 @@ class AutoAcceptCall(object): self._report_callback_done(self._on_got_pending_members) +class WasMissedCall(object): + + def __init__(self, bus, conn, chan, on_success, on_error): + self._sessionBus = bus + self._conn = conn + self._chan = chan + self._on_success = on_success + self._on_error = on_error + + self._requested = None + self._didMembersChange = False + self._didClose = False + self._didReport = False + + self._timeoutId = gobject_utils.timeout_add_seconds(10, self._on_timeout) + + self._chan[telepathy.interfaces.CHANNEL_INTERFACE_GROUP].connect_to_signal( + "MembersChanged", + self._on_members_changed, + ) + + self._chan[telepathy.interfaces.CHANNEL].connect_to_signal( + "Closed", + self._on_closed, + ) + + self._chan[DBUS_PROPERTIES].GetAll( + telepathy.interfaces.CHANNEL_INTERFACE, + reply_handler = self._on_got_all, + error_handler = self._on_got_all, + ) + + def _report_missed_if_ready(self): + if self._didReport: + pass + elif self._requested is not None and (self._didMembersChange or self._didClose): + if self._requested: + self._report_error("wrong direction") + elif self._didClose: + self._report_success() + else: + self._report_error("members added") + else: + if self._didClose: + self._report_error("closed too early") + + def _report_success(self): + assert not self._didReport + self._didReport = True + if self._timeoutId: + gobject.source_remove(self._timeoutId) + self._timeoutId = None + self._on_success(self) + + def _report_error(self, reason): + assert not self._didReport + self._didReport = True + if self._timeoutId: + gobject.source_remove(self._timeoutId) + self._timeoutId = None + self._on_error(self, reason) + + @gtk_toolbox.log_exception(_moduleLogger) + @gtk_toolbox.trace(_moduleLogger) + def _on_got_all(self, properties): + self._requested = properties["Requested"] + self._report_missed_if_ready() + + @gtk_toolbox.log_exception(_moduleLogger) + @gtk_toolbox.trace(_moduleLogger) + def _on_members_changed(self, message, added, removed, lp, rp, actor, reason): + pprint.pprint((message, added, removed, lp, rp, actor, reason)) + if added: + self._didMembersChange = True + self._report_missed_if_ready() + + @gtk_toolbox.log_exception(_moduleLogger) + @gtk_toolbox.trace(_moduleLogger) + def _on_closed(self): + self._didClose = True + self._report_missed_if_ready() + + @gtk_toolbox.log_exception(_moduleLogger) + @gtk_toolbox.trace(_moduleLogger) + def _on_error(self, *args): + self._report_error(args) + + @gtk_toolbox.log_exception(_moduleLogger) + @gtk_toolbox.trace(_moduleLogger) + def _on_timeout(self): + self._report_error("timeout") + return False + + class NewChannelSignaller(object): def __init__(self, on_new_channel): @@ -171,7 +270,7 @@ class NewChannelSignaller(object): self._on_user_new_channel(self._sessionBus, conn, chan, channelType) -class Manager(object): +class AutoAcceptManager(object): def __init__(self): self._newChannelSignaller = NewChannelSignaller(self._on_new_channel) @@ -185,7 +284,7 @@ class Manager(object): if channelType != telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA: return - # @bug does not distinguish between preferred CMs + # @todo distinguish between preferred CMs attemptPickup = AutoAcceptCall(bus, conn, chan, self._on_inbound_call, self._on_inbound_call_error) @gtk_toolbox.log_exception(_moduleLogger) @@ -211,13 +310,44 @@ class Manager(object): def _on_pickup_error(self, autoAcceptCall, *args): _moduleLogger.info("Call failed to pick up (%r)" % (args, )) + +class MissedManager(object): + + def __init__(self): + self._newChannelSignaller = NewChannelSignaller(self._on_new_channel) + + def start(self): + self._newChannelSignaller.start() + + @gtk_toolbox.log_exception(_moduleLogger) + def _on_new_channel(self, bus, conn, chan, channelType): + pprint.pprint((bus, conn, chan, channelType)) + if channelType != telepathy.interfaces.CHANNEL_TYPE_STREAMED_MEDIA: + return + + missDetection = WasMissedCall( + bus, conn, chan, self._on_missed_call, self._on_error_for_missed + ) + + @gtk_toolbox.log_exception(_moduleLogger) + def _on_missed_call(self, missDetection): + _moduleLogger.info("Missed a call") + + @gtk_toolbox.log_exception(_moduleLogger) + def _on_error_for_missed(self, missDetection, reason): + _moduleLogger.info("Error: %r claims %r" % (missDetection, reason)) + + if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) l = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) - autoaccept = Manager() + if False: + manager = AutoAcceptManager() + else: + manager = MissedManager() gobject.threads_init() - gobject.idle_add(autoaccept.start) + gobject.idle_add(manager.start) mainloop = gobject.MainLoop(is_running=True) mainloop.run() -- 1.7.9.5