Complete move to external bundle registry.

This commit is contained in:
Tomeu Vizoso 2007-08-09 18:10:16 +02:00
parent f00f3e2f8d
commit cff8ffc328
10 changed files with 141 additions and 140 deletions

View File

@ -48,6 +48,15 @@ class ActivityRegistry(dbus.service.Object):
registry = bundleregistry.get_registry()
return registry.add_bundle(bundle_path)
@dbus.service.method(_ACTIVITY_REGISTRY_IFACE,
in_signature='', out_signature='aa{sv}')
def GetActivities(self):
result = []
registry = bundleregistry.get_registry()
for bundle in registry:
result.append(self._bundle_to_dict(bundle))
return result
@dbus.service.method(_ACTIVITY_REGISTRY_IFACE,
in_signature='s', out_signature='a{sv}')
def GetActivity(self, service_name):
@ -89,7 +98,8 @@ class ActivityRegistry(dbus.service.Object):
return {'name': bundle.get_name(),
'icon': bundle.get_icon(),
'service_name': bundle.get_service_name(),
'path': bundle.get_path()}
'path': bundle.get_path(),
'show_launcher': bundle.get_show_launcher()}
def _bundle_added_cb(self, bundle_registry, bundle):
self.ActivityAdded(self._bundle_to_dict(bundle))

View File

@ -18,29 +18,29 @@ import gobject
from sugar.graphics.xocolor import XoColor
from sugar.presence import presenceservice
from sugar import activity
from model import bundleregistry
from model.BuddyModel import BuddyModel
from model.accesspointmodel import AccessPointModel
from hardware import hardwaremanager
from hardware import nmclient
class ActivityModel:
def __init__(self, activity, bundle):
def __init__(self, activity, activity_info):
self._activity = activity
self._bundle = bundle
self._activity_info = activity_info
def get_id(self):
return self._activity.props.id
def get_icon_name(self):
return self._bundle.get_icon()
return self._activity_info.icon
def get_color(self):
return XoColor(self._activity.props.color)
def get_service_name(self):
return self._bundle.get_service_name()
return self._activity_info.service_name
def get_title(self):
return self._activity.props.name
@ -75,7 +75,6 @@ class MeshModel(gobject.GObject):
self._buddies = {}
self._access_points = {}
self._mesh = None
self._bundle_registry = bundleregistry.get_registry()
self._pservice = presenceservice.get_instance()
self._pservice.connect("activity-appeared",
@ -196,13 +195,14 @@ class MeshModel(gobject.GObject):
def _activity_appeared_cb(self, pservice, activity):
self._check_activity(activity)
def _check_activity(self, activity):
bundle = self._bundle_registry.get_bundle(activity.props.type)
if not bundle:
def _check_activity(self, presence_activity):
registry = activity.get_registry()
activity_info = registry.get_activity(presence_activity.props.type)
if not activity_info:
return
if self.has_activity(activity.props.id):
if self.has_activity(presence_activity.props.id):
return
self.add_activity(bundle, activity)
self.add_activity(activity_info, presence_activity)
def has_activity(self, activity_id):
return self._activities.has_key(activity_id)
@ -213,8 +213,8 @@ class MeshModel(gobject.GObject):
else:
return None
def add_activity(self, bundle, activity):
model = ActivityModel(activity, bundle)
def add_activity(self, activity_info, activity):
model = ActivityModel(activity, activity_info)
self._activities[model.get_id()] = model
self.emit('activity-added', model)

View File

@ -44,10 +44,10 @@ class HomeActivity(gobject.GObject):
gobject.PARAM_READWRITE),
}
def __init__(self, bundle, activity_id):
def __init__(self, activity_info, activity_id):
"""Initialise the HomeActivity
bundle -- sugar.activity.bundle.Bundle instance,
activity_info -- sugar.activity.registry.ActivityInfo instance,
provides the information required to actually
create the new instance. This is, in effect,
the "type" of activity being created.
@ -61,7 +61,7 @@ class HomeActivity(gobject.GObject):
self._pid = None
self._service = None
self._activity_id = activity_id
self._bundle = bundle
self._activity_info = activity_info
self._launch_time = time.time()
self._launching = False
@ -99,9 +99,9 @@ class HomeActivity(gobject.GObject):
return self._window.get_name()
def get_icon_name(self):
"""Retrieve the bundle's icon (file) name"""
if self._bundle:
return self._bundle.get_icon()
"""Retrieve the activity's icon (file) name"""
if self._activity_info:
return self._activity_info.icon
else:
return 'theme:stock-missing'
@ -156,9 +156,9 @@ class HomeActivity(gobject.GObject):
return self._window
def get_type(self):
"""Retrieve bundle's "service_name" for future reference"""
if self._bundle:
return self._bundle.get_service_name()
"""Retrieve activity_info's "service_name" for future reference"""
if self._activity_info:
return self._activity_info.service_name
else:
return None

View File

@ -21,9 +21,9 @@ import wnck
import dbus
from sugar import wm
from sugar import activity
from model.homeactivity import HomeActivity
from model import bundleregistry
class HomeModel(gobject.GObject):
"""Model of the "Home" view (activity management)
@ -61,7 +61,6 @@ class HomeModel(gobject.GObject):
gobject.GObject.__init__(self)
self._activities = []
self._bundle_registry = bundleregistry.get_registry()
self._active_activity = None
self._pending_activity = None
@ -83,11 +82,11 @@ class HomeModel(gobject.GObject):
"""
return self._pending_activity
def _set_pending_activity(self, activity):
if self._pending_activity == activity:
def _set_pending_activity(self, home_activity):
if self._pending_activity == home_activity:
return
self._pending_activity = activity
self._pending_activity = home_activity
self.emit('pending-activity-changed', self._pending_activity)
def get_active_activity(self):
@ -101,8 +100,8 @@ class HomeModel(gobject.GObject):
"""
return self._active_activity
def _set_active_activity(self, activity):
if self._active_activity == activity:
def _set_active_activity(self, home_activity):
if self._active_activity == home_activity:
return
if self._active_activity:
@ -111,14 +110,14 @@ class HomeModel(gobject.GObject):
service.set_active(False,
reply_handler=self._set_active_success,
error_handler=self._set_active_error)
if activity:
service = activity.get_service()
if home_activity:
service = home_activity.get_service()
if service:
service.set_active(True,
reply_handler=self._set_active_success,
error_handler=self._set_active_error)
self._active_activity = activity
self._active_activity = home_activity
self.emit('active-activity-changed', self._active_activity)
def __iter__(self):
@ -135,45 +134,46 @@ class HomeModel(gobject.GObject):
def _window_opened_cb(self, screen, window):
if window.get_window_type() == wnck.WINDOW_NORMAL:
activity = None
home_activity = None
activity_id = wm.get_activity_id(window)
bundle_id = wm.get_bundle_id(window)
if bundle_id:
bundle = self._bundle_registry.get_bundle(bundle_id)
service_name = wm.get_bundle_id(window)
if service_name:
registry = activity.get_registry()
activity_info = registry.get_activity(service_name)
else:
bundle = None
activity_info = None
if activity_id:
activity = self._get_activity_by_id(activity_id)
home_activity = self._get_activity_by_id(activity_id)
if not activity:
activity = HomeActivity(bundle, activity_id)
self._add_activity(activity)
if not home_activity:
home_activity = HomeActivity(activity_info, activity_id)
self._add_activity(home_activity)
activity.set_window(window)
home_activity.set_window(window)
activity.props.launching = False
self.emit('activity-started', activity)
home_activity.props.launching = False
self.emit('activity-started', home_activity)
if self._pending_activity is None:
self._set_pending_activity(activity)
self._set_pending_activity(home_activity)
def _window_closed_cb(self, screen, window):
if window.get_window_type() == wnck.WINDOW_NORMAL:
self._remove_activity_by_xid(window.get_xid())
def _get_activity_by_xid(self, xid):
for activity in self._activities:
if activity.get_xid() == xid:
return activity
for home_activity in self._activities:
if home_activity.get_xid() == xid:
return home_activity
return None
def _get_activity_by_id(self, activity_id):
for activity in self._activities:
if activity.get_activity_id() == activity_id:
return activity
for home_activity in self._activities:
if home_activity.get_activity_id() == activity_id:
return home_activity
return None
def _set_active_success(self):
@ -194,12 +194,12 @@ class HomeModel(gobject.GObject):
self._set_pending_activity(act)
self._set_active_activity(act)
def _add_activity(self, activity):
self._activities.append(activity)
self.emit('activity-added', activity)
def _add_activity(self, home_activity):
self._activities.append(home_activity)
self.emit('activity-added', home_activity)
def _remove_activity(self, activity):
if activity == self._active_activity:
def _remove_activity(self, home_activity):
if home_activity == self._active_activity:
self._set_active_activity(None)
# Figure out the new _pending_activity.
windows = wnck.screen_get_default().get_windows_stacked()
@ -213,28 +213,29 @@ class HomeModel(gobject.GObject):
logging.error('No activities are running')
self._set_pending_activity(None)
self.emit('activity-removed', activity)
self._activities.remove(activity)
self.emit('activity-removed', home_activity)
self._activities.remove(home_activity)
def _remove_activity_by_xid(self, xid):
activity = self._get_activity_by_xid(xid)
if activity:
self._remove_activity(activity)
home_activity = self._get_activity_by_xid(xid)
if home_activity:
self._remove_activity(home_activity)
else:
logging.error('Model for window %d does not exist.' % xid)
def notify_activity_launch(self, activity_id, service_name):
bundle = self._bundle_registry.get_bundle(service_name)
if not bundle:
registry = activity.get_registry()
activity_info = registry.get_activity(service_name)
if not activity_info:
raise ValueError("Activity service name '%s' was not found in the bundle registry." % service_name)
activity = HomeActivity(bundle, activity_id)
activity.props.launching = True
self._add_activity(activity)
home_activity = HomeActivity(activity_info, activity_id)
home_activity.props.launching = True
self._add_activity(home_activity)
def notify_activity_launch_failed(self, activity_id):
activity = self._get_activity_by_id(activity_id)
if activity:
logging.debug("Activity %s (%s) launch failed" % (activity_id, activity.get_type()))
self._remove_activity(activity)
home_activity = self._get_activity_by_id(activity_id)
if home_activity:
logging.debug("Activity %s (%s) launch failed" % (activity_id, home_activity.get_type()))
self._remove_activity(home_activity)
else:
logging.error('Model for activity id %s does not exist.' % activity_id)

View File

@ -26,6 +26,7 @@ import gtk
import wnck
from sugar.activity.activityhandle import ActivityHandle
from sugar import activity
from sugar.activity import activityfactory
from sugar.datastore import datastore
from sugar import profile
@ -34,7 +35,6 @@ from view.ActivityHost import ActivityHost
from view.frame.frame import Frame
from view.keyhandler import KeyHandler
from view.home.HomeWindow import HomeWindow
from model import bundleregistry
from model.shellmodel import ShellModel
from hardware import hardwaremanager
@ -116,16 +116,16 @@ class Shell(gobject.GObject):
return self._frame
def join_activity(self, bundle_id, activity_id):
activity = self.get_activity(activity_id)
if activity:
activity.present()
activity_host = self.get_activity(activity_id)
if activity_host:
activity_host.present()
return
# Get the service name for this activity, if
# we have a bundle on the system capable of handling
# this activity type
breg = bundleregistry.get_registry()
bundle = breg.get_bundle(bundle_id)
registry = activity.get_registry()
bundle = registry.get_activity(bundle_id)
if not bundle:
logging.error("Couldn't find activity for type %s" % bundle_id)
return

View File

@ -123,32 +123,8 @@ class ClipboardMenu(Palette):
def _open_item_activate_cb(self, menu_item):
if self._percent < 100:
return
jobject = self._copy_to_journal()
# TODO: we cannot simply call resume() right now because we would lock
# the shell as we are sharing the same loop as the shell service.
#jobject.resume()
# TODO: take this out when we fix the mess that is the shell/shellservice.
from model import bundleregistry
from sugar.activity.bundle import Bundle
from sugar.activity import activityfactory
if jobject.is_bundle():
bundle = Bundle(jobject.file_path)
if not bundle.is_installed():
bundle.install()
activityfactory.create(bundle.get_service_name())
else:
service_name = None
mime_type = jobject.metadata['mime_type']
for bundle in bundleregistry.get_registry():
if bundle.get_mime_types() and mime_type in bundle.get_mime_types():
service_name = bundle.get_service_name()
break
if service_name:
activityfactory.create_with_object_id(service_name,
jobject.object_id)
jobject.resume()
def _remove_item_activate_cb(self, menu_item):
cb_service = clipboardservice.get_instance()

View File

@ -22,31 +22,31 @@ from sugar.graphics.xocolor import XoColor
from sugar.graphics.iconbutton import IconButton
from sugar.graphics import style
from sugar import profile
from sugar import activity
from model import bundleregistry
from frameinvoker import FrameCanvasInvoker
class ActivityButton(IconButton):
def __init__(self, activity):
IconButton.__init__(self, icon_name=activity.get_icon(),
def __init__(self, activity_info):
IconButton.__init__(self, icon_name=activity_info.icon,
stroke_color=style.COLOR_WHITE,
fill_color=style.COLOR_TRANSPARENT)
palette = Palette(activity.get_name())
palette = Palette(activity_info.name)
palette.props.invoker = FrameCanvasInvoker(self)
palette.set_group_id('frame')
self.set_palette(palette)
self._activity = activity
self._activity_info = activity_info
def get_bundle_id(self):
return self._activity.get_service_name()
return self._activity_info.service_name
class InviteButton(IconButton):
def __init__(self, activity, invite):
IconButton.__init__(self, icon_name=activity.get_icon())
def __init__(self, activity_model, invite):
IconButton.__init__(self, icon_name=activity_model.get_color())
self.props.xo_color = activity.get_color()
self.props.xo_color = activity_model.get_color()
self._invite = invite
def get_activity_id(self):
@ -67,12 +67,12 @@ class ActivitiesBox(hippo.CanvasBox):
self._invite_to_item = {}
self._invites = self._shell_model.get_invites()
bundle_registry = bundleregistry.get_registry()
for bundle in bundle_registry:
if bundle.get_show_launcher():
self.add_activity(bundle)
registry = activity.get_registry()
for activity_info in registry.get_activities():
if activity_info.show_launcher:
self.add_activity(activity_info)
bundle_registry.connect('bundle-added', self._bundle_added_cb)
registry.connect('activity-added', self._activity_added_cb)
for invite in self._invites:
self.add_invite(invite)
@ -93,19 +93,19 @@ class ActivitiesBox(hippo.CanvasBox):
def _invite_removed_cb(self, invites, invite):
self.remove_invite(invite)
def _bundle_added_cb(self, bundle_registry, bundle):
self.add_activity(bundle)
def _activity_added_cb(self, activity_registry, activity_info):
self.add_activity(activity_info)
def add_activity(self, activity):
item = ActivityButton(activity)
def add_activity(self, activity_info):
item = ActivityButton(activity_info)
item.connect('activated', self._activity_clicked_cb)
self.append(item, 0)
def add_invite(self, invite):
mesh = self._shell_model.get_mesh()
activity = mesh.get_activity(invite.get_activity_id())
activity_model = mesh.get_activity(invite.get_activity_id())
if activity:
item = InviteButton(activity, invite)
item = InviteButton(activity_model, invite)
item.connect('activated', self._invite_clicked_cb)
self.append(item, 0)

View File

@ -20,8 +20,8 @@ import gobject
from sugar.graphics.canvasicon import CanvasIcon
from sugar.graphics import style
from sugar.presence import presenceservice
from sugar import activity
from model import bundleregistry
from view.BuddyIcon import BuddyIcon
class FriendView(hippo.CanvasBox):
@ -46,9 +46,9 @@ class FriendView(hippo.CanvasBox):
self._buddy.connect('disappeared', self._buddy_disappeared_cb)
self._buddy.connect('color-changed', self._buddy_color_changed_cb)
def _get_new_icon_name(self, activity):
registry = bundleregistry.get_registry()
bundle = registry.get_bundle(activity.get_type())
def _get_new_icon_name(self, home_activity):
registry = activity.get_registry()
bundle = registry.get_bundle(home_activity.get_type())
if bundle:
return bundle.get_icon()
return None
@ -58,14 +58,14 @@ class FriendView(hippo.CanvasBox):
self.remove(self._activity_icon)
self._activity_icon_visible = False
def _buddy_activity_changed_cb(self, buddy, activity=None):
if not activity:
def _buddy_activity_changed_cb(self, buddy, home_activity=None):
if not home_activity:
self._remove_activity_icon()
return
# FIXME: use some sort of "unknown activity" icon rather
# than hiding the icon?
name = self._get_new_icon_name(activity)
name = self._get_new_icon_name(home_activity)
if name:
self._activity_icon.props.icon_name = name
self._activity_icon.props.xo_color = buddy.get_color()
@ -76,8 +76,8 @@ class FriendView(hippo.CanvasBox):
self._remove_activity_icon()
def _buddy_appeared_cb(self, buddy):
activity = self._buddy.get_current_activity()
self._buddy_activity_changed_cb(buddy, activity)
home_activity = self._buddy.get_current_activity()
self._buddy_activity_changed_cb(buddy, home_activity)
def _buddy_disappeared_cb(self, buddy):
self._buddy_activity_changed_cb(buddy, None)

View File

@ -296,11 +296,8 @@ class Bundle:
raise ZipExtractException
self._init_with_path(bundle_path)
bus = dbus.SessionBus()
proxy_obj = bus.get_object(_DBUS_SHELL_SERVICE, _DBUS_SHELL_PATH)
dbus_service = dbus.Interface(proxy_obj, _DBUS_ACTIVITY_REGISTRY_IFACE)
if not dbus_service.AddBundle(bundle_path):
if not activity.get_registry().add_bundle(bundle_path):
raise RegistrationException
def deinstall(self):

View File

@ -19,6 +19,7 @@
import logging
import dbus
import gobject
_ACTIVITY_REGISTRY_SERVICE_NAME = 'org.laptop.ActivityRegistry'
_ACTIVITY_REGISTRY_IFACE = 'org.laptop.ActivityRegistry'
@ -28,17 +29,25 @@ def _activity_info_from_dict(info_dict):
if not info_dict:
return None
return ActivityInfo(info_dict['name'], info_dict['icon'],
info_dict['service_name'], info_dict['path'])
info_dict['service_name'], info_dict['path'],
info_dict['show_launcher'])
class ActivityInfo(object):
def __init__(self, name, icon, service_name, path):
def __init__(self, name, icon, service_name, path, show_launcher):
self.name = name
self.icon = icon
self.service_name = service_name
self.path = path
self.show_launcher = show_launcher
class ActivityRegistry(object):
class ActivityRegistry(gobject.GObject):
__gsignals__ = {
'activity-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
def __init__(self):
gobject.GObject.__init__(self)
bus = dbus.SessionBus()
bus_object = bus.get_object(_ACTIVITY_REGISTRY_SERVICE_NAME,
_ACTIVITY_REGISTRY_PATH)
@ -57,6 +66,10 @@ class ActivityRegistry(object):
return result
def get_activities(self):
info_list = self._registry.GetActivities()
return self._convert_info_list(info_list)
def get_activity(self, service_name):
if self._service_name_to_activity_info.has_key(service_name):
return self._service_name_to_activity_info[service_name]
@ -81,10 +94,14 @@ class ActivityRegistry(object):
self._mime_type_to_activities[mime_type] = activities
return activities
def _activity_added_cb(self, bundle):
def add_bundle(self, bundle_path):
return self._registry.AddBundle(bundle_path)
def _activity_added_cb(self, info_dict):
logging.debug('ActivityRegistry._activity_added_cb: flushing caches')
self._service_name_to_activity_info.clear()
self._mime_type_to_activities.clear()
self.emit('activity-added', _activity_info_from_dict(info_dict))
_registry = None