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