Update the application guide
[apps/agl-service-windowmanager-2017.git] / doc / ApplicationGuide.md
1 **Window Manager Application Guide**
2 ====
3 <div align="right">Revision: 0.2Final</div>
4 <div align="right">TOYOTA MOTOR CORPORATION</div>
5 <div align="right">23rd/Oct/2017</div>
6
7 * * *
8 ## **<div id="Table\ of\ content">Table of content</div>**
9 - [Introduction](#Introduction)
10         - [Intended audience](#Intended\ audience)
11         - [Scope of this Document](#Scope\ of\ this\ Document)
12         - [Known Issues](#Known\ Issues)
13         - [External libraries](#External\ libraries)
14         - [Client Library](#Client\ Library)
15 - [Concepts](#Concepts)
16         - [Layers](#Layers)
17         - [Surfaces](#Surfaces)
18 - [Configuration](#Configuration)
19         - [Configuration Items](#Configuration\ Items)
20 - [Building and Running](#Building\ and\ Running)
21         - [Dependencies](#Dependencies)
22         - [Build Configuration](#Build\ Configuration)
23 - [Implementation Notes](#Implementation\ Notes)
24         - [Binding code generation](#Binding\ code\ generation)
25         - [Structure](#Structure)
26 - [Sequence](#Sequence)
27 - [Binding API](#Binding\ API)
28         - [LibWindowmanager](#LibWindowmanager)
29         - [Methods](#Methods)
30         - [Errors](#Errors)
31         - [Usage](#Usage)
32         - [Events](#Events)
33 - [Sample](#Sample)
34
35
36 <div id="Introduction">Introduction</div>
37 ============
38
39 This WindowManager implements simple layout switching of applications on
40 multiple layers and with different layer layouts.
41
42 <div id="Intended\ audience">Intended audience</div>
43 -----------------
44
45 This documentation is intended for developers and system integrators who
46 need to know, how the window manager works and how it is to be used.
47
48 <div id="Scope\ of\ this\ Document">Scope of this Document</div>
49 ----------------------
50
51 This document covers the window manager that was implemented for TMC and
52 delivered to the Automotive Grade Linux (AGL) project. It includes its
53 implementation details, concepts of operation, configuration and usage.
54
55 It does not include
56
57 -   documentation of the underlying architecture, see
58     [HMI-Framework](https://wiki.automotivelinux.org/hmiframework).
59
60 -   documentation of the AGL application framework and its technologies,
61     see [AGL Application
62     Framework](https://wiki.automotivelinux.org/agl-distro/app-framework).
63
64 It is highly recommended to have a good understanding of these documents
65 and projects before using the window manager.
66
67 <div id="Known\ Issues">Known Issues</div>
68 ------------
69
70 Currently there is a one known issues:
71
72 -   Only single-surface Qt applications are support through the
73     libwindowmanager library. This is a limitation of how Qt creates surface
74     IDs for the ivi-application interface.
75
76 <div id="External\ libraries">External libraries</div>
77 ------------------
78
79 This project includes a copy of version 2.1.1 the excellent [C++11 JSON
80 library by Niels Lohmann](https://github.com/nlohmann/json).
81
82 <div id="Client\ Library">Client Library</div>
83 --------------
84
85 A client library implementation that internally uses the *libafbwsc*, is
86 provided in the subdirectory `libwindowmanager/` with its own documentation
87 directory.
88
89 The client library is built together with the window manager itself.
90
91 <div id="Concepts">Concepts</div>
92 ========
93
94 The window manager implements a couple of concepts in order to allow
95 efficient implementation.
96
97 <div id="Layers">Layers</div>
98 ------
99
100 Layers are entities that are stacked on top of each other. Each layer
101 has an ID which is used for the ivi-controller interface, but this ID
102 also implicitly specifies its stacking order, from lowest to highest.
103
104 Layers are always full-screen. We do not use layer dimensions as a way
105 to setup the scene, rather - each layer has a layout attached to it,
106 which specifies an area that is used by surfaces to draw on.
107
108 Additionally, layers will generally leave surfaces on below layers
109 activated, and only disable surfaces on layers the are above the
110 currently used layer.
111
112 It is possible to deactivate these surfaces on lower layers explicitly
113 using the `DeactivateSurface` API call.
114
115 <div id="Surfaces">Surfaces</div>
116 --------
117
118 Surfaces are *placed* on layers according to their name. The surface
119 will then be resized to dimensions, according to the layer's layout
120 configuration.
121
122
123 <div id="Configuration">Configuration</div>
124 =============
125
126 The window manager is configured with the *layers.json* configuration
127 file, by default it is searched in `/etc/layers.json` but through the
128 use of the environment variable `LAYERS_JSON` the WM can be instructed
129 to use different file. Note, that the WM will not run unless this
130 configuration is found and valid.
131
132 A sample configuration is provided with the window manager
133 implementation, this sample is installed to /etc/layers.json.
134
135 <div id="Configuration\ Items">Configuration Items</div>
136 -------------------
137
138 This section describes configuration items available through
139 `layers.json`. It will do this, by first providing an example, and then
140 going into its components.
141
142 ### main\_surface
143
144     "main_surface": {
145        "surface_role": "HomeScreen",
146     },
147
148 The `main_surface` object describes a surface that will internally be
149 treated as the main surface - usually this mean *HomeScreen*. The only
150 special handling this surface receives, is that it is not allowed to
151 deactivate it. Placement of this surface on an layer is done by the
152 other configuration described below.
153
154 -   `surface_role` this configuration item specifies the name of the
155     main surface. Set this to e.g. `HomeScreen`.
156
157 ### mappings
158
159 This configuration item is a list of surface-name to layer mappings.
160
161 #### surface to layer mapping
162
163     "mappings": [
164       {
165          "role": "^HomeScreen$",
166          "name": "HomeScreen",
167          "layer_id": 1000,
168          "area": { "type": "full" },
169          "comment": "Single layer map for the HomeScreen, XXX: type is redundant, could also check existence of id/first_id+last_id"
170       },
171       {
172          "role": "MediaPlayer|Radio|Phone|Navigation|HVAC|Settings|Dashboard|POI|Mixer",
173          "name": "apps",
174          "layer_id": 1001,
175          "area": { "type": "rect", "rect": { "x": 0, "y": 218, "width": -1, "height": -433 } },
176          "comment": "Range of IDs that will always be placed on layer 1001, negative rect values are interpreted as output_size.dimension - $value",
177
178          "split_layouts": [
179             {
180                "name": "Navigation",
181                "main_match": "Navigation",
182                "sub_match": "HVAC|MediaPlayer",
183                "priority": 1000
184             }
185          ]
186       },
187       {
188          "role": "^OnScreen.*",
189          "name": "popups",
190          "layer_id": 9999,
191          "area": { "type": "rect", "rect": { "x": 0, "y": 760, "width": -1, "height": 400 } },
192          "comment": "Range of IDs that will always be placed on the popup layer, that gets a very high 'dummy' id of 9999"
193       }
194     ]
195
196 Each mapping defines the following items to map corresponding surfaces
197 to a layer.
198
199 -   `role` defines a regular expression that application drawing names
200     are matched against. If applications match tis regular expression,
201     the surface will be visible on this layer.
202
203 -   `name` is just a name definition for this layer, it has no
204     functional use apart from identifying a layer with a name.
205
206 -   `layer_id` specifies which ID this layer will use.
207
208 -   `area` is an object that defines the area assigned to surfaces.
209
210 -   `split_layouts` is an optional item, that - if present - defines a
211     number of possible split-screen layouts for this layer.
212
213 #### Area
214
215 Areas can be either `full` or `rect`, whereas `full` means a full-screen
216 layer, this is mostly useful for the main\_surface or HomeScreen layer.
217 `rect` declares a layer drawing area specified as a rectangle with start
218 coordinates `x` and `y` as well as its dimensions `width` and `height`.
219
220 The dimensions can be specified relative to the screen dimensions. For
221 this negative values for width and height mus be used.
222
223 For example, a full-screen surface can have the following `rect`
224 definition:
225
226     "rect": { "x": 0,
227               "y": 0,
228               "width": -1,
229               "height": -1 }
230
231 A surface that leaves a 200pixel margin on the top and bottom can use
232 the following `rect` definition:
233
234     "rect": { "x": 0,
235               "y": 200,
236               "width": -1,
237               "height": -401 }
238
239 So the expression for the actual surface dimensions when using
240 screen-size-relative values will be:
241
242     actual_width = screen_width + 1 + width
243     actual_height = screen_height + 1 + height
244
245 Or in other words, to leave an `N` wide border around a surface, the
246 actual value in the dimension configuration needs to be `-N - 1`, and
247 appropriate offsets need to be set for `x` and `y`.
248
249 #### split\_layouts
250
251 This configuration item allows the specification of split-screen layouts
252 on layers for certain surfaces.
253
254 A split screen layout always has a *main* surface and a *sub* surface.
255 In order to enter a split screen layout, first the *main* surface of the
256 layout must be activated, and then the *sub* surface. In order to
257 disable the split layout, one of the two participating surface must be
258 deactivated (or a surface on a layer below the current one must be
259 activated).
260
261     "split_layouts": [
262        {
263            "name": "Navigation",
264            "main_match": "Navigation",
265            "sub_match": "HVAC|MediaPlayer",
266        }
267     ]
268
269 A split layout object has the following attributes:
270
271 -   `name` defines its name, it has no actual function other then a way
272     to identify this split layout.
273
274 -   `main_match` is a regular expression that matches for the *main*
275     surface of this split layout.
276
277 -   `sub_match` is a regular expression that matches for the *sub*
278     surface of this layout.
279
280 In the above example only the surface with drawing name
281 `App MPlayer Main` will be used as the *main* surface, but all surfaces
282 that begin with `App MPlayer Sub` can be used as a *sub* surface for
283 this layout.
284
285 The names must still match the layer’s role match!
286
287 <div id="Building\ and\ Running">Building and Running</div>
288 ====================
289
290 <div id="Dependencies">Dependencies</div>
291 ------------
292
293 This project is intended to be build with the 4.0 release of AGL.
294
295 Build dependencies are as follows:
296
297 -   afb-daemon &gt;= 1.0
298
299 -   libsystemd &gt;= 222
300
301 -   wayland-client &gt;= 1.11
302
303 -   cmake &gt;= 3.6.1
304
305 <div id="Build\ Configuration">Build Configuration</div>
306 -------------------
307
308 **Download recipe**
309 If repo is already done, please start with git clone
310 ```
311 $ mkdir WORK
312 $ cd WORK
313 $ repo init -b dab -m dab_4.0.0_xml -u https://gerrit.automotivelinux.org/gerrit/AGL/AGL-repo
314 $ repo sync
315 $ git clone https://gerrit.automotivelinux.org/gerrit/staging/meta-hmi-framework
316
317 ```
318
319 Then you can get the following recipe.
320 * `meta-hmi-framework/windowmanager`
321
322
323 **Bitbake**
324 ```
325 $ source meta-agl/scripts/aglsetup.sh -m m3ulcb agl-demo agl-devel agl-appfw-smack agl-hmi-framework
326 $ bitbake agl-service-windowmanager-2017
327 ```
328
329
330 A couple of build options to configure the build are available:
331
332 -   `ENABLE_DEBUG_OUTPUT:BOOL` Compiles including very verbose debug
333     output from the window manager, use --verbose three times on an
334     afb-daemon instance to see the debug messages.
335
336 -   `ENABLE_SCOPE_TRACING:BOOL` Enables a simple scope tracing mechanism
337     used for a rather small portion of the window manager code. However,
338     it is used quite extensively in the libwindowmanager implementation.
339
340 By default these options will be disabled.
341
342
343 <div id="Implementation\ Notes">Implementation Notes</div>
344 ====================
345
346 The window manager is implemented as a app-framework-binder binding.
347 That means, the build produces one shared object that exports a binding
348 interface.
349
350 <div id="Binding\ code\ generation">Binding code generation</div>
351 -----------------------
352
353 The binding API is rather simple; functions receive a json object
354 describing arguments and return a json object describing the result or
355 an error. In order to simplify development, the
356 `generate-binding-glue.py` script was added, that contains a description
357 of the API as a python dictionary. This script generates the header
358 `afb_binding_api.hpp` and the afb binding functions as
359 `afb_binding_glue.inl`. Where the latter is included in `main.cpp`.
360
361 Each function for the AFB binding that is generated does the following:
362
363 -   Lock the binding mutex, so that we serialize all access to
364     the binding.
365
366 -   Do some debug logging (if wanted).
367
368 -   Check the binding state, i.e. the compositor might have exited
369     unexpectedly at which point it would not make sense to continue.
370
371 -   Extract the arguments from the json object that is provided (doing
372     some primitive type checking).
373
374 -   Call the afb\_binding\_api method corresponding to this binding
375     function
376
377 -   Check the afb\_binding\_api’s function return value, log an error
378     state and return the result to the afb request.
379
380 The generated functions do also check for any "loose" exception that
381 comes out of the afb\_binding\_api call (which in turn might call the
382 actual non-trivial implementation in `App`). However, **IF** an
383 exception is thrown and not handled inside the afb\_binding\_call, that
384 internal state of the window manager might be broken at this time (hence
385 the talkative error log).
386
387 <div id="Structure">Structure</div>
388 ---------
389
390 The implementation is loosely split across the following source files:
391
392 -   `main.cpp`: The program entry point as used by the afb-daemon. This
393     file defines the afbBindingV2 symbol tat is used by the afb-daemon
394     in order to load a binding. It also defines the wayland fd event
395     dispatcher and some globals to be used (as context for the afb calls
396     we receive).
397
398 -   `afb_binding_api.cpp`: The implementation of the afb
399     binding functions. The actual functions are generated by
400     `generate-binding-glue.py` which generates a **.inl** file that is
401     included by `main.cpp`.
402
403 -   `app.cpp` / `app.hpp`: This is the main application
404     logic implementation.
405
406 -   `config.cpp` / `config.hpp`: Very simple configuration
407     item interface.
408
409 -   `controller_hooks.hpp`: hook functions called by the wayland
410     controller to call into the App instance. Only a very limited number
411     of events are passed to the Application, which allowed the usage of
412     such a simple interface.
413
414 -   `json_helper.cpp` / `json_helper.hpp`: Smaller json related
415     helper functions.
416
417 -   `layers.cpp` / `layers.hpp`: Actually hold all the data from
418     layers.json configuration, do some transformations and service the
419     App implementation.
420
421 -   `layout.cpp` / `layout.hpp`: Very simple layout state for the
422     implementation of split layouts and tracking of the
423     surfaces involved.
424
425 -   `policy.hpp`: PolicyManager implementation stub. Gets passed the
426     current and new layout on layout switch and can decide upon it being
427     valid or not.
428
429 -   `result.hpp`: Simple result class around
430     `std::experimental::optional` that additionally can hold a
431     `char const *` to describe the error.
432
433 -   `util.cpp` / `util.hpp`: general utility functions and structs - and
434     preprocessor definitions (e.g. `log*()` to AFB logging functions.
435
436 -   `wayland.cpp` / `wayland.hpp`: A C++ object-oriented
437     libwayland-client wrapper. It is instanced in `main.cpp` and handles
438     all our wayland needs.
439
440 <div id="Sequence">Sequence</div>
441 ===============
442
443 To understand the sequence between application and window manager, refer to the [spec documentation](https://wiki.automotivelinux.org/windowmanager).
444
445
446 <div id="Binding\ API">Binding API</div>
447 ===============
448
449 Each function returns a reply containing at least a failed or successful
450 result of the call, additionally, when calls return something, it is
451 noted.
452
453 <div id="LibWindowmanager">LibWindowmanager</div>
454 ------
455
456 This is the public interface of the class `LibWindowmanager`.
457
458     class LibWindowmanager
459     {
460     public:
461         LibWindowmanager();
462         ~LibWindowmanager();
463
464         enum EventType {
465            Event_Active = 0,
466            Event_Inactive,
467
468            Event_Visible,
469            Event_Invisible,
470
471            Event_SyncDraw,
472            Event_FlushDraw,
473         };
474
475         int init(int port, char const *token);
476
477         // WM API
478         int requestSurface(json_object *object);
479         int activateSurface(json_object *object);
480         int deactivateSurface(json_object *object);
481         int endDraw(json_object *object);
482
483         void set_event_handler(enum EventType et, handler_fun f);
484
485     };
486
487 <div id="Methods">Methods</div>
488 -------
489
490 ### init(int port, char const *token)
491
492 Initialize the Binding communication.
493
494 The `token` parameter is a string consisting of only alphanumeric characters.
495 If these conditions are not met, the LibWindowmanager instance will not initialize,
496 i.e. this call will return `-EINVAL`.
497
498 The `port` parameter is the port the afb daemon is listening on, an
499 invalid port will lead to a failure of the call and return `-EINVAL`.
500
501 ### requestSurface(json_object *object)
502
503 **args: `{ 'kKeyDrawingName': 'application name' }`**
504 This method requests a surface with the label given from the *Window
505 Manager*. It will return `0` for a successful surface request, and
506 `-errno` on failure. Additionally, on the standard error, messages are
507 logged to help debgging the issue.
508
509 ### activateSurface(json_object *object)
510
511 **args: `{ 'kKeyDrawingName': 'application name', 'kKeyDrawingArea': 'layout'  }`**
512 This method is mainly intended for *manager* applications that control
513 other applications (think an application manager or the *HomeScreen*).
514 It instructs the window manager to activate the surface with the given
515 *label*.
516
517 This method only is effective after the actual window or surface was
518 created by the application.
519
520 ### deactivateSurface(json_object *object)
521
522 **args: `{ 'kKeyDrawingName': 'application name' }`**
523 This method is mainly intended for *manager* applications that control
524 other applications. It instructs the window manager to deactivate the
525 surface associated with the given label. Note, that deactivating a
526 surface also means to implicitly activate another (the last active or if
527 not available *main surface* or *HomeScreen*.)
528
529 This method only is effective after the actual window or surface was
530 created by the application.
531
532 ### endDraw(json_object *object)
533
534 **args: `{ 'kKeyDrawingName': 'application name' }`**
535 This function is called from a client application when it is done
536 drawing its surface content.
537
538 It is not crucial to make this call at every time a drawing is finished
539 - it is mainly intended to allow the window manager to synchronize
540 drawing in case of layout switch. The exact semantics are explained in
541 the next [Events](#_events) Section.
542
543 ### set\_event\_handler(enum EventType et, handler_fun f)
544
545 This method needs to be used to register event handlers for the WM
546 events described in the EventType enum. Only one hendler for each
547 EventType is possible, i.e. if it is called multiple times with the same
548 EventType the previous handler will be replaced.
549
550 The `func` handler functions will receive the label of the surface this
551 event is targeted at.
552
553 See Section [Events](#_events) for mor detailed information about event
554 delivery to client applications.
555
556 <div id="Errors">Errors</div>
557 ------
558
559 Methods returning an `int` signal successful operation when returning
560 `0`. In case of an error, an error value is returned as a negative errno
561 value. E.g. `-EINVAL` to signal that some input value was invalid.
562
563 Additionally, logging of error messages is done on the standard error
564 file descriptor to help debugging the issue.
565
566 <div id="Usage">Usage</div>
567 -----
568
569 ### Initialization of LibWindowmanager
570
571 Before usage of the LibWindowmanager, the method `init()` must be
572 called once, it will return `-errno` in case of en error and log
573 diagnostic messages to stderr.
574
575 ### Request a surface
576
577 When creating a surface with *Qt* - it is necessary to request a surface
578 from the WM, internally this will communicate with the window manager
579 binding. Only after `requestSurface()` was successful, a surface should
580 be created.
581
582 This is also true for *QML* applications, where only after the
583 `requestSurface()` should the load of the resource be done. The method
584 returns `0` after the surface was requested successfully.
585
586 #### Workings of requestSurface()
587
588 `LibWindowmanager::requestSurface()` calls the AFB binding verb
589 `requestsurface` of the `windowmanager` API. This API call will return a
590 numeric ID to be used when creating the surface. This ID is never
591 explicitly returned to the client application, instead, it is set in the
592 application environment in order for *Qt* to then use it when creating
593 the surface.
594
595 With the current *Qt* implementation this means, that only one surface
596 will be available to client applications, as subsequent windows will
597 increment this numeric ID internally - which then will lead to IDs that
598 cannot be known by the window manager as there is no direct
599 communication from *Qt* to the WM.
600
601 <div id="Events">Events</div>
602 ------
603
604 Events are a way for the *Window Manager* to propagate information to
605 client applications. It was vital for the project to implement a number
606 of events, that mirror functionality that is already present in the
607 wayland protocol.
608
609 All events have the surface label as argument - a way to enable future
610 multi-surface applications.
611
612 As already stated above, this is currently not possible with the way
613 *Qt* implements its surface ID setting.
614
615 ### Active and Inactive Events
616
617 These events signal an application that it was activated or deactivated
618 respectively. Usually this means it was switched visible - which means
619 the surface will now be on the screen and therefor continue to render.
620
621 -   `Active(json_object *object)`
622     args: { 'kKeyDrawingName': 'application name' }
623     Signal that the surface with the name
624     `kKeyDrawingName` is now active.
625
626 -   `Inactive(json_object *object)`
627     args: { 'kKeyDrawingName': 'application name' }
628     Signal that the surface with the
629     name `kKeyDrawingName` is now inactive. This usually means, the layout
630     got changed, and the surface is now considered inactive
631     (or sleeping).
632
633 ### Visible and Invisible
634
635 These events signal an application that it was switched to be visible or
636 invisible respectively. These events also are handled implicitly through
637 the wayland protocol by means of `wl_surface::enter` and
638 `wl_surface::leave` events to the client.
639
640 -   `Visible(json_object *object)`
641     args: { 'kKeyDrawingName': 'application name' }
642     Signal applications, that the
643     surface with name `kKeyDrawingName` is now visible.
644
645 -   `Invisible(json_object *object)`
646     args: { 'kKeyDrawingName': 'application name' }
647     Signal applications that the
648     surface with name `kKeyDrawingName` is now invisible.
649
650 ### SyncDraw and FlushDraw
651
652 These events instruct applications that they should redraw their surface
653 contents - again, this is handled implicitly by the wayland protocol.
654
655 `SyncDraw` is sent to the application when it has to redraw its surface.
656
657 `FlushDraw` is sent to the application when it should swap its buffers,
658 that is *signal* the compositor that its surface contains new content.
659
660 -   `SyncDraw(json_object *object)`
661     args: { 'kKeyDrawingName': 'application name', 'kKeyDrawingArea': 'layout'  }
662     Signal applications, that the
663     surface with name `kKeyDrawingArea` needs to redraw its content - this
664     usually is sent when the surface geometry changed.
665
666 -   `FlushDraw(json_object *object)`
667     args: { 'kKeyDrawingName': 'application name' }
668     Signal applications, that the
669     surface with name `kKeyDrawingArea` can now be swapped to its newly
670     drawn content as the window manager is ready to activate a new
671     layout (i.e. a new surface geometry).
672
673 <div id="Sample">Sample</div>
674 ============
675
676 In order to enable application to use the `WM` surface registration
677 function the above described steps need to be implemented.
678
679 As a minimal example the usage and initialization can look like the
680 following.
681
682 Repo: `apps/agl-service-homescreen-2017`
683 Path: `sample/template/main.c`
684