107b39979d4063630fad0d7e8f6ffc7acd1020d9
[src/app-framework-main.git] / doc / afm-user-daemon.md
1
2 The afm-user-daemon
3 ===================
4
5     version: 1
6     Date:    14 March 2016
7     Author:  José Bollo
8
9
10 Foreword
11 --------
12
13 This document describes what we intend to do. It may happen that our
14 current implementation and the content of this document differ.
15
16 In case of differences, it is assumed that this document is right
17 and the implementation is wrong.
18
19
20 Introduction
21 ------------
22
23 The daemon **afm-user-daemon** is in charge of handling
24 applications for one user. Its main tasks are:
25
26  - enumerate the applications that the user can run
27    and keep the list avalable on demand
28
29  - start applications for the user, set their running
30    environment, set their security context
31
32  - list the current runner applications
33
34  - stop (aka pause), continue (aka resume), terminate
35    the running instance of application
36
37  - transfer requests for installation or uninstallation
38    of applications to the dedicated system daemon
39    **afm-system-daemon**
40
41 The **afm-user-daemon** takes its orders from the session
42 instance of D-Bus.
43
44 The figure below summarizes the situation of the
45 **afm-user-daemon** in the system.
46
47     +------------------------------------------------------------+
48     |                          User                              |
49     |                                 +---------------------+    |
50     |     +---------------------+     |   Smack isolated    |    |
51     |     |   D-Bus   session   +     |    APPLICATIONS     |    |
52     |     +----------+----------+     +---------+-----------+    |
53     |                |                          |                |
54     |                |                          |                |
55     |     +----------+--------------------------+-----------+    |
56     |     |                                                 |    |
57     |     |                  afm-user-daemon                |    |
58     |     |                                                 |    |
59     |     +----------+----------------------+----------+----+    |
60     |                |                      |          :         |
61     |                |                      |          :         |
62     :================|======================|==========:=========:
63     |                |                      |          :         |
64     |     +----------+----------+     +-----+-----+    :         |
65     |     |   D-Bus   system    +-----+  CYNARA   |    :         |
66     |     +----------+----------+     +-----+-----+    :         |
67     |                |                      |          :         |
68     |     +----------+---------+    +-------+----------+----+    |
69     |     | afm-system-daemon  +----+   SECURITY-MANAGER    |    |
70     |     +--------------------+    +-----------------------+    |
71     |                                                            |
72     |                          System                            |
73     +------------------------------------------------------------+
74
75
76 Tasks of **afm-user-daemon**
77 ----------------------------
78
79 ### Maintaining list of applications ###
80
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.
84
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
88 list of applications.
89
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.
93
94 ### Launching applications ###
95
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.
99
100 Applications of different kind can be launched.
101
102 This is set using a configuration file that describes
103 how to launch an application of a given kind for a given
104 mode.
105
106 There is two launching modes: local or remote.
107
108 Launching an application locally means that
109 the application and its binder are launcher together.
110
111 Launching application remotely means that only the
112 binder is launched for the application.
113
114 Once launched, running instances of application receive
115 a runid that identify them.
116
117 ### Managing instances of running applications ###
118
119 **afm-user-daemon** manages the list of applications
120 that it launched.
121
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.
126
127 ### Installing and uninstalling applications ###
128
129 If the client has the good permission,
130 **afm-user-daemon** delegates that task
131 to **afm-system-daemon**.
132
133
134 Starting **afm-user-daemon**
135 -----------------------------
136
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.
140
141 The options for launching **afm-user-daemon** are:
142
143     -a
144     --application directory
145     
146          Includes the given application directory to
147          the database base of applications.
148     
149     -r
150     --root directory
151     
152          Includes the root application directory to
153          the database base of applications.
154
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).
158     
159     -m
160     --mode (local|remote)
161     
162          Set the default launch mode.
163          The default value is 'local'
164     
165     -d
166     --daemon
167     
168          Daemonizes the process. It is not needed by sytemd.
169     
170     -q
171     --quiet
172     
173          Reduces the verbosity (can be repeated).
174     
175     -v
176     --verbose
177     
178          Increases the verbosity (can be repeated).
179     
180     -h
181     --help
182     
183          Prints a short help.
184     
185
186 Configuration of the launcher
187 -----------------------------
188
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***
193 of the widget.
194
195 This couple mode and type allows to select the rule.
196
197 The configuration file is **/etc/afm/afm-launch.conf**.
198
199 It contains sections and rules. It can also contain comments
200 and empty lines to improve the readability.
201
202 The separators are space and tabulation, any other character
203 is meaning something.
204
205 The format is line oriented.
206 The new line character separate the lines.
207
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.
211
212 Lines starting with a not separator character are differents
213 of lines starting with a separator character.
214
215 The grammar of the configuration file is defined below:
216
217     CONF: *COMMENT *SECTION
218     
219     SECTION: MODE *RULE
220     
221     RULE: +TYPE VECTOR ?VECTOR
222     
223     MODE: 'mode' +SEP ('local' | 'remote') *SEP EOL
224     
225     TYPE: DATA *SEP EOL
226     
227     VECTOR: +SEP DATA *(+SEP NDATA) *SEP EOL
228     
229     DATA: CHAR *NCHAR
230     NDATA: +NCHAR
231
232     EOL: NL *COMMENT
233     COMMENT: *SEP CMT *(SEP | NCHAR) NL
234
235     NL: '\x0a'
236     SEP: '\x20' | '\x09'
237     CMT: '#'
238     CHAR: '\x00'..'\x08' | '\x0b'..'\x1f' | '\x21' | '\x22' | '\x24'..'\xff'
239     NCHAR: CMT | CHAR
240     
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:
244
245     mode local
246     
247     application/x-executable
248     text/x-shellscript
249         %r/%c
250     
251     text/html
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
254
255 This shows that:
256
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
262
263 ### mode local
264
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'.
268
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.
272
273 ### mode remote
274
275 Within this mode, the launchers have either one or two vectors
276 describing them.
277
278 The first vector is treated as a program and is executed with
279 the system call 'execve'.
280
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.
284
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
288 incremental.
289 A more reliable (cacheable and same-originable) allocation
290 is to be defined.
291
292 ### %substitutions
293
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
298 to sequences.
299
300 Here is the list of *%substitutions*:
301
302  - ***%%***: %.
303
304    This simply emits the percent sign %
305
306  - ***%a***: appid
307
308    This is the application Id of the launched application.
309
310    Defined by the attribute **id** of the element **<widget>**
311    of **config.xml**.
312
313  - ***%c***: content
314
315    The file within the widget directory that is the entry point.
316
317    For a HTML application, it is the relative path to the main
318    page (aka index.html).
319
320    Defined by the attribute **src** of the element **<content>**
321    of **config.xml**.
322
323  - ***%D***: datadir
324
325    Path of the directory where the application runs (cwd)
326    and stores its data.
327
328    It is equal to %h/%a.
329
330  - ***%H***: height
331
332    Requested height for the widget.
333
334    Defined by the attribute **height** of the element **<widget>**
335    of **config.xml**.
336
337  - ***%h***: homedir
338
339    Path of the home directory for all applications.
340
341    It is generally equal to $HOME/app-data
342
343  - ***%I***: icondir
344
345    Path of the directory were the icons of the applications can be found.
346
347  - ***%m***: mime-type
348
349    Mime type of the launched application.
350
351    Defined by the attribute **type** of the element **<content>**
352    of **config.xml**.
353
354  - ***%n***: name
355
356    Name of the application as defined by the content of the
357    element **<name>** of **config.xml**.
358
359  - ***%p***: plugins
360
361    Unhandled until now.
362
363    Will be the colon separated list of plugins and plugins directory.
364
365  - ***%P***: port
366
367    A port to use. It is currently a kind of random port. The precise
368    model is to be defined later.
369
370  - ***%R***: readyfd
371
372    Number of the file descriptor to use for signalling
373    readyness of the launched process.
374
375  - ***%r***: rootdir
376
377    Path of the directory containing the widget and its data.
378
379  - ***%S***: secret
380
381    An hexadecimal number that can be used to pair the client
382    with its server binder.
383
384  - ***%W***: width
385
386    Requested width for the widget.
387
388    Defined by the attribute **width** of the element **<widget>**
389    of **config.xml**.
390
391
392 The D-Bus interface
393 -------------------
394
395 ### Overview of the dbus interface
396
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.
400
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
404 user sessions.
405
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***.
412
413 D-Bus is mainly used for signaling and discovery. Its optimized
414 typed protocol is not used except for transmitting only one string
415 in both directions.
416
417 The client and the service are using JSON serialisation to
418 exchange data. 
419
420 The D-Bus interface is defined by:
421
422  * DESTINATION: **org.AGL.afm.user**
423
424  * PATH: **/org/AGL/afm/user**
425
426  * INTERFACE: **org.AGL.afm.user**
427
428 The signature of any member of the interface is ***string -> string***
429 for ***JSON -> JSON***.
430
431 This is the normal case. In case of error, the current implmentation
432 returns a dbus error that is a string.
433
434 Here is an example that use *dbus-send* to query data on
435 installed applications.
436
437     dbus-send --session --print-reply \
438         --dest=org.AGL.afm.user \
439         /org/AGL/afm/user \
440         org.AGL.afm.user.runnables string:true
441
442 ### Using ***afm-util***
443
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.
448
449 The syntax is simple: it accept a command and if the command
450 requires it, the argument to the command.
451
452 Here is the summary of ***afm-util***:
453
454  - **afm-util runnables      **:
455
456    list the runnable widgets installed
457
458  - **afm-util install    wgt **:
459
460    install the wgt file
461
462  - **afm-util uninstall  id  **:
463
464    remove the installed widget of id
465
466  - **afm-util detail     id  **:
467
468    print detail about the installed widget of id
469
470  - **afm-util runners        **:
471
472    list the running instance
473
474  - **afm-util start      id  **:
475
476    start an instance of the widget of id
477
478  - **afm-util terminate  rid **:
479
480    terminate the running instance rid
481
482  - **afm-util stop       rid **:
483
484    stop the running instance rid
485
486  - **afm-util continue   rid **:
487
488    continue the previously rid
489
490  - **afm-util state      rid **:
491
492    get status of the running instance rid
493
494
495 Here is how to list applications using ***afm-util***:
496
497     afm-util runnables
498
499 ---
500
501 ### The protocol over D-Bus
502
503 Recall:
504
505  * **DESTINATION**: org.AGL.afm.user
506
507  * **PATH**: /org/AGL/afm/user
508
509  * **INTERFACE**: org.AGL.afm.user
510
511 ---
512
513 #### Method org.AGL.afm.user.detail
514
515 **Description**: Get details about an application from its id.
516
517 **Input**: the id of the application as below.
518
519 Either just a string:
520
521     "appli@x.y"
522
523 Or an object having the field "id" of type string:
524
525     {"id":"appli@x.y"}
526
527 **Output**: A JSON object describing the application containing
528 the fields described below.
529
530     {
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
539     }
540
541 ---
542
543 #### Method org.AGL.afm.user.runnables
544
545 **Description**: Get the list of applications that can be run.
546
547 **Input**: any valid json entry, can be anything except null.
548
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*.
553
554 ---
555
556 #### Method org.AGL.afm.user.install
557
558 **Description**: Install an application from its widget file.
559
560 If an application of the same *id* and *version* exists, it is not
561 reinstalled except if *force=true*.
562
563 Applications are installed in the subdirectories of the common directory
564 of applications.
565 If *root* is specified, the application is installed under the
566 sub-directories of the *root* defined.
567
568 Note that this methods is a simple accessor to the method
569 ***org.AGL.afm.system.install*** of ***afm-system-daemon***.
570
571 After the installation and before returning to the sender,
572 ***afm-user-daemon*** sends the signal ***org.AGL.afm.user.changed***.
573
574 **Input**: The *path* of the widget file to install and, optionaly,
575 a flag to *force* reinstallation, and, optionaly, a *root* directory.
576
577 Either just a string being the absolute path of the widget file:
578
579     "/a/path/driving/to/the/widget"
580
581 Or an object:
582
583     {
584       "wgt": "/a/path/to/the/widget",
585       "force": false,
586       "root": "/a/path/to/the/root"
587     }
588
589 "wgt" and "root" must be absolute paths.
590
591 **output**: An object with the field "added" being the string for
592 the id of the added application.
593
594     {"added":"appli@x.y" }
595
596 ---
597
598 #### Method org.AGL.afm.user.uninstall
599
600 **Description**: Uninstall an application from its id.
601
602
603 Note that this methods is a simple accessor to the method
604 ***org.AGL.afm.system.uninstall*** of ***afm-system-daemon***.
605
606 After the uninstallation and before returning to the sender,
607 ***afm-user-daemon*** sends the signal ***org.AGL.afm.user.changed***.
608
609 **Input**: the *id* of the application and, otpionaly, the path to
610 *root* of the application.
611
612 Either a string:
613
614     "appli@x.y"
615
616 Or an object:
617
618     {
619       "id": "appli@x.y",
620       "root": "/a/path/to/the/root"
621     }
622
623 **output**: the value 'true'.
624
625 ---
626
627 #### Method org.AGL.afm.user.start
628
629 **Description**:
630
631 **Input**: the *id* of the application and, optionaly, the
632 start *mode* as below.
633
634 Either just a string:
635
636     "appli@x.y"
637
638 Or an object having the field "id" of type string and
639 optionaly a field mode:
640
641     {"id":"appli@x.y","mode":"local"}
642
643 The field "mode" as a string value being either "local" or "remote".
644
645 **output**: The *runid* of the application launched.
646 The runid is an integer.
647
648 ---
649
650 #### Method org.AGL.afm.user.terminate
651
652 **Description**: Terminates the application of *runid*.
653
654 **Input**: The *runid* (an integer) of the running instance to terminate.
655
656 **output**: the value 'true'.
657
658 ---
659
660 #### Method org.AGL.afm.user.stop
661
662 **Description**: Stops the application of *runid* until terminate or continue.
663
664 **Input**: The *runid* (an integer) of the running instance to stop.
665
666 **output**: the value 'true'.
667
668 ---
669
670 #### Method org.AGL.afm.user.continue
671
672 **Description**: Continues the application of *runid* previously stopped.
673
674 **Input**: The *runid* (an integer) of the running instance to continue.
675
676 **output**: the value 'true'.
677
678 ---
679
680 #### Method org.AGL.afm.user.state
681
682 **Description**: Get informations about a running instance of *runid*.
683
684 **Input**: The *runid* (an integer) of the running instance inspected.
685
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"
689 or "stopped").
690
691 Example of returned state:
692
693     {
694       "runid": 2,
695       "state": "running",
696       "id": "appli@x.y"
697     }
698
699 ---
700
701 #### Method org.AGL.afm.user.runners
702
703 **Description**: Get the list of the currently running instances.
704
705 **Input**: anything.
706
707 **output**: An array of states, one per running instance, as returned by
708 the methodd ***org.AGL.afm.user.state***.
709
710
711 The afb plugin
712 --------------
713
714 The base of the path is FWKAPI = /api/fwk
715
716
717 request FWKAPI/runnables
718   -- get the list of applications
719   => [ APPDESC... ]
720
721 request FWKAPI/detail?id=APPID
722   subject to languages tuning
723   => { "id": "APPID", "name": "name", "description": "description", "license": "license", "author": "author" }
724
725 /*
726 request FWKAPI/icon?id=APPID
727   subject to languages tuning
728   => the icon image
729 */
730
731 request FWKAPI/run?id=APPID
732   => { "status": "done/error", "data": { "runid": "RUNID" } }
733
734 request FWKAPI/running
735   => [ { "id": "RUNID", "appid": "APPID", "state": ... }... ]
736
737 request FWKAPI/state?id=RUNID
738   => { "id": "RUNID", "appid": "APPID", "state": ... }
739
740 request FWKAPI/stop?id=RUNID
741   => { "error": "message" ou "done": "RUNID" }
742
743 request FWKAPI/suspend?id=RUNID
744   => { "error": "message" ou "done": "RUNID" }
745
746 request FWKAPI/resume?id=RUNID
747   => { "error": "message" ou "done": "RUNID" }
748
749 /*
750 request FWKAPI/features
751   => returns the features of the current application
752
753 request FWKAPI/preferences
754   => returns the features of the current application
755 */
756
757
758