import dbus from .engine import Engine from .dbustools import remote_call from .TProbe import ProbeManager import logging LOGGER = logging.getLogger("sugar.tutorius.service") _DBUS_SERVICE = "org.tutorius.Service" _DBUS_PATH = "/org/tutorius/Service" _DBUS_SERVICE_IFACE = "org.tutorius.Service" class Service(dbus.service.Object): """ Global tutorius entry point to control the whole system """ def __init__(self): bus = dbus.SessionBus() bus_name = dbus.service.BusName(_DBUS_SERVICE, bus=bus) dbus.service.Object.__init__(self, bus_name, _DBUS_PATH) self._engine = None self._probeMgr = ProbeManager() def start(self): """ Start the service itself """ # For the moment there is nothing to do LOGGER.debug("Service.start()") @dbus.service.method(_DBUS_SERVICE_IFACE, in_signature="s", out_signature="") def launch(self, tutorialID): """ Launch a tutorial @param tutorialID unique tutorial identifier used to retrieve it from the disk """ if self._engine == None: self._engine = Engine(self._probeMgr) self._engine.launch(tutorialID) @dbus.service.method(_DBUS_SERVICE_IFACE, in_signature="", out_signature="") def stop(self): """ Stop the current tutorial """ self._engine.stop() @dbus.service.method(_DBUS_SERVICE_IFACE, in_signature="", out_signature="") def pause(self): """ Interrupt the current tutorial and save its state in the journal """ self._engine.pause() @dbus.service.method(_DBUS_SERVICE_IFACE, in_signature="ss", out_signature="") def register_probe(self, process_name, unique_id): """ Adds a probe to the known probes, to be used by a tutorial. A generic name for a process (like an Activity) is passed so that the execution of a tutorial will use that generic name. However, a unique id is also passed to differentiate between many instances of the same process. @param process_name The generic name of a process @param unique_id The unique identification associated to this process """ LOGGER.debug("Service.register_probe(%s,%s)", process_name, unique_id) self._probeMgr.register_probe(process_name, unique_id) @dbus.service.method(_DBUS_SERVICE_IFACE, in_signature="s", out_signature="") def unregister_probe(self, unique_id): """ Remove a probe from the known probes. @param process_name The generic name of a process @param unique_id The unique identification associated to this process """ LOGGER.debug("Service.unregister_probe(%s)", unique_id) self._probeMgr.unregister_probe(unique_id) class ServiceProxy: """ Proxy to connect to the Service object, abstracting the DBus interface""" def __init__(self): bus = dbus.SessionBus() self._object = bus.get_object(_DBUS_SERVICE,_DBUS_PATH) self._service = dbus.Interface(self._object, _DBUS_SERVICE_IFACE) def launch(self, tutorialID): """ Launch a tutorial @param tutorialID unique tutorial identifier used to retrieve it from the disk """ remote_call(self._service.launch, (tutorialID, ), block=False) def stop(self): """ Stop the current tutorial """ remote_call(self._service.stop, (), block=False) def pause(self): """ Interrupt the current tutorial and save its state in the journal """ remote_call(self._service.pause, (), block=False) def register_probe(self, process_name, unique_id): """ Adds a probe to the known probes, to be used by a tutorial. A generic name for a process (like an Activity) is passed so that the execution of a tutorial will use that generic name. However, a unique id is also passed to differentiate between many instances of the same process. @param process_name The generic name of a process @param unique_id The unique identification associated to this process """ remote_call(self._service.register_probe, (process_name,unique_id), block=False) def unregister_probe(self, unique_id): """ Remove a probe from the known probes. @param process_name The generic name of a process @param unique_id The unique identification associated to this process """ # We make it synchronous because otherwise on closing, # activities kill the dbus session bus too fast for the # asynchronous call to be completed self._service.unregister_probe(unique_id) if __name__ == "__main__": import dbus.mainloop.glib import gobject loop = gobject.MainLoop() dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) s = Service() loop.run()