Low-level Activity API: Difference between revisions
No edit summary |
|||
Line 4: | Line 4: | ||
=Overview= |
=Overview= |
||
An [[Activity Bundle]] can specify an executable in the activity.info's <tt>exec</tt> field. |
An [[Activity Bundle]] can specify an executable in the activity.info's <tt>exec</tt> field. When launching an activity from Sugar shell, the specified executable is runned with the following parameters: |
||
; -a, --activity-id : Unique identifier of the activity instance. |
|||
The [[#Activity Factory|factory service]] provides a <tt>org.laptop.ActivityFactory.create()</tt> method which spawns an activity instance. Each activity instance has a unique <tt>activity_id</tt> which is passed as one of the parameters to the <tt>create()</tt> method. |
|||
; -o, --object-id : Unique identifier of the associated datastore object. |
|||
; -u, --uri : URI to load. |
|||
Each [[#Activity Instance|activity instance]] opens an X window. This window must have two string properties, <code>_SUGAR_BUNDLE_ID</code> specifying the service name and <code>_SUGAR_ACTIVITY_ID</code> which is the id that was passed to <code>create()</code>. The instance registers a DBus object at <tt>/org/laptop/Activity''id''</tt> where ''id'' is again the activity id. This object must implement the <tt>org.laptop.Activity</tt> interface. |
Each [[#Activity Instance|activity instance]] opens an X window. This window must have two string properties, <code>_SUGAR_BUNDLE_ID</code> specifying the service name and <code>_SUGAR_ACTIVITY_ID</code> which is the id that was passed to <code>create()</code>. The instance registers a DBus object at <tt>/org/laptop/Activity''id''</tt> where ''id'' is again the activity id. This object must implement the <tt>org.laptop.Activity</tt> interface. |
||
When the last activity instance exits, the factory service should quit. |
|||
=Activity Factory= |
=Activity Factory= |
Revision as of 14:29, 8 October 2007
Most activities will use the Python API to implement activities. This page will document the underlying mechanism that non-Python activities need to conform to.
This documentation effort was started by Bert while implementing the Squeak-based Etoys activity. Please fill in missing pieces and correct mistakes!
Overview
An Activity Bundle can specify an executable in the activity.info's exec field. When launching an activity from Sugar shell, the specified executable is runned with the following parameters:
- -a, --activity-id
- Unique identifier of the activity instance.
- -o, --object-id
- Unique identifier of the associated datastore object.
- -u, --uri
- URI to load.
Each activity instance opens an X window. This window must have two string properties, _SUGAR_BUNDLE_ID
specifying the service name and _SUGAR_ACTIVITY_ID
which is the id that was passed to create()
. The instance registers a DBus object at /org/laptop/Activityid where id is again the activity id. This object must implement the org.laptop.Activity interface.
Activity Factory
Service name: my.organization.MyActivity (from activity bundle info file)
Object path: /my/organization/MyActivity (derived from service name)
Interface: org.laptop.ActivityFactory
org.laptop.ActivityFactory.create(params)
The create() method creates a new Activity instance. That instance is exposed on the DBus as /org/laptop/Activity/123456 where the number 123456 is the instance's top-level window XID.
The params dictionary can have the following entries:
- activity_id
- unique id for the activity to be created
- pservice_id
- identity of the sharing service for this activity in the PresenceService
- object_id
- identity of the journal object associated with the activity. When you resume an activity from the journal the object_id will be passed in (see datastore).
- uri
- URI associated with the activity. Used when opening an external file or resource in the activity, rather than a journal object (downloads stored on the file system for example or web pages)
Activity Instance
Service name: org.laptop.Activity6f7f3acacca87886332f50bdd522d805f0abbf1f (where 6f7f3acacca87886332f50bdd522d805f0abbf1f is the activity id)
Object path: /org/laptop/Activity/6f7f3acacca87886332f50bdd522d805f0abbf1f (where 6f7f3acacca87886332f50bdd522d805f0abbf1f is the activity id)
Interface: org.laptop.Activity
X Properties
The activity instance needs to set some properties on its top-level window:
_SUGAR_BUNDLE_ID
The bundle id (e.g., my.organization.MyActivity) of type STRING.
_SUGAR_ACTIVITY_ID
The activity id (e.g., 6f7f3acacca87886332f50bdd522d805f0abbf1f) of type STRING.
This properties must to set before the window is showed on the screen, using the gtk realize event, for example.
Also, some Window Manager hints need to be set:
_NET_WM_NAME
should be set to the current activity title. It usually corresponds to the title which is displayed in the journal and advertised on the network for shared activities. See Freedesktop specification.
_NET_WM_PID
must be set to the activity's process id so the shell can associate memory usage with an activity. See Freedesktop specification.
Methods
An activity instance needs to support the following methods:
org.laptop.Activity.SetActive(active)
Activate or passivate an activity. Passive activities must release resources like sound, camera etc.
There used to be more methods but the API evolved so only this single one is remaining for now.
Datastore
An Activity instance must store its complete state in the central datastore so it appears in the Journal and can be resumed later. It needs to connect to the datastore service:
Service name: org.laptop.sugar.DataStore Object path: /org/laptop/sugar/DataStore Interface: org.laptop.sugar.DataStore
Keeping and Resuming
An item in the datastore is referenced by an object_id, it has a dictionary of properties, and possibly a file. The properties have String keys but Variant values. Here are a few properties:
'activity': 'my.organization.MyActivity' 'activity_id': '6f7f3acacca87886332f50bdd522d805f0abbf1f' 'title': 'My new project' 'title_set_by_user': '0' 'keep': '0' 'ctime': '1972-05-12T18:41:08' #created 'mtime': '2007-06-16T03:42:33' #modified 'buddies': array of buddies #not spec'ed yet 'preview': base64(png file data, 300x225 px) #temporarily Base64, will be a ByteArray 'icon-color': '#ff0000,#ffff00' 'mime_type': 'application/x-my-activity' 'summary:text': 'text I want to be indexed' #properties with key ending in ":text" will be searched in fulltext search
To create an item in the datastore, call create():
object_id = datastore.create(properties, filename)
If filename is not empty, the file will be copied to the datastore. The activity should delete the file once the call completes. The returned id will be a string like '4543af91-7be9-404e-b2f1-3e27cb15a15d'.
To update an item use update():
datastore.update(object_id, properties, filename)
Again, if a filename was given, it should be deleted when the call returns.
To retrieve an object's properties and file:
properties = datastore.get_properties(object_id) filename = datastore.get_filename(object_id)
The returned temp file should be deleted by the activity as soon as possible, latest when the activity quits.
Querying
Activities may query the datastore:
(results,count) = datastore.find(query)
It returns the results as array of properties and a count of matching items (the array may have less items if the query was limited). In addition to the usual metadata items, the properties will include the object id at key 'uid', the mountpoint of the item at key 'mountpoint', and possibly a 'filename' if requested.
The query can be a:
- string: fulltext search
- the given string is searched in all text properties
- dictionary: structured query
- the key-value pairs in the dictionary specify the value (or array of values, or dictionary specifying range) for a specific property, e.g.:
- 'title' = 'First Project'
- 'mime_type' = ['image/png', 'image/jpeg']
- 'mtime' = {'start' = '2007-07-01T00:00:00', 'end' = '2007-08-01T00:00:00'}
- also, there are a few specific keys to adjust the query:
- 'query': fulltext search term
- 'order_by': key (or array of keys) to order results by, to reverse order use '-key'
- 'limit', 'offset': return only limit results starting at offset
- 'mountpoints': array of mountpoint ids to search (or all if not specified)
- 'include_files': if true, generate files as if get_filename() had been called for each item. In results, a property 'filename' will be added.
- the key-value pairs in the dictionary specify the value (or array of values, or dictionary specifying range) for a specific property, e.g.:
You can also retrieve an array of unique values for a field:
values = datastore.get_uniquevaluesfor(property, query)
Note that currently (2007-07-25) the query is ignored in this call, it looks for all values in all entries.
Mount Points
Devices are represented as mount points in the datastore. If no mountpoint is explicitely specified, the main datastore (Journal) is used.
mounts = datastore.mounts()
Returns an array of mount point descriptiors where each descriptor is a dictionary containing at least the following keys:
- 'id': the id used to refer explicitly to the mount point
- 'title': Human readable identifier for the mountpoint
- 'uri': The uri which triggered the mount
Mount points can be specified when creating an object (using a 'mountpoint' key and id value in the properties), and when querying the datastore (by adding a 'mountpoints' query option).
Example
[Activity] name = My Activity activity_version = 1 host_version = 1 service_name = my.organization.MyActivity icon = activity-my exec = myactivityfactory show_launcher = yes
create factory service at my.organization.MyActivity
Signal /org/freedesktop/DBus org.freedesktop.DBus.NameAcquired(':1.23')
Signal /org/freedesktop/DBus org.freedesktop.DBus.NameAcquired('my.organization.MyActivity')
MethodCall /my/organization/MyActivity org.freedesktop.DBus.Introspectable.Introspect()
MethodCall /my/organization/MyActivity org.laptop.ActivityFactory.create(activity_id='6f7f3acacca87886332f50bdd522d805f0abbf1f')
launch new activity instance
create X window with _SUGAR_BUNDLE_ID='my.organization.MyActivity' and _SUGAR_ACTIVITY_ID='6f7f3acacca87886332f50bdd522d805f0abbf1f' and then show it
create instance dbus service at org.laptop.Activity6f7f3acacca87886332f50bdd522d805f0abbf1f
Signal /org/freedesktop/DBus org.freedesktop.DBus.NameAcquired(':1.24')
Signal /org/freedesktop/DBus org.freedesktop.DBus.NameAcquired('org.laptop.Activity6f7f3acacca87886332f50bdd522d805f0abbf1f')