From ef47f6e4c5baedf9c7f6aa4e44e5564da431d071 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 25 Aug 2006 14:55:19 -0400 Subject: [PATCH] Fix buddy & activity visibility leaks if they are not yet valid; add Activity color attribute and don't make activity valid until we get the color --- shell/PresenceService/Activity.py | 26 ++++++++++++++-- shell/PresenceService/Buddy.py | 19 ++++++++++-- shell/PresenceService/PresenceService.py | 39 +++++++++++++++++++----- sugar/presence/Activity.py | 7 +++-- 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/shell/PresenceService/Activity.py b/shell/PresenceService/Activity.py index 6aa27195..6dc9497f 100644 --- a/shell/PresenceService/Activity.py +++ b/shell/PresenceService/Activity.py @@ -41,6 +41,11 @@ class ActivityDBusHelper(dbus.service.Object): def getId(self): return self._parent.get_id() + @dbus.service.method(ACTIVITY_DBUS_INTERFACE, + in_signature="", out_signature="s") + def getColor(self): + return self._parent.get_color() + @dbus.service.method(ACTIVITY_DBUS_INTERFACE, in_signature="", out_signature="ao") def getJoinedBuddies(self): @@ -81,6 +86,8 @@ class Activity(object): self._buddies = [] self._services = {} # service type -> list of Services + self._color = None + self._valid = False self._object_id = object_id self._object_path = "/org/laptop/Presence/Activities/%d" % self._object_id @@ -91,9 +98,16 @@ class Activity(object): def object_path(self): return dbus.ObjectPath(self._object_path) + def is_valid(self): + """An activity is only valid when it's color is available.""" + return self._valid + def get_id(self): return self._activity_id + def get_color(self): + return self._color + def get_services(self): ret = [] for serv_list in self._services.values(): @@ -112,7 +126,7 @@ class Activity(object): for serv_list in self._services.values(): for serv in serv_list: owner = serv.get_owner() - if not owner in buddies: + if not owner in buddies and owner.is_valid(): buddies.append(owner) return buddies @@ -121,11 +135,17 @@ class Activity(object): if not self._services.has_key(stype): self._services[stype] = [] + if not self._color: + color = service.get_one_property('color') + if color: + self._color = color + self._valid = True + # Send out the BuddyJoined signal if this is the first # service from the buddy that we've seen buddies = self.get_joined_buddies() serv_owner = service.get_owner() - if serv_owner and serv_owner not in buddies: + if serv_owner and serv_owner not in buddies and serv_owner.is_valid(): self._dbus_helper.BuddyJoined(serv_owner.object_path()) serv_owner.add_activity(self) @@ -146,6 +166,6 @@ class Activity(object): # service from the buddy buddies = self.get_joined_buddies() serv_owner = service.get_owner() - if serv_owner and serv_owner not in buddies: + if serv_owner and serv_owner not in buddies and serv_owner.is_valid(): serv_owner.remove_activity(self) self._dbus_helper.BuddyLeft(serv_owner.object_path()) diff --git a/shell/PresenceService/Buddy.py b/shell/PresenceService/Buddy.py index 6d3ff3d4..5f3f0e83 100644 --- a/shell/PresenceService/Buddy.py +++ b/shell/PresenceService/Buddy.py @@ -65,6 +65,8 @@ class BuddyDBusHelper(dbus.service.Object): in_signature="", out_signature="ao") def getJoinedActivities(self): acts = [] + for act in self._parent.get_joined_activities(): + acts.append(act.object_path()) return acts @dbus.service.method(BUDDY_DBUS_INTERFACE, @@ -181,7 +183,8 @@ class Buddy(object): if not found: raise RuntimeError("Tried to add activity for which we had no service") self._activities[actid] = activity - self._dbus_helper.JoinedActivity(activity.object_path()) + if activity.is_valid(): + self._dbus_helper.JoinedActivity(activity.object_path()) def remove_service(self, service): """Remove a service from a buddy; ie, the activity was closed @@ -204,8 +207,15 @@ class Buddy(object): if not self._activities.has_key(actid): return del self._activities[actid] - print "Buddy (%s) left activity %s." % (self._nick_name, actid) - self._dbus_helper.LeftActivity(activity.object_path()) + if activity.is_valid(): + self._dbus_helper.LeftActivity(activity.object_path()) + + def get_joined_activities(self): + acts = [] + for act in self._activities.values(): + if act.is_valid(): + acts.append(act) + return acts def get_service_of_type(self, stype=None, activity=None): """Return a service of a certain type, or None if the buddy @@ -213,6 +223,9 @@ class Buddy(object): if not stype: raise RuntimeError("Need to specify a service type.") + if activity and not activity.is_valid(): + raise RuntimeError("Activity is not yet valid.") + if activity: actid = activity.get_id() for service in self._services.values(): diff --git a/shell/PresenceService/PresenceService.py b/shell/PresenceService/PresenceService.py index 4fe0b2f6..fe97698f 100644 --- a/shell/PresenceService/PresenceService.py +++ b/shell/PresenceService/PresenceService.py @@ -302,24 +302,36 @@ class PresenceService(object): return ret def get_activities(self): - return self._activities.values() + # Only return valid activities + ret = [] + for act in self._activities.values(): + if act.is_valid(): + ret.append(act) + return ret def get_activity(self, actid): if self._activities.has_key(actid): - return self._activities[actid] + act = self._activities[actid] + if act.is_valid(): + return act return None def get_buddies(self): - return self._buddies.values() + buddies = [] + for buddy in self._buddies.values(): + if buddy.is_valid(): + buddies.append(buddy) + return buddies def get_buddy_by_name(self, name): if self._buddies.has_key(name): - return self._buddies[name] + if self._buddies[name].is_valid(): + return self._buddies[name] return None def get_buddy_by_address(self, address): for buddy in self._buddies.values(): - if buddy.get_address() == address: + if buddy.get_address() == address and buddy.is_valid(): return buddy return None @@ -379,17 +391,21 @@ class PresenceService(object): if not actid: return activity = None + was_valid = False if not self._activities.has_key(actid): objid = self._get_next_object_id() activity = Activity.Activity(self._bus_name, objid, service) self._activities[actid] = activity - self._dbus_helper.ActivityAppeared(activity.object_path()) else: activity = self._activities[actid] + was_valid = activity.is_valid() if activity: activity.add_service(service) + if not was_valid and activity.is_valid(): + self._dbus_helper.ActivityAppeared(activity.object_path()) + def _handle_remove_activity_service(self, service): actid = service.get_activity_id() if not actid: @@ -596,7 +612,11 @@ class PresenceService(object): if not len(services): raise NotFoundError("The service type %s was not present within the activity %s" % (stype, activity.object_path())) act_service = services[0] - return self._share_activity(activity.get_id(), stype, act_service.get_properties(), + props = act_service.get_properties() + color = activity.get_color() + if color: + props['color'] = color + return self._share_activity(activity.get_id(), stype, properties, act_service.get_address(), act_service.get_port(), act_service.get_domain()) def share_activity(self, activity_id, stype, properties=None, address=None, port=-1, domain=u"local"): @@ -615,6 +635,10 @@ class PresenceService(object): properties['port'] = port if port and port != -1 and (type(port) != type(1) or port <= 1024 or port >= 65535): raise ValueError("port must be a number between 1024 and 65535") + + color = self._owner.get_color() + if color: + properties['color'] = color logging.debug('Share activity %s, type %s, address %s, port %d, properties %s' % (activity_id, stype, address, port, properties)) return self.register_service(real_name, stype, properties, address, port, domain) @@ -699,6 +723,7 @@ class PresenceService(object): def main(): from sugar import TracebackUtils + env.read_profile() loop = gobject.MainLoop() ps = PresenceService() tbh = TracebackUtils.TracebackHelper() diff --git a/sugar/presence/Activity.py b/sugar/presence/Activity.py index 35def82d..bef91fc8 100644 --- a/sugar/presence/Activity.py +++ b/sugar/presence/Activity.py @@ -30,6 +30,7 @@ class Activity(gobject.GObject): self._activity.connect_to_signal('ServiceDisappeared', self._service_disappeared_cb) self._id = None + self._color = None def object_path(self): return self._object_path @@ -68,8 +69,10 @@ class Activity(gobject.GObject): self._id = self._activity.getId() return self._id - def get_icon(self): - return self._buddy.getIcon() + def get_color(self): + if not self._color: + self._color = self._activity.getColor() + return self._color def get_services(self): resp = self._activity.getServices()