13 This document describes what we intend to do. It may happen that our
14 current implementation and the content of this document differ.
16 In case of differences, it is assumed that this document is right
17 and the implementation is wrong.
23 The daemon **afm-user-daemon** is in charge of handling
24 applications for one user. Its main tasks are:
26 - enumerate the applications that the user can run
27 and keep the list avalable on demand
29 - start applications for the user, set their running
30 environment, set their security context
32 - list the current runner applications
34 - stop (aka pause), continue (aka resume), terminate
35 the running instance of application
37 - transfer requests for installation or uninstallation
38 of applications to the dedicated system daemon
41 The **afm-user-daemon** takes its orders from the session
44 The figure below summarizes the situation of the
45 **afm-user-daemon** in the system.
47 +------------------------------------------------------------+
49 | +---------------------+ |
50 | +---------------------+ | Smack isolated | |
51 | | D-Bus session + | APPLICATIONS | |
52 | +----------+----------+ +---------+-----------+ |
55 | +----------+--------------------------+-----------+ |
57 | | afm-user-daemon | |
59 | +----------+----------------------+----------+----+ |
62 :================|======================|==========:=========:
64 | +----------+----------+ +-----+-----+ : |
65 | | D-Bus system +-----+ CYNARA | : |
66 | +----------+----------+ +-----+-----+ : |
68 | +----------+---------+ +-------+----------+----+ |
69 | | afm-system-daemon +----+ SECURITY-MANAGER | |
70 | +--------------------+ +-----------------------+ |
73 +------------------------------------------------------------+
76 Tasks of **afm-user-daemon**
77 ----------------------------
79 ### Maintaining list of applications ###
81 At start **afm-user-daemon** scans the directories containing
82 the applications and load in memory the list applications
83 availables to the current user.
85 When **afm-system-daemon** installs or removes an application,
86 it sends the signal *org.AGL.afm.system.changed* on success.
87 If it receives that signal, **afm-user-daemon** rebuild its
90 **afm-user-daemon** provides the data that it collected about
91 application to its clients that either want to get that list
92 or to get information about one application.
94 ### Launching applications ###
96 **afm-user-daemon** launchs the applications. This means
97 that its builds a secure environment for the application
98 and then start it inside that secured environment.
100 Applications of different kind can be launched.
102 This is set using a configuration file that describes
103 how to launch an application of a given kind for a given
106 There is two launching modes: local or remote.
108 Launching an application locally means that
109 the application and its binder are launcher together.
111 Launching application remotely means that only the
112 binder is launched for the application.
114 Once launched, running instances of application receive
115 a runid that identify them.
117 ### Managing instances of running applications ###
119 **afm-user-daemon** manages the list of applications
122 With the good permissions, a client can get the list
123 of the running instances and details about a specific
124 running instance. It can also terminate, stop or
125 continue a given application.
127 ### Installing and uninstalling applications ###
129 If the client has the good permission,
130 **afm-user-daemon** delegates that task
131 to **afm-system-daemon**.
134 Starting **afm-user-daemon**
135 -----------------------------
137 **afm-user-daemon** is launched as a **systemd** service
138 attached to user sessions. Normally, the service file is
139 located at /usr/lib/systemd/user/afm-user-daemon.service.
141 The options for launching **afm-user-daemon** are:
144 --application directory
146 Includes the given application directory to
147 the database base of applications.
152 Includes the root application directory to
153 the database base of applications.
155 Note that the default root directory for
156 applications is always added. It is defined
157 to be /usr/share/afm/applications (may change).
160 --mode (local|remote)
162 Set the default launch mode.
163 The default value is 'local'
168 Daemonizes the process. It is not needed by sytemd.
173 Reduces the verbosity (can be repeated).
178 Increases the verbosity (can be repeated).
186 Configuration of the launcher
187 -----------------------------
189 It contains rules for launching applications.
190 When **afm-user-daemon** need to launch an application,
191 it looks to the mode of launch, local or remote, and the
192 type of the application as given by the file ***config.xml***
195 This couple mode and type allows to select the rule.
197 The configuration file is **/etc/afm/afm-launch.conf**.
199 It contains sections and rules. It can also contain comments
200 and empty lines to improve the readability.
202 The separators are space and tabulation, any other character
203 is meaning something.
205 The format is line oriented.
206 The new line character separate the lines.
208 Lines having only separators are blank lines and are skipped.
209 Line having the character # (sharp) as first not separator character
210 are comment lines and are ignored.
212 Lines starting with a not separator character are differents
213 of lines starting with a separator character.
215 The grammar of the configuration file is defined below:
217 CONF: *COMMENT *SECTION
221 RULE: +TYPE VECTOR ?VECTOR
223 MODE: 'mode' +SEP ('local' | 'remote') *SEP EOL
227 VECTOR: +SEP DATA *(+SEP NDATA) *SEP EOL
233 COMMENT: *SEP CMT *(SEP | NCHAR) NL
238 CHAR: '\x00'..'\x08' | '\x0b'..'\x1f' | '\x21' | '\x22' | '\x24'..'\xff'
241 Here is a sample of configuration file for defining how
242 to launch an application declared of types *application/x-executable*,
243 *text/x-shellscript* and *text/html* in mode local:
247 application/x-executable
252 /usr/bin/afb-daemon --mode=local --readyfd=%R --alias=/icons:%I --port=%P --rootdir=%r --token=%S --sessiondir=%D/.afb-daemon
253 /usr/bin/web-runtime http://localhost:%P/%c?token=%S
257 - within a section, several rules can be defined
258 - within a rule, several types can be defined
259 - within a rule, one or two vectors can be defined
260 - vectors are using %substitution
261 - launched binaries must be defined with their full path
265 Within this mode, the launchers have either one or two vectors
266 describing them. All of these vectors are treated as programs
267 and are executed with the system call 'execve'.
269 The first vector is the leader vector and it defines the process
270 group. The second vector (if any) is attached to the group
271 defined by this first vector.
275 Within this mode, the launchers have either one or two vectors
278 The first vector is treated as a program and is executed with
279 the system call 'execve'.
281 The second vector (if any) defines a text that is returned
282 to the caller. This mechanism can be used to return the uri
283 to connect to for executing the application remotely.
285 The daemon ***afm-user-daemon*** allocates a port for the
286 running the application remotely.
287 The current implmentation of the port allocation is just
289 A more reliable (cacheable and same-originable) allocation
294 Vectors can include sequences of 2 characters that have a special
295 meaning. These sequences are named *%substitution* because their
296 first character is the percent sign (%) and because each occurrence
297 of the sequence is replaced, at launch time, by the value associated
300 Here is the list of *%substitutions*:
304 This simply emits the percent sign %
308 This is the application Id of the launched application.
310 Defined by the attribute **id** of the element **<widget>**
315 The file within the widget directory that is the entry point.
317 For a HTML application, it is the relative path to the main
318 page (aka index.html).
320 Defined by the attribute **src** of the element **<content>**
325 Path of the directory where the application runs (cwd)
328 It is equal to %h/%a.
332 Requested height for the widget.
334 Defined by the attribute **height** of the element **<widget>**
339 Path of the home directory for all applications.
341 It is generally equal to $HOME/app-data
345 Path of the directory were the icons of the applications can be found.
347 - ***%m***: mime-type
349 Mime type of the launched application.
351 Defined by the attribute **type** of the element **<content>**
356 Name of the application as defined by the content of the
357 element **<name>** of **config.xml**.
363 Will be the colon separated list of plugins and plugins directory.
367 A port to use. It is currently a kind of random port. The precise
368 model is to be defined later.
372 Number of the file descriptor to use for signalling
373 readyness of the launched process.
377 Path of the directory containing the widget and its data.
381 An hexadecimal number that can be used to pair the client
382 with its server binder.
386 Requested width for the widget.
388 Defined by the attribute **width** of the element **<widget>**
395 ### Overview of the dbus interface
397 ***afm-user-daemon*** takes its orders from the session instance
398 of D-Bus. The use of D-Bus is great because it allows to implement
399 discovery and signaling.
401 The dbus of the session is by default adressed by the environment
402 variable ***DBUS_SESSION_BUS_ADDRESS***. Using **systemd**
403 the variable *DBUS_SESSION_BUS_ADDRESS* is automatically set for
406 The **afm-user-daemon** is listening with the destination name
407 ***org.AGL.afm.user*** at the object of path ***/org/AGL/afm/user***
408 on the interface ***org.AGL.afm.user*** for the below detailed
409 members ***runnables***, ***detail***, ***start***, ***terminate***,
410 ***stop***, ***continue***, ***runners***, ***state***,
411 ***install*** and ***uninstall***.
413 D-Bus is mainly used for signaling and discovery. Its optimized
414 typed protocol is not used except for transmitting only one string
417 The client and the service are using JSON serialisation to
420 The D-Bus interface is defined by:
422 * DESTINATION: **org.AGL.afm.user**
424 * PATH: **/org/AGL/afm/user**
426 * INTERFACE: **org.AGL.afm.user**
428 The signature of any member of the interface is ***string -> string***
429 for ***JSON -> JSON***.
431 This is the normal case. In case of error, the current implmentation
432 returns a dbus error that is a string.
434 Here is an example that use *dbus-send* to query data on
435 installed applications.
437 dbus-send --session --print-reply \
438 --dest=org.AGL.afm.user \
440 org.AGL.afm.user.runnables string:true
442 ### Using ***afm-util***
444 The command line tool ***afm-util*** uses dbus-send to send
445 orders to **afm-user-daemon**. This small scripts allows to
446 send command to ***afm-user-daemon*** either interactively
447 at shell prompt or scriptically.
449 The syntax is simple: it accept a command and if the command
450 requires it, the argument to the command.
452 Here is the summary of ***afm-util***:
454 - **afm-util runnables **:
456 list the runnable widgets installed
458 - **afm-util install wgt **:
462 - **afm-util uninstall id **:
464 remove the installed widget of id
466 - **afm-util detail id **:
468 print detail about the installed widget of id
470 - **afm-util runners **:
472 list the running instance
474 - **afm-util start id **:
476 start an instance of the widget of id
478 - **afm-util terminate rid **:
480 terminate the running instance rid
482 - **afm-util stop rid **:
484 stop the running instance rid
486 - **afm-util continue rid **:
488 continue the previously rid
490 - **afm-util state rid **:
492 get status of the running instance rid
495 Here is how to list applications using ***afm-util***:
501 ### The protocol over D-Bus
505 * **DESTINATION**: org.AGL.afm.user
507 * **PATH**: /org/AGL/afm/user
509 * **INTERFACE**: org.AGL.afm.user
513 #### Method org.AGL.afm.user.detail
515 **Description**: Get details about an application from its id.
517 **Input**: the id of the application as below.
519 Either just a string:
523 Or an object having the field "id" of type string:
527 **Output**: A JSON object describing the application containing
528 the fields described below.
531 "id": string, the application id (id@version)
532 "version": string, the version of the application
533 "width": integer, requested width of the application
534 "height": integer, resqueted height of the application
535 "name": string, the name of the application
536 "description": string, the description of the application
537 "shortname": string, the short name of the application
538 "author": string, the author of the application
543 #### Method org.AGL.afm.user.runnables
545 **Description**: Get the list of applications that can be run.
547 **Input**: any valid json entry, can be anything except null.
549 **output**: An array of description of the runnable applications.
550 Each item of the array contains an object containing the detail of
551 an application as described above for the method
552 *org.AGL.afm.user.detail*.
556 #### Method org.AGL.afm.user.install
558 **Description**: Install an application from its widget file.
560 If an application of the same *id* and *version* exists, it is not
561 reinstalled except if *force=true*.
563 Applications are installed in the subdirectories of the common directory
565 If *root* is specified, the application is installed under the
566 sub-directories of the *root* defined.
568 Note that this methods is a simple accessor to the method
569 ***org.AGL.afm.system.install*** of ***afm-system-daemon***.
571 After the installation and before returning to the sender,
572 ***afm-user-daemon*** sends the signal ***org.AGL.afm.user.changed***.
574 **Input**: The *path* of the widget file to install and, optionaly,
575 a flag to *force* reinstallation, and, optionaly, a *root* directory.
577 Either just a string being the absolute path of the widget file:
579 "/a/path/driving/to/the/widget"
584 "wgt": "/a/path/to/the/widget",
586 "root": "/a/path/to/the/root"
589 "wgt" and "root" must be absolute paths.
591 **output**: An object with the field "added" being the string for
592 the id of the added application.
594 {"added":"appli@x.y" }
598 #### Method org.AGL.afm.user.uninstall
600 **Description**: Uninstall an application from its id.
603 Note that this methods is a simple accessor to the method
604 ***org.AGL.afm.system.uninstall*** of ***afm-system-daemon***.
606 After the uninstallation and before returning to the sender,
607 ***afm-user-daemon*** sends the signal ***org.AGL.afm.user.changed***.
609 **Input**: the *id* of the application and, otpionaly, the path to
610 *root* of the application.
620 "root": "/a/path/to/the/root"
623 **output**: the value 'true'.
627 #### Method org.AGL.afm.user.start
631 **Input**: the *id* of the application and, optionaly, the
632 start *mode* as below.
634 Either just a string:
638 Or an object having the field "id" of type string and
639 optionaly a field mode:
641 {"id":"appli@x.y","mode":"local"}
643 The field "mode" as a string value being either "local" or "remote".
645 **output**: The *runid* of the application launched.
646 The runid is an integer.
650 #### Method org.AGL.afm.user.terminate
652 **Description**: Terminates the application of *runid*.
654 **Input**: The *runid* (an integer) of the running instance to terminate.
656 **output**: the value 'true'.
660 #### Method org.AGL.afm.user.stop
662 **Description**: Stops the application of *runid* until terminate or continue.
664 **Input**: The *runid* (an integer) of the running instance to stop.
666 **output**: the value 'true'.
670 #### Method org.AGL.afm.user.continue
672 **Description**: Continues the application of *runid* previously stopped.
674 **Input**: The *runid* (an integer) of the running instance to continue.
676 **output**: the value 'true'.
680 #### Method org.AGL.afm.user.state
682 **Description**: Get informations about a running instance of *runid*.
684 **Input**: The *runid* (an integer) of the running instance inspected.
686 **output**: An object describing the state of the instance. It contains:
687 the runid (an integer), the id of the running application (a string),
688 the state of the application (a string being either "starting", "running"
691 Example of returned state:
701 #### Method org.AGL.afm.user.runners
703 **Description**: Get the list of the currently running instances.
707 **output**: An array of states, one per running instance, as returned by
708 the methodd ***org.AGL.afm.user.state***.
714 The base of the path is FWKAPI = /api/fwk
717 request FWKAPI/runnables
718 -- get the list of applications
721 request FWKAPI/detail?id=APPID
722 subject to languages tuning
723 => { "id": "APPID", "name": "name", "description": "description", "license": "license", "author": "author" }
726 request FWKAPI/icon?id=APPID
727 subject to languages tuning
731 request FWKAPI/run?id=APPID
732 => { "status": "done/error", "data": { "runid": "RUNID" } }
734 request FWKAPI/running
735 => [ { "id": "RUNID", "appid": "APPID", "state": ... }... ]
737 request FWKAPI/state?id=RUNID
738 => { "id": "RUNID", "appid": "APPID", "state": ... }
740 request FWKAPI/stop?id=RUNID
741 => { "error": "message" ou "done": "RUNID" }
743 request FWKAPI/suspend?id=RUNID
744 => { "error": "message" ou "done": "RUNID" }
746 request FWKAPI/resume?id=RUNID
747 => { "error": "message" ou "done": "RUNID" }
750 request FWKAPI/features
751 => returns the features of the current application
753 request FWKAPI/preferences
754 => returns the features of the current application