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