Make activity launching asynchronous

The ActivityFactory create() method now returns a handler GObject,
which callers may attach signals to to receive success and error
signals from the result of the activity launch request.
master
Dan Williams 18 years ago
parent 8cea4c5fc6
commit fb716ae046

@ -127,7 +127,7 @@ class HomeModel(gobject.GObject):
del self._activities[act_id]
def _remove_activity(self, xid):
activity = self._get_activity_by_xid(window.get_xid())
activity = self._get_activity_by_xid(xid)
if activity:
self._internal_remove_activity(activity)
else:

@ -18,11 +18,19 @@
import sys
import os
import gobject
from sugar.activity import ActivityFactory
from sugar import env
from sugar import util
def _success_cb(handler, activity, loop):
activity.start(util.unique_id())
loop.quit()
def _error_cb(handler, err, loop):
loop.quit()
ppath = env.get_profile_path()
bus_file = os.path.join(ppath, "session_bus_address")
f = open(bus_file, "r")
@ -30,5 +38,10 @@ bus_name = f.read()
f.close()
os.environ['DBUS_SESSION_BUS_ADDRESS'] = bus_name
activity = ActivityFactory.create(sys.argv[1])
activity.start(util.unique_id())
loop = gobject.MainLoop()
handler = ActivityFactory.create(sys.argv[1])
handler.connect('success', _success_cb, loop)
handler.connect('error', _error_cb, loop)
loop.run()

@ -191,35 +191,41 @@ class Shell(gobject.GObject):
def get_model(self):
return self._model
def _join_success_cb(self, handler, activity, activity_ps, activity_id, activity_type):
logging.debug("Joining activity %s (%s)" % (activity_id, activity_type))
activity.join(activity_ps.object_path())
def _join_error_cb(self, handler, err, home_model, activity_id, activity_type):
logging.error("Couldn't launch activity %s (%s):\n%s" % (activity_id, activity_type, err))
home_mode.notify_activity_launch_failed(activity_id)
def join_activity(self, bundle_id, activity_id):
activity = self.get_activity(activity_id)
if activity:
activity.present()
else:
activity_ps = self._pservice.get_activity(activity_id)
if activity_ps:
# Get the service name for this activity, if
# we have a bundle on the system capable of handling
# this activity type
breg = self._model.get_bundle_registry()
bundle = breg.find_by_default_type(bundle_id)
if bundle:
act_type = bundle.get_service_name()
home_model = self._model.get_home()
home_model.notify_activity_launch(activity_id, act_type)
try:
activity = ActivityFactory.create(act_type)
except DBusException, e:
logging.error("Couldn't launch activity %s:\n%s" % (act_type, e))
home_mode.notify_activity_launch_failed(activity_id)
else:
logging.debug("Joining activity type %s id %s" % (act_type, activity_id))
activity.join(activity_ps.object_path())
else:
logging.error("Couldn't find activity for type %s" % bundle_id)
else:
logging.error('Cannot start activity.')
return
activity_ps = self._pservice.get_activity(activity_id)
if not activity_ps:
logging.error("Couldn't find shared activity for %s" % activity_id)
return
# Get the service name for this activity, if
# we have a bundle on the system capable of handling
# this activity type
breg = self._model.get_bundle_registry()
bundle = breg.find_by_default_type(bundle_id)
if not bundle:
logging.error("Couldn't find activity for type %s" % bundle_id)
return
act_type = bundle.get_service_name()
home_model = self._model.get_home()
home_model.notify_activity_launch(activity_id, act_type)
handler = ActivityFactory.create(act_type)
handler.connect('success', self._join_success_cb, activity_ps, activity_id, act_type)
handler.connect('error', self._join_error_cb, home_model, activity_id, act_type)
def _find_unique_activity_id(self):
# create a new unique activity ID
@ -251,6 +257,14 @@ class Shell(gobject.GObject):
return act_id
def _start_success_cb(self, handler, activity, activity_id, activity_type):
logging.debug("Started activity %s (%s)" % (activity_id, activity_type))
activity.start(activity_id)
def _start_error_cb(self, handler, err, home_model, activity_id, activity_type):
logging.error("Couldn't launch activity %s (%s):\n%s" % (activity_id, activity_type, err))
home_mode.notify_activity_launch_failed(activity_id)
def start_activity(self, activity_type):
logging.debug('Shell.start_activity')
act_id = self._find_unique_activity_id()
@ -261,16 +275,10 @@ class Shell(gobject.GObject):
home_model = self._model.get_home()
home_model.notify_activity_launch(act_id, activity_type)
try:
logging.debug("Shell.start_activity will start %s:%s" % (activity_type, act_id))
activity = ActivityFactory.create(activity_type)
except dbus.DBusException, e:
logging.debug("Couldn't start activity '%s':\n %s" % (activity_type, e))
home_mode.notify_activity_launch_failed(act_id)
return None
activity.start(act_id)
return activity
logging.debug("Shell.start_activity will start %s (%s)" % (act_id, activity_type))
handler = ActivityFactory.create(activity_type)
handler.connect('success', self._start_success_cb, act_id, activity_type)
handler.connect('error', self._start_error_cb, home_model, act_id, activity_type)
def set_zoom_level(self, level):
if level == sugar.ZOOM_ACTIVITY:

@ -40,22 +40,32 @@ class ClipboardIcon(MenuIcon):
else:
return None
def _activity_create_success_cb(self, handler, activity):
activity.start(util.unique_id())
activity.execute("open_document", [self._object_id])
def _activity_create_error_cb(self, handler, err):
pass
def _icon_activated_cb(self, icon):
if self._percent == 100:
cb_service = clipboardservice.get_instance()
(name, percent, icon, preview, format_types) = \
cb_service.get_object(self._object_id)
if self._percent < 100:
return
if format_types:
logging.debug("_icon_activated_cb: " + self._object_id)
activity_id = self._get_activity_for_mime_type(format_types[0])
if activity_id:
activity = ActivityFactory.create(activity_id)
activity.start(util.unique_id())
activity.execute("open_document", [self._object_id])
cb_service = clipboardservice.get_instance()
(name, percent, icon, preview, format_types) = \
cb_service.get_object(self._object_id)
if not format_types:
return
logging.debug("_icon_activated_cb: " + self._object_id)
activity_type = self._get_activity_for_mime_type(format_types[0])
if not activity_type:
return
# Launch the activity to handle this item
handler = ActivityFactory.create(activity_type)
handler.connect('success', self._activity_create_success_cb)
handler.connect('error', self._activity_create_error_cb)
def _popup_action_cb(self, popup, action):
self.popdown()

@ -76,24 +76,43 @@ class ActivityFactory(dbus.service.Object):
if len(self._activities) == 0:
gtk.main_quit()
def create(activity_name):
"""Create a new activity from his name."""
bus = dbus.SessionBus()
class ActivityCreationHandler(gobject.GObject):
__gsignals__ = {
'error': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT])),
'success': (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE,
([gobject.TYPE_PYOBJECT]))
}
factory_name = activity_name
factory_path = get_path(factory_name)
def __init__(self, activity_name):
gobject.GObject.__init__(self)
proxy_obj = bus.get_object(factory_name, factory_path)
factory = dbus.Interface(proxy_obj, "com.redhat.Sugar.ActivityFactory")
bus = dbus.SessionBus()
factory_name = activity_name
factory_path = get_path(factory_name)
xid = factory.create()
proxy_obj = bus.get_object(factory_name, factory_path)
factory = dbus.Interface(proxy_obj, "com.redhat.Sugar.ActivityFactory")
bus = dbus.SessionBus()
proxy_obj = bus.get_object(Activity.get_service_name(xid),
Activity.get_object_path(xid))
activity = dbus.Interface(proxy_obj, Activity.ACTIVITY_INTERFACE)
factory.create(reply_handler=self._reply_handler, error_handler=self._error_handler)
return activity
def _reply_handler(self, xid):
bus = dbus.SessionBus()
proxy_obj = bus.get_object(Activity.get_service_name(xid),
Activity.get_object_path(xid))
activity = dbus.Interface(proxy_obj, Activity.ACTIVITY_INTERFACE)
self.emit('success', activity)
def _error_handler(self, err):
logging.debug("Couldn't create activity: %s" % err)
self.emit('error', err)
def create(activity_name):
"""Create a new activity from its name."""
return ActivityCreationHandler(activity_name)
def start_factory(activity_class, bundle_path):
"""Start the activity factory."""

Loading…
Cancel
Save