Activity bundles: Difference between revisions

From OLPC
Jump to navigation Jump to search
(Clarifying comment on the exec line)
 
(100 intermediate revisions by 44 users not shown)
Line 1: Line 1:
{{Migrated to sl.o | http://wiki.sugarlabs.org/go/Development_Team/Almanac/Activity_Bundles}}
= Introduction =
{{Developers}}
Every activity in the [[Sugar]] environment is packaged into a self-contained "bundle". The bundle contains all the resources and executable code (other than system-provided base libraries) which the activity needs to execute. Any resources or executable code that is not provided by the base system must be packaged within the bundle.
{{Translations}}

== Introduction ==

[[Activities]] in the [[Sugar]] environment are packaged into a self-contained '''"bundles"'''. Each bundle contains all the resources and executable code (other than system-provided base libraries) which the activity needs to execute. Any resources or executable code that is not provided by the base system must be packaged within the bundle. Activity bundles are the end result of, and use a different directory structure than, [[Creating_an_activity|activity development]]

; See also
* [[OLPC Bitfrost]] in general and its section on [[OLPC Bitfrost#Software installation|software installation]]
* [[OLPC Human Interface Guidelines/Activities|HIG-Activities]] and its section on [[OLPC Human Interface Guidelines/Activities/Activity Bundles|activity bundles]]
* [[Creating an activity]]

== Rationale ==


= Rationale =
Activities are meant to be shared between children. If a child doesn't have the activity, it is automatically transfered to the child when he or she joins the shared activity. Packaging activities in self-contained bundles allows easy sharing, installation, removal, and backup.
Activities are meant to be shared between children. If a child doesn't have the activity, it is automatically transfered to the child when he or she joins the shared activity. Packaging activities in self-contained bundles allows easy sharing, installation, removal, and backup.


= Location =
== Location ==

Activities are installed and removed automatically by [[Sugar]], in response to user actions. Sugar places activities in directory of its choice. Activities should not rely on being installed in a specific location, and should use relative paths where paths are necessary (i.e., for shared library linkage, activity resources such as images, sounds, etc). They should also not rely on the bundle's base directory name remaining the same. Sugar may rename the activity bundle base directory at any time to prevent bundle conflicts.
Activities are installed and removed automatically by [[Sugar]], in response to user actions. Sugar places activities in directory of its choice. Activities should not rely on being installed in a specific location, and should use relative paths where paths are necessary (i.e., for shared library linkage, activity resources such as images, sounds, etc). They should also not rely on the bundle's base directory name remaining the same. Sugar may rename the activity bundle base directory at any time to prevent bundle conflicts.


Currently Sugar on jhbuild looks for bundles in the "activities" subfolders of XDG_DATA_DIRS. Right now this is /usr/share/activities and the usr/share/activities subfolder of the jhbuild build folder.
Currently Sugar on jhbuild looks for bundles in the "activities" subfolders of XDG_DATA_DIRS. Right now this is /usr/share/activities and the usr/share/activities subfolder of the jhbuild build folder.


Sugar will automatically generate and remove the .service files necessary to launch the activity through D-Bus service activation when the activity is installed or removed.
Sugar will automatically generate and remove the .service files necessary to launch the activity through [[D-BUS]] service activation when the activity is installed or removed.


Activities should also NEVER store local state or preferences in the activity bundle itself. These should always be stored in an activity-specific directory in the user's sugar profile, available through the SUGAR_PROFILE environment variable.
Activities should also NEVER store local state or preferences in the activity bundle itself. These should always be stored in an activity-specific directory in the user's sugar profile, available through the SUGAR_PROFILE environment variable.
Line 18: Line 30:
profile_path = sugar.env.get_profile_path()
profile_path = sugar.env.get_profile_path()


= Bundle Structure =
== Bundle structure ==

The activity bundle is a directory, with a name ending in ".activity". Each activity bundle must, in a subdirectory called 'activity', contain a file named "activity.info", and following a special format. For example:
The activity bundle is a directory, with a name ending in ".activity". Each activity bundle must, in a subdirectory called 'activity', contain a file named "activity.info", and following a special format. For example:


Web.activity/
Web.activity/
activity/
activity/
activity.info
activity.info (activity info file)
activity-web.svg
activity-web.svg (icon for activity as specified in activity.info)
mimetypes.xml (map documents to MIME types)
localized/
text-plain.svg (icons for documents, e.g. "text-plain.svg" for "text/plain")
de_DE.linfo
zh_CN.linfo
text-html.svg
contents (manifest for bundle contents)
images/
contents.sig (credentials for signed bundle)
sounds/
permissions.info (optional; '''not a stable API''')
bin/
bin/
web-activity (launcher script or activity executable)
locale/
de_DE/
activity.linfo (localized info 1)
zh_CN/
activity.linfo (localized info 2)
lib/
mylib.so (native library)
icons/


; activity
(the images, sounds, and bin subdirectories are not required, but are shown as examples of how an activity may wish to organize its resources)
All metadata about the activity is organized in this subdirectory. The <code>contents</code> and <code>contents.sig</code> are manifest and credential files for the entire bundle contents (excepting the <code>contents</code> and <code>contents.sig</code> files themselves), as described by the [[Manifest Specification]]. The optional <code>mimetypes.xml</code> file is a [http://freedesktop.org/wiki/Specifications/shared-mime-info-spec freedesktop.org MIME type file] describing how to recognize the MIME types defined by the activity. SVG icons for those MIME types can be put in this directory as well.


;bin
All metadata about the activity is organized in the 'activity' subdirectory of the activity bundle.


Contains executables, is added to the PATH environment variable.
The 'activity/localized/' directory contains localizations of the activity bundle's name. It must be present.


;lib
= .info File Format =


See [[#Bundling native libraries]] below.
.info files follow a key/value pair format, similar to the [http://www.freedesktop.org/wiki/Standards_2fdesktop_2dentry_2dspec Desktop Entry standard], but not conforming to it. An example is shown here:

;locale

See [[#Activity name localization/translation]] below.

; icons
Contains the icons used by the activity. When using the sugar.activity python package the path is automatically added to the default [http://www.pygtk.org/docs/pygtk/class-gtkicontheme.html gtk icon theme].

== .info file format ==

.info files follow a key/value pair format, similar to the [http://www.freedesktop.org/wiki/Specifications/desktop-entry-spec fd.o desktop entry spec], but not conforming to it. An example is shown here:


[Activity]
[Activity]
Line 46: Line 81:
activity_version = 1
activity_version = 1
host_version = 1
host_version = 1
service = com.redhat.Sugar.BrowserActivity
bundle_id = com.redhat.Sugar.BrowserActivity
license = GPLv2+ and BSD
icon = activity-web
icon = activity-web
exec = sugar-activity-factory com.redhat.Sugar.BrowserActivity BrowserActivity.BrowserActivity
exec = sugar-activity browseractivity.BrowserActivity -s
mime_types = application/pdf;image/tiff
show_launcher = yes
update_url = http://host.net/bundles/FooBar


A more detailed explanation of each line follows:
A more detailed explanation of the valid properties follows:


[Activity]
[Activity]
Line 60: Line 97:


activity_version = 1
activity_version = 1
: Each activity.info file must have a "activity_version" key. The version is a single positive integer, and may only contain the characters 1 through 9. Larger versions are considered "newer". The value assigned to this key should be considered '''opaque''' to the activity; the only requirement of the activity is that it must be larger for new activity builds.
: Each activity.info file must have a "activity_version" key. The version is a single positive integer. Larger versions are considered "newer". The value assigned to this key should be considered '''opaque''' to the activity; the only requirement of the activity is that it must be larger for new activity builds.


host_version = 1
host_version = 1
: Each activity.info file must have a "host_version" key. The version is a single positive integer, and may only contain the characters 1 through 9. This specifies the version of the Sugar environment which the activity is compatible with. (fixme: need to specify sugar versions somewhere. Obviously we start with 1.)
: Each activity.info file must have a "host_version" key. The version is a single positive integer. This specifies the version of the Sugar environment which the activity is compatible with. (fixme: need to specify sugar versions somewhere. Obviously we start with 1.)


service = com.redhat.Sugar.BrowserActivity
bundle_id = com.redhat.Sugar.BrowserActivity
: This is the activity bundle identifier. It is required. The name should conform to the [http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names D-Bus spec] - in particular, hyphens are not allowed (although this wasn't enforced in earlier builds, see [http://dev.laptop.org/ticket/6226 Trac 6226]). It is recommended that [http://en.wikipedia.org/wiki/Java_package#Package_naming_conventions Java package naming conventions] are used when chosing bundle identifiers, to ensure uniqueness. Briefly, your name should begin with the reversed domain name of an organization you belong to.
: This is the activity's dbus service name. It is required. It is also used as the activity's default service type when the activity is shared on the network. To determine this type, the distince parts (separated by the '.' character) are reversed, any '.' is replaced by a '_' character, and the type is prefixed by a '_' character. So in this example, the default service type would be "_BrowserActivity_Sugar_redhat_com".
: The reversed domain name part is supposed to be rooted in some actual DNS-rooted namespace. You don't need to own this domain; you just need to have a reasonable claim on some ''unique'' name at that domain. There are several ways to derive one:
:* If your email address is ''yourname''@''somemailhost''.com, then you could use ''com.somemailhost.yourname''.''YourActivity''.
:* You could set up a web page on a free hosting service with information about your activity, and use a name derived from its URL. For example, if you create a page at http://www.geocities.com/xotumusica for your activity, then com.geocities.www.xotumusica is a reasonable bundle_id.
:* If nothing else is available, even org.laptop.wiki.''YourActivityPageTitle'' is probably a reasonable bundle_id, provided that you create the [[YourActivityPageTitle]] page. Remember, bundle_ids should be unique, so you should double check that the [[YourActivityPageTitle]] page doesn't already exist (and then create it) before using this as your bundle_id.
: In the Python bindings, the bundle_id is also used as the activity's default service type when the activity is shared on the network. To determine this type, the distinct parts (separated by the '.' character) are reversed, any '.' is replaced by a '_' character, and the type is prefixed by a '_' character. So in this example, the default service type would be "_BrowserActivity_Sugar_redhat_com".

license = GPLv2+ and BSD
: This field names the license used for the activity bundle (the binary .xo file). The contents of this field should conform to the same guidelines as the [http://fedoraproject.org/wiki/Packaging/LicensingGuidelines#License:_field <code>License:</code> field] of an RPM package; consult the [http://fedoraproject.org/wiki/Packaging/LicensingGuidelines Fedora Licensing Guidelines] for more information. A 'license' field naming an entry or entries in the "Good Licenses" table at [http://fedoraproject.org/wiki/Licensing Fedora's Licensing list] is required for any activities distributed by OLPC.


icon = activity-web
icon = activity-web
: This key is optional. It points to the activity's icon. The icon is first searched for in the activity bundle's base directory, and if not found, is looked up in the current GTK icon theme. It cannot contain a path. When searching for the icon in the activity bundle's base directory, only an file with the icon name and the extension '.svg' is looked for.
: It points to the activity's icon. The icon is looked up in the activity bundle's 'activity' directory (the same directory the activity.info file is in). It cannot contain a path. When searching for the icon in the activity bundle's 'activity' directory, only a file with the icon name and the extension '.svg' will be looked for. This property is required unless 'show_launcher' is 'no' (see below).

exec = sugar-activity webactivity.WebActivity
: The exec key specifies the executable which [[Sugar]] runs to start the activity instances. In the above example, "webactivity" refers to a file webactivity.py in the activity bundle directory and "WebActivity" refers to a class contained in that file. Environment variables given on the exec line are expanded. Executable files should be placed into the bin/ directory in the bundle. It should support the following arguments:

; -b, --bundle-id : Identifier of the activity bundle
; -a, --activity-id : Identifier of the activity instance.
; -o, --object-id : Identifier of the associated datastore object.
; -u, --uri : URI to load.

Python activities should generally use the generic sugar-activity executable. Other activities need to adhere to the [[Low-level Activity API]].


mime_types = application/pdf;image/tiff
exec = sugar-activity-factory com.redhat.Sugar.BrowserActivity BrowserActivity.BrowserActivity
: List of mime types supported by the activity, separated by semi colons. It's used when opening a file from the web or to present to the user a list of activities which can open a certain journal object.
: The exec key are used when [[Sugar]] installs the activity. It specifies the executable which [[Sugar]] runs to start the activity's factory service. A factory service spawns instances of the actual activity. A factory service for Python-based activities is provided with [[Sugar]].


show_launcher = yes
show_launcher = yes
: This key is optional. If not present, or if present with a value of "yes", the activity is shown with its icon in the [[Sugar]] panel launcher and a valid 'icon' key/value pair is required. If specified with a value of "no", the activity is not shown in the [[Sugar]] panel launcher, and the 'icon' key is not required.
: This key is optional. If not present, or if present with a value of "yes", the activity is shown with its icon in the [[Sugar]] panel launcher and a valid 'icon' key/value pair is required. If specified with a value of "no", the activity is not shown in the [[Sugar]] panel launcher, and the 'icon' key is not required.


update_url = ...
= Activity Name Localization/Translation =
Localizated data lives in the activity/localized/ directory. Localized keys from the 'activity.info' file are stored in the '.linfo' files in that directory. Each language stores its localized keys in a <u>separate</u> '.linfo' file named for the language's ISO code. For example, German-localized German (as opposed to Swiss-localized German) language translations are stored in the 'de_DE.linfo' file.


: URL to retrieve update information; implemented in <trac>4951</trac>. The [[software update]] control panel will attempt to look for information about the latest version of the activity by fetching the given url with first the core OS build number, then the release number, then the release major version number appended, then finally as-is. (For example, if your update URL tag has the value 'http://host.net/bundles/FooBar' and you are currently running release 8.2.1 (build 802), the following URLs will be tried, in this order: http://host.net/bundles/FooBar/802, http://host.net/bundles/FooBar/8.2.1 &mdash; ''Note:'' Software update in 8.2.1 '''does not''' look for this "dot-dot" version of update URLs, see <trac>9317</trac>), http://host.net/bundles/FooBar/8.2, http://host.net/bundles/FooBar .) The contents of the URLs should be in the [[activity microformat]]. If no update_url is specified, http://wiki.laptop.org/go/Activities will be used with the same sequence of appended values (''Note'' that as of June 2009 there are no subpages of the [[Activities]] page with these version suffixes; instead it transcludeds the [[Activities/G1G1/8.2]] list of activities, thus specifying the 8.2 versions of the G1G1 activity group for all updates). See [[Software update]] for more information.
At this time, only translations for the 'name' and 'icon' keys from the 'activity.info' file are supported. A localized 'de_DE.linfo' file would look like:


===Future properties===
name = Web
There are properties anticipated to be used by future Sugar versions. In general, Sugar will ignore unknown properties, and use defaults for missing properties.


tags = ...
'icon' keys only need to be localized when the icon itself includes language- or culture-specific material. For example, if the icon was the first letter of a word, that word may be different in other languages and therefore would need to be localized.
: List of tags to categorize this activity. Not yet implemented, see [http://dev.laptop.org/ticket/6634 #6634].

== Activity name localization/translation ==

Localized data lives in the locale directory. Each language stores its localized keys in a <u>separate</u> directory named for the language's ISO code. Localized keys from the 'activity.info' file are stored in the 'activity.linfo' files in that directory. For example, German-localized German (as opposed to Swiss-localized German) language translations are stored in the 'de_DE/activity.linfo' file:

Example.activity/
exampleactivity.py
activity/
activity.info
locale/
de_DE/
activity.linfo
de_CH/
activity.linfo
es/
activity.linfo

At this time, only translations for the 'name' key from the 'activity.info' file is supported. A localized 'de_DE/activity.linfo' file would look like:

[Activity]
name = Web


Keys in the languague-specific '.linfo' files selectively override keys from the 'activity.info' file; if a key is not present in the '.linfo' file the value from the 'activity.info' file is used instead.
Keys in the languague-specific '.linfo' files selectively override keys from the 'activity.info' file; if a key is not present in the '.linfo' file the value from the 'activity.info' file is used instead.

== Package, extension, mime type ==

Activity bundles should be packaged as zip files with the ".xo" extension. The mime type in the journal is "application/vnd.olpc-sugar".

== Bundling native libraries ==

Sometimes you need to include a native library or two with your activity. The strategy that [[Develop]] and [[Model]] use is specifying a shell script for the executable in the .info file:

exec = ./model_startup.sh

The script, 'model_startup.sh', modifies the library path, python, or both paths (depending on the types of libraries you are including) to reference folders inside your bundle, then launches your application:

#!/bin/sh
export PYTHONPATH=$SUGAR_BUNDLE_PATH/site-packages:$PYTHONPATH
export LD_LIBRARY_PATH=$SUGAR_BUNDLE_PATH/lib:$LD_LIBRARY_PATH
sugar-activity model_app.ModelActivity

Make sure to add your shell script and any native libraries to the MANIFEST before you package your bundle. You can also accomplish the same thing by throwing all your libraries in the root folder of the bundle, like the [[Map_(activity)|Map activity]] does, but if you have more than a few libraries to include it can get quite cluttered.

== activity/permissions.info ==

'''Note: the API described in this section is NOT STABLE and will probably change in future releases; perhaps drastically.'''

Bitfrost describes a variety of security-related settings which activity authors can specify about their activity. At the option of the activity author, these settings can be described in a file called 'permissions.info' which can be placed alongside 'activity.info' in the 'activity' directory of the bundle.

As of rainbow-0.7.21, writing the single line

constant-uid

into the permissions.info file will result in your activity being launched with the same uid each time it is run. (Usually each activity gets a constant gid, but each instance launched of the activity gets a unique uid. Activities based on the xulrunner codebase, however, tend to set restrictive group permissions on local files, so this option avoids this problem at the cost of less isolation between activity instances.)

As of rainbow-0.7.22, the line:

use-serial

will add the activity UIDs to the 'uucp' group, so that the activity can access /dev/ttyUSB* devices. (See <trac>8434</trac>.)

Other options which may be specified include:

lim_nofile 20
lim_fsize 10e6
lim_nproc 8
lim_mem 190e6

which will limit the number of file descriptors, the maximum writable file size, the number of processes, and the maximum size of the activity's address space, respectively. (See <tt>[http://linux.die.net/man/2/setrlimit man 2 setrlimit]</tt> for details.)

== Other technologies comparison ==

Activity bundles are similar to OS X bundles or [[Java JAR files]]; a simple mechanism to encapsulate everything you need in a single directory that can be moved around independently.

It differs from autopackage, it's not a package management system. There's no central database, no scripts get run on install/uninstall. There also is no special file format.

As compared to klik, it's not intended to replicate a local Unix directory structure inside the package; the activity can still link to system
provided binaries and such. There's also no server-side component other than compressing the archive and sending it over the network.There is also no dependency checking since activities are required to be self-contained.

== See also ==

* [[Bundle]] for a generic introduction to bundles
* [[Activity tutorial]]

[[Category:API]]
[[Category:Developers]]
[[Category:Software development]]
[[Category:File formats]]
[[Category:Activity installation]]

Latest revision as of 05:03, 23 August 2012

542-stopicon.png    This page has been migrated to the Sugar Labs wiki.
This is an archive (and likely, out-of-date) copy of material found at http://wiki.sugarlabs.org/go/Development_Team/Almanac/Activity_Bundles .
Please edit and comment on it there.
If you disagree with its migration, please explain why on its talk page.
  english | 한국어 HowTo [ID# 273751]  +/-  


Introduction

Activities in the Sugar environment are packaged into a self-contained "bundles". Each bundle contains all the resources and executable code (other than system-provided base libraries) which the activity needs to execute. Any resources or executable code that is not provided by the base system must be packaged within the bundle. Activity bundles are the end result of, and use a different directory structure than, activity development

See also

Rationale

Activities are meant to be shared between children. If a child doesn't have the activity, it is automatically transfered to the child when he or she joins the shared activity. Packaging activities in self-contained bundles allows easy sharing, installation, removal, and backup.

Location

Activities are installed and removed automatically by Sugar, in response to user actions. Sugar places activities in directory of its choice. Activities should not rely on being installed in a specific location, and should use relative paths where paths are necessary (i.e., for shared library linkage, activity resources such as images, sounds, etc). They should also not rely on the bundle's base directory name remaining the same. Sugar may rename the activity bundle base directory at any time to prevent bundle conflicts.

Currently Sugar on jhbuild looks for bundles in the "activities" subfolders of XDG_DATA_DIRS. Right now this is /usr/share/activities and the usr/share/activities subfolder of the jhbuild build folder.

Sugar will automatically generate and remove the .service files necessary to launch the activity through D-BUS service activation when the activity is installed or removed.

Activities should also NEVER store local state or preferences in the activity bundle itself. These should always be stored in an activity-specific directory in the user's sugar profile, available through the SUGAR_PROFILE environment variable.

Python developers can also get the profile folder this way:

import sugar.env
profile_path = sugar.env.get_profile_path()

Bundle structure

The activity bundle is a directory, with a name ending in ".activity". Each activity bundle must, in a subdirectory called 'activity', contain a file named "activity.info", and following a special format. For example:

Web.activity/
    activity/
        activity.info                          (activity info file)
        activity-web.svg                       (icon for activity as specified in activity.info)
        mimetypes.xml                          (map documents to MIME types)
        text-plain.svg                         (icons for documents, e.g. "text-plain.svg" for "text/plain")
        text-html.svg
        contents                               (manifest for bundle contents)
        contents.sig                           (credentials for signed bundle)
        permissions.info                       (optional; not a stable API)
    bin/
        web-activity                           (launcher script or activity executable)
    locale/
        de_DE/
            activity.linfo                     (localized info 1)
        zh_CN/
            activity.linfo                     (localized info 2)
    lib/
        mylib.so                               (native library)
    icons/
activity

All metadata about the activity is organized in this subdirectory. The contents and contents.sig are manifest and credential files for the entire bundle contents (excepting the contents and contents.sig files themselves), as described by the Manifest Specification. The optional mimetypes.xml file is a freedesktop.org MIME type file describing how to recognize the MIME types defined by the activity. SVG icons for those MIME types can be put in this directory as well.

bin

Contains executables, is added to the PATH environment variable.

lib

See #Bundling native libraries below.

locale

See #Activity name localization/translation below.

icons

Contains the icons used by the activity. When using the sugar.activity python package the path is automatically added to the default gtk icon theme.

.info file format

.info files follow a key/value pair format, similar to the fd.o desktop entry spec, but not conforming to it. An example is shown here:

[Activity]
name = Web
activity_version = 1
host_version = 1
bundle_id = com.redhat.Sugar.BrowserActivity
license = GPLv2+ and BSD
icon = activity-web
exec = sugar-activity browseractivity.BrowserActivity -s
mime_types = application/pdf;image/tiff
update_url = http://host.net/bundles/FooBar

A more detailed explanation of the valid properties follows:

[Activity]
The activity.info file must begin with [Activity], and only that, on the first line of the file
name = Web
This is the name is displayed in Sugar referring to the activity. A 'name' key without a bracketed language code is the "en_US" localized name of the activity. The activity.info file must have this key.
activity_version = 1
Each activity.info file must have a "activity_version" key. The version is a single positive integer. Larger versions are considered "newer". The value assigned to this key should be considered opaque to the activity; the only requirement of the activity is that it must be larger for new activity builds.
host_version = 1
Each activity.info file must have a "host_version" key. The version is a single positive integer. This specifies the version of the Sugar environment which the activity is compatible with. (fixme: need to specify sugar versions somewhere. Obviously we start with 1.)
bundle_id = com.redhat.Sugar.BrowserActivity
This is the activity bundle identifier. It is required. The name should conform to the D-Bus spec - in particular, hyphens are not allowed (although this wasn't enforced in earlier builds, see Trac 6226). It is recommended that Java package naming conventions are used when chosing bundle identifiers, to ensure uniqueness. Briefly, your name should begin with the reversed domain name of an organization you belong to.
The reversed domain name part is supposed to be rooted in some actual DNS-rooted namespace. You don't need to own this domain; you just need to have a reasonable claim on some unique name at that domain. There are several ways to derive one:
  • If your email address is yourname@somemailhost.com, then you could use com.somemailhost.yourname.YourActivity.
  • You could set up a web page on a free hosting service with information about your activity, and use a name derived from its URL. For example, if you create a page at http://www.geocities.com/xotumusica for your activity, then com.geocities.www.xotumusica is a reasonable bundle_id.
  • If nothing else is available, even org.laptop.wiki.YourActivityPageTitle is probably a reasonable bundle_id, provided that you create the YourActivityPageTitle page. Remember, bundle_ids should be unique, so you should double check that the YourActivityPageTitle page doesn't already exist (and then create it) before using this as your bundle_id.
In the Python bindings, the bundle_id is also used as the activity's default service type when the activity is shared on the network. To determine this type, the distinct parts (separated by the '.' character) are reversed, any '.' is replaced by a '_' character, and the type is prefixed by a '_' character. So in this example, the default service type would be "_BrowserActivity_Sugar_redhat_com".
license = GPLv2+ and BSD
This field names the license used for the activity bundle (the binary .xo file). The contents of this field should conform to the same guidelines as the License: field of an RPM package; consult the Fedora Licensing Guidelines for more information. A 'license' field naming an entry or entries in the "Good Licenses" table at Fedora's Licensing list is required for any activities distributed by OLPC.
icon = activity-web
It points to the activity's icon. The icon is looked up in the activity bundle's 'activity' directory (the same directory the activity.info file is in). It cannot contain a path. When searching for the icon in the activity bundle's 'activity' directory, only a file with the icon name and the extension '.svg' will be looked for. This property is required unless 'show_launcher' is 'no' (see below).
exec = sugar-activity webactivity.WebActivity
The exec key specifies the executable which Sugar runs to start the activity instances. In the above example, "webactivity" refers to a file webactivity.py in the activity bundle directory and "WebActivity" refers to a class contained in that file. Environment variables given on the exec line are expanded. Executable files should be placed into the bin/ directory in the bundle. It should support the following arguments:
-b, --bundle-id
Identifier of the activity bundle
-a, --activity-id
Identifier of the activity instance.
-o, --object-id
Identifier of the associated datastore object.
-u, --uri
URI to load.

Python activities should generally use the generic sugar-activity executable. Other activities need to adhere to the Low-level Activity API.

mime_types = application/pdf;image/tiff
List of mime types supported by the activity, separated by semi colons. It's used when opening a file from the web or to present to the user a list of activities which can open a certain journal object.
show_launcher = yes
This key is optional. If not present, or if present with a value of "yes", the activity is shown with its icon in the Sugar panel launcher and a valid 'icon' key/value pair is required. If specified with a value of "no", the activity is not shown in the Sugar panel launcher, and the 'icon' key is not required.
update_url = ...
URL to retrieve update information; implemented in <trac>4951</trac>. The software update control panel will attempt to look for information about the latest version of the activity by fetching the given url with first the core OS build number, then the release number, then the release major version number appended, then finally as-is. (For example, if your update URL tag has the value 'http://host.net/bundles/FooBar' and you are currently running release 8.2.1 (build 802), the following URLs will be tried, in this order: http://host.net/bundles/FooBar/802, http://host.net/bundles/FooBar/8.2.1Note: Software update in 8.2.1 does not look for this "dot-dot" version of update URLs, see <trac>9317</trac>), http://host.net/bundles/FooBar/8.2, http://host.net/bundles/FooBar .) The contents of the URLs should be in the activity microformat. If no update_url is specified, http://wiki.laptop.org/go/Activities will be used with the same sequence of appended values (Note that as of June 2009 there are no subpages of the Activities page with these version suffixes; instead it transcludeds the Activities/G1G1/8.2 list of activities, thus specifying the 8.2 versions of the G1G1 activity group for all updates). See Software update for more information.

Future properties

There are properties anticipated to be used by future Sugar versions. In general, Sugar will ignore unknown properties, and use defaults for missing properties.

tags = ...
List of tags to categorize this activity. Not yet implemented, see #6634.

Activity name localization/translation

Localized data lives in the locale directory. Each language stores its localized keys in a separate directory named for the language's ISO code. Localized keys from the 'activity.info' file are stored in the 'activity.linfo' files in that directory. For example, German-localized German (as opposed to Swiss-localized German) language translations are stored in the 'de_DE/activity.linfo' file:

Example.activity/
    exampleactivity.py
    activity/
        activity.info
    locale/
        de_DE/
            activity.linfo
        de_CH/
            activity.linfo
        es/
            activity.linfo

At this time, only translations for the 'name' key from the 'activity.info' file is supported. A localized 'de_DE/activity.linfo' file would look like:

[Activity]
name = Web

Keys in the languague-specific '.linfo' files selectively override keys from the 'activity.info' file; if a key is not present in the '.linfo' file the value from the 'activity.info' file is used instead.

Package, extension, mime type

Activity bundles should be packaged as zip files with the ".xo" extension. The mime type in the journal is "application/vnd.olpc-sugar".

Bundling native libraries

Sometimes you need to include a native library or two with your activity. The strategy that Develop and Model use is specifying a shell script for the executable in the .info file:

exec = ./model_startup.sh

The script, 'model_startup.sh', modifies the library path, python, or both paths (depending on the types of libraries you are including) to reference folders inside your bundle, then launches your application:

#!/bin/sh

export PYTHONPATH=$SUGAR_BUNDLE_PATH/site-packages:$PYTHONPATH
export LD_LIBRARY_PATH=$SUGAR_BUNDLE_PATH/lib:$LD_LIBRARY_PATH

sugar-activity model_app.ModelActivity

Make sure to add your shell script and any native libraries to the MANIFEST before you package your bundle. You can also accomplish the same thing by throwing all your libraries in the root folder of the bundle, like the Map activity does, but if you have more than a few libraries to include it can get quite cluttered.

activity/permissions.info

Note: the API described in this section is NOT STABLE and will probably change in future releases; perhaps drastically.

Bitfrost describes a variety of security-related settings which activity authors can specify about their activity. At the option of the activity author, these settings can be described in a file called 'permissions.info' which can be placed alongside 'activity.info' in the 'activity' directory of the bundle.

As of rainbow-0.7.21, writing the single line

 constant-uid

into the permissions.info file will result in your activity being launched with the same uid each time it is run. (Usually each activity gets a constant gid, but each instance launched of the activity gets a unique uid. Activities based on the xulrunner codebase, however, tend to set restrictive group permissions on local files, so this option avoids this problem at the cost of less isolation between activity instances.)

As of rainbow-0.7.22, the line:

 use-serial

will add the activity UIDs to the 'uucp' group, so that the activity can access /dev/ttyUSB* devices. (See <trac>8434</trac>.)

Other options which may be specified include:

lim_nofile 20
lim_fsize 10e6
lim_nproc 8
lim_mem 190e6

which will limit the number of file descriptors, the maximum writable file size, the number of processes, and the maximum size of the activity's address space, respectively. (See man 2 setrlimit for details.)

Other technologies comparison

Activity bundles are similar to OS X bundles or Java JAR files; a simple mechanism to encapsulate everything you need in a single directory that can be moved around independently.

It differs from autopackage, it's not a package management system. There's no central database, no scripts get run on install/uninstall. There also is no special file format.

As compared to klik, it's not intended to replicate a local Unix directory structure inside the package; the activity can still link to system provided binaries and such. There's also no server-side component other than compressing the archive and sending it over the network.There is also no dependency checking since activities are required to be self-contained.

See also