X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=doc%2FApplicationGuide.md;h=2240bb1161ab30adf5f5748cc38a3f0c0ad70347;hb=refs%2Ftags%2Fflounder%2F6.0.2;hp=b74dfddf27866fb209879f8a1e9efe51ca280dda;hpb=02eef0a7cff4ede60d1434e860cd4bc9e163af56;p=apps%2Fagl-service-windowmanager-2017.git diff --git a/doc/ApplicationGuide.md b/doc/ApplicationGuide.md index b74dfdd..2240bb1 100644 --- a/doc/ApplicationGuide.md +++ b/doc/ApplicationGuide.md @@ -1,11 +1,14 @@ **Window Manager Application Guide** ==== -
Revision: 0.2Final
+
Revision: 0.5
TOYOTA MOTOR CORPORATION
-
23rd/Oct/2017
+
20th/Mar/2018
* * * -## **
Table of content
** +
+ +Table of content +============ - [Introduction](#Introduction) - [Intended audience](#Intended\ audience) - [Scope of this Document](#Scope\ of\ this\ Document) @@ -21,7 +24,6 @@ - [Dependencies](#Dependencies) - [Build Configuration](#Build\ Configuration) - [Implementation Notes](#Implementation\ Notes) - - [Binding code generation](#Binding\ code\ generation) - [Structure](#Structure) - [Sequence](#Sequence) - [Binding API](#Binding\ API) @@ -33,19 +35,25 @@ - [Sample](#Sample) -
Introduction
+
+ +Introduction ============ -This WindowManager implements simple layout switching of applications on +This window manager implements simple layout switching of applications on multiple layers and with different layer layouts. -
Intended audience
+
+ +Intended audience ----------------- -This documentation is intended for developers and system integrators who +This document is intended for developers and system integrators who need to know, how the window manager works and how it is to be used. -
Scope of this Document
+
+ +Scope of this Document ---------------------- This document covers the window manager that was implemented for TMC and @@ -54,17 +62,19 @@ implementation details, concepts of operation, configuration and usage. It does not include -- documentation of the underlying architecture, see +- document of the underlying architecture, see [HMI-Framework](https://wiki.automotivelinux.org/hmiframework). -- documentation of the AGL application framework and its technologies, +- document of the AGL application framework and its technologies, see [AGL Application Framework](https://wiki.automotivelinux.org/agl-distro/app-framework). It is highly recommended to have a good understanding of these documents and projects before using the window manager. -
Known Issues
+
+ +Known Issues ------------ Currently there is a one known issues: @@ -73,28 +83,33 @@ Currently there is a one known issues: libwindowmanager library. This is a limitation of how Qt creates surface IDs for the ivi-application interface. -
External libraries
+
+ +External libraries ------------------ This project includes a copy of version 2.1.1 the excellent [C++11 JSON library by Niels Lohmann](https://github.com/nlohmann/json). -
Client Library
+
+ +Client Library -------------- A client library implementation that internally uses the *libafbwsc*, is -provided in the subdirectory `libwindowmanager/` with its own documentation -directory. +provided in the `libwindowmanager`. -The client library is built together with the window manager itself. +
-
Concepts
+Concepts ======== The window manager implements a couple of concepts in order to allow efficient implementation. -
Layers
+
+ +Layers ------ Layers are entities that are stacked on top of each other. Each layer @@ -112,7 +127,9 @@ currently used layer. It is possible to deactivate these surfaces on lower layers explicitly using the `DeactivateSurface` API call. -
Surfaces
+
+ +Surfaces -------- Surfaces are *placed* on layers according to their name. The surface @@ -120,19 +137,24 @@ will then be resized to dimensions, according to the layer's layout configuration. -
Configuration
+
+ +Configuration ============= The window manager is configured with the *layers.json* configuration -file, by default it is searched in `/etc/layers.json` but through the -use of the environment variable `LAYERS_JSON` the WM can be instructed -to use different file. Note, that the WM will not run unless this -configuration is found and valid. +file, by default it is searched in `${AFM_APP_INSTALL_DIR}/etc/layers.json`. +Note, that the window manager will use default configuration unless this configuration is found. A sample configuration is provided with the window manager -implementation, this sample is installed to /etc/layers.json. +implementation, this sample is installed to ${AFM_APP_INSTALL_DIR}/etc/layers.json. + +Note: +Currently, window manager doesn't block the application displaying because "Fallback" is set by default. If the "Fallback" is not set in layers.json, window manager blocks the application displaying. In such a situation, you have to add your role(application name) at "role" in layers.json. + +
-
Configuration Items
+Configuration Items ------------------- This section describes configuration items available through @@ -166,7 +188,7 @@ This configuration item is a list of surface-name to layer mappings. "name": "HomeScreen", "layer_id": 1000, "area": { "type": "full" }, - "comment": "Single layer map for the HomeScreen, XXX: type is redundant, could also check existence of id/first_id+last_id" + "comment": "Single layer map for the HomeScreen" }, { "role": "MediaPlayer|Radio|Phone|Navigation|HVAC|Settings|Dashboard|POI|Mixer", @@ -197,7 +219,7 @@ Each mapping defines the following items to map corresponding surfaces to a layer. - `role` defines a regular expression that application drawing names - are matched against. If applications match tis regular expression, + are matched against. If applications match this regular expression, the surface will be visible on this layer. - `name` is just a name definition for this layer, it has no @@ -218,7 +240,7 @@ layer, this is mostly useful for the main\_surface or HomeScreen layer. coordinates `x` and `y` as well as its dimensions `width` and `height`. The dimensions can be specified relative to the screen dimensions. For -this negative values for width and height mus be used. +this negative values for width and height must be used. For example, a full-screen surface can have the following `rect` definition: @@ -278,19 +300,21 @@ A split layout object has the following attributes: surface of this layout. In the above example only the surface with drawing name -`App MPlayer Main` will be used as the *main* surface, but all surfaces -that begin with `App MPlayer Sub` can be used as a *sub* surface for +`Navigation` will be used as the *main* surface, and the surfaces +with drawing name `HVAC` or `MediaPlayer` can be used as a *sub* surface for this layout. -The names must still match the layer’s role match! +The names must still match the layer's role match! -
Building and Running
+
+ +Building and Running ==================== -
Dependencies
------------- +
-This project is intended to be build with the 4.0 release of AGL. +Dependencies +------------ Build dependencies are as follows: @@ -300,115 +324,81 @@ Build dependencies are as follows: - wayland-client >= 1.11 -- cmake >= 3.6.1 +- wayland-ivi-extension >= 2.0.2 (until eel, wayland-ivi-extension >= 1.13) + +- cmake >= 2.8 -
Build Configuration
+
+ +Supported environment +------------------- + +| Item | Description | +|:------------|:----------------------------------| +| AGL version | Electric Eel | +| Hardware | Renesas R-Car Starter Kit Pro(M3) | + + +
+ +Build Configuration ------------------- **Download recipe** If repo is already done, please start with git clone + ``` $ mkdir WORK $ cd WORK -$ repo init -b dab -m dab_4.0.0_xml -u https://gerrit.automotivelinux.org/gerrit/AGL/AGL-repo +$ repo init -u https://gerrit.automotivelinux.org/gerrit/AGL/AGL-repo $ repo sync -$ git clone https://gerrit.automotivelinux.org/gerrit/staging/meta-hmi-framework ``` Then you can get the following recipe. -* `meta-hmi-framework/windowmanager` +* `meta-agl-devel/meta-hmi-framework/recipes-graphics/agl-service-windowmanager-2017` + +* `meta-agl-devel/meta-hmi-framework/recipes-graphics/libwindowmanager` **Bitbake** + ``` -$ source meta-agl/scripts/aglsetup.sh -m m3ulcb agl-demo agl-devel agl-appfw-smack agl-hmi-framework -$ bitbake agl-service-windowmanager-2017 +$ source meta-agl/scripts/aglsetup.sh -m m3ulcb agl-demo +$ bitbake agl-demo-platform ``` +
-A couple of build options to configure the build are available: - -- `ENABLE_DEBUG_OUTPUT:BOOL` Compiles including very verbose debug - output from the window manager, use --verbose three times on an - afb-daemon instance to see the debug messages. - -- `ENABLE_SCOPE_TRACING:BOOL` Enables a simple scope tracing mechanism - used for a rather small portion of the window manager code. However, - it is used quite extensively in the libwindowmanager implementation. - -By default these options will be disabled. - - -
Implementation Notes
+Implementation Notes ==================== The window manager is implemented as a app-framework-binder binding. That means, the build produces one shared object that exports a binding interface. -
Binding code generation
------------------------ - -The binding API is rather simple; functions receive a json object -describing arguments and return a json object describing the result or -an error. In order to simplify development, the -`generate-binding-glue.py` script was added, that contains a description -of the API as a python dictionary. This script generates the header -`afb_binding_api.hpp` and the afb binding functions as -`afb_binding_glue.inl`. Where the latter is included in `main.cpp`. - -Each function for the AFB binding that is generated does the following: - -- Lock the binding mutex, so that we serialize all access to - the binding. +
-- Do some debug logging (if wanted). - -- Check the binding state, i.e. the compositor might have exited - unexpectedly at which point it would not make sense to continue. - -- Extract the arguments from the json object that is provided (doing - some primitive type checking). - -- Call the afb\_binding\_api method corresponding to this binding - function - -- Check the afb\_binding\_api’s function return value, log an error - state and return the result to the afb request. - -The generated functions do also check for any "loose" exception that -comes out of the afb\_binding\_api call (which in turn might call the -actual non-trivial implementation in `App`). However, **IF** an -exception is thrown and not handled inside the afb\_binding\_call, that -internal state of the window manager might be broken at this time (hence -the talkative error log). - -
Structure
+Structure --------- The implementation is loosely split across the following source files: - `main.cpp`: The program entry point as used by the afb-daemon. This - file defines the afbBindingV2 symbol tat is used by the afb-daemon + file defines the afbBindingV2 symbol that is used by the afb-daemon in order to load a binding. It also defines the wayland fd event dispatcher and some globals to be used (as context for the afb calls we receive). -- `afb_binding_api.cpp`: The implementation of the afb - binding functions. The actual functions are generated by - `generate-binding-glue.py` which generates a **.inl** file that is - included by `main.cpp`. - -- `app.cpp` / `app.hpp`: This is the main application +- `app.cpp` / `app.hpp`: This is the main window manager logic implementation. - `config.cpp` / `config.hpp`: Very simple configuration item interface. - `controller_hooks.hpp`: hook functions called by the wayland - controller to call into the App instance. Only a very limited number - of events are passed to the Application, which allowed the usage of + controller to call into the window manager instance. Only a very limited number + of events are passed to the window manager, which allowed the usage of such a simple interface. - `json_helper.cpp` / `json_helper.hpp`: Smaller json related @@ -416,7 +406,7 @@ The implementation is loosely split across the following source files: - `layers.cpp` / `layers.hpp`: Actually hold all the data from layers.json configuration, do some transformations and service the - App implementation. + window manager implementation. - `layout.cpp` / `layout.hpp`: Very simple layout state for the implementation of split layouts and tracking of the @@ -433,24 +423,31 @@ The implementation is loosely split across the following source files: - `util.cpp` / `util.hpp`: general utility functions and structs - and preprocessor definitions (e.g. `log*()` to AFB logging functions. -- `wayland.cpp` / `wayland.hpp`: A C++ object-oriented +- `wayland_ivi_wm.cpp` / `wayland_ivi_wm.hpp`: A C++ object-oriented libwayland-client wrapper. It is instanced in `main.cpp` and handles - all our wayland needs. + all our wayland needs. These files are in master. In eel, the name + of these files are `wayland.cpp` / `wayland.hpp` -
Sequence
+
+ +Sequence =============== -To understand the sequence between application and window manager, refer to the [spec documentation](https://wiki.automotivelinux.org/windowmanager). +To understand the sequence between application and window manager, refer to the [spec document](https://wiki.automotivelinux.org/windowmanager). + +
-
Binding API
+Binding API =============== Each function returns a reply containing at least a failed or successful result of the call, additionally, when calls return something, it is noted. -
LibWindowmanager
+
+ +LibWindowmanager ------ This is the public interface of the class `LibWindowmanager`. @@ -474,17 +471,24 @@ This is the public interface of the class `LibWindowmanager`. int init(int port, char const *token); - // WM API + // Window manager API int requestSurface(json_object *object); + int requestSurfaceXDG(json_object *object); int activateSurface(json_object *object); int deactivateSurface(json_object *object); int endDraw(json_object *object); + int getDisplayInfo(json_object *object); + int getAreaInfo(json_object *in_obj, json_object *out_obj); + + int getAreaInfo(const char *label, json_object *out_obj); void set_event_handler(enum EventType et, handler_fun f); }; -
Methods
+
+ +Methods ------- ### init(int port, char const *token) @@ -501,10 +505,18 @@ invalid port will lead to a failure of the call and return `-EINVAL`. ### requestSurface(json_object *object) **args: `{ 'kKeyDrawingName': 'application name' }`** -This method requests a surface with the label given from the *Window -Manager*. It will return `0` for a successful surface request, and +This method requests a surface with the label given from the *Window Manager*. +It will return `surface id` a client application can use, and +`-errno` on failure. Additionally, on the standard error, messages are +logged to help debugging the issue. + +### requestSurfaceXDG(json_object *object) + +**args: `{ 'kKeyDrawingName': 'application name', 'kKeyIviId': 'ivi id' }`** +This method is mainly intended for *xdglauncher* that controls xdg application such as chromium. +It will return `surface id` xdglauncher uses, and `-errno` on failure. Additionally, on the standard error, messages are -logged to help debgging the issue. +logged to help debugging the issue. ### activateSurface(json_object *object) @@ -520,11 +532,9 @@ created by the application. ### deactivateSurface(json_object *object) **args: `{ 'kKeyDrawingName': 'application name' }`** -This method is mainly intended for *manager* applications that control -other applications. It instructs the window manager to deactivate the -surface associated with the given label. Note, that deactivating a -surface also means to implicitly activate another (the last active or if -not available *main surface* or *HomeScreen*.) +This method is mainly intended for *manager* applications that control other applications. +In adition, this is for applications that overrides other applications such like popup message. +In this case, popup surface requests to be hidden. It instructs the window manager to deactivate the surface associated with the given label. Note, that deactivating a surface also means to implicitly activate another (the last active or if not available *main surface* or *HomeScreen*.) This method only is effective after the actual window or surface was created by the application. @@ -540,6 +550,56 @@ It is not crucial to make this call at every time a drawing is finished drawing in case of layout switch. The exact semantics are explained in the next [Events](#_events) Section. +### getDisplayInfo(json_object *object) + +**args: `{ }`** +This function gets the display information as follows: + - width[pixel] + - height[pixel] + - width[mm] + - height[mm] + +It outputs the display information for json_object in the argument as follows: + `{"width_pixel": int value of width[pixel], "height_pixel": int value of height[pixel], + "width_mm": int value of width[mm], "height_mm": int value of height[mm]}` + +It should be called after calling init(). +It should not be called in the event handler because it occurs hang-up. + +#### NOTE +It uses wl_output::geometry() for getting physical width[mm] and height[mm] of the display, +but the value is different with measured value. + + - value from wl_output::geometry(): width:320 height:520 + - measured value : width:193 height:343 + +### getAreaInfo(json_object *in_obj, json_object *out_obj) + +**args1: `{ 'kKeyDrawingName': 'application name' }`** +**args2: `{ }`** +This function gets the information of area drawn by the application as follows: + - x-coordinate + - y-coordinate + - width + - height + +It outputs the area information for json_object in the 2nd argument as follows: + `{"x": int value of x-coordinate, "y": int value of y-coordinate, + "width": int value of width, "height": int value of height}` + +It should be called after calling activateSurface(). +It should not be called in the event handler because it occurs hang-up. + +#### NOTE +The same information can given by SyncDraw event. + +### getAreaInfo(const char *label, json_object *out_obj) + +**args1: String of application name** +**args2: `{ }`** +This function is same with `getAreaInfo(json_object *in_obj, json_object *out_obj)`, +but only has difference of 1st argument. + ### set\_event\_handler(enum EventType et, handler_fun f) This method needs to be used to register event handlers for the WM @@ -550,10 +610,12 @@ EventType the previous handler will be replaced. The `func` handler functions will receive the label of the surface this event is targeted at. -See Section [Events](#_events) for mor detailed information about event +See Section [Events](#_events) for more detailed information about event delivery to client applications. -
Errors
+
+ +Errors ------ Methods returning an `int` signal successful operation when returning @@ -563,13 +625,15 @@ value. E.g. `-EINVAL` to signal that some input value was invalid. Additionally, logging of error messages is done on the standard error file descriptor to help debugging the issue. -
Usage
+
+ +Usage ----- ### Initialization of LibWindowmanager Before usage of the LibWindowmanager, the method `init()` must be -called once, it will return `-errno` in case of en error and log +called once, it will return `-errno` in case of an error and log diagnostic messages to stderr. ### Request a surface @@ -581,7 +645,8 @@ be created. This is also true for *QML* applications, where only after the `requestSurface()` should the load of the resource be done. The method -returns `0` after the surface was requested successfully. +returns `surface id` a client application can use +after the surface was requested successfully. #### Workings of requestSurface() @@ -598,7 +663,9 @@ increment this numeric ID internally - which then will lead to IDs that cannot be known by the window manager as there is no direct communication from *Qt* to the WM. -
Events
+
+ +Events ------ Events are a way for the *Window Manager* to propagate information to @@ -658,10 +725,14 @@ contents - again, this is handled implicitly by the wayland protocol. that is *signal* the compositor that its surface contains new content. - `SyncDraw(json_object *object)` - args: { 'kKeyDrawingName': 'application name', 'kKeyDrawingArea': 'layout' } + args: { 'kKeyDrawingName': 'application name', 'kKeyDrawingArea': 'layout', + 'kKeyDrawingRect': { "x": int value of x-coordinate, "y": int value of y-coordinate, + "width": int value of width, "height": int value of height } } Signal applications, that the - surface with name `kKeyDrawingArea` needs to redraw its content - this + surface with name `kKeyDrawingArea` needs to redraw its content + in the layout with name `kKeyDrawingArea` - this usually is sent when the surface geometry changed. + And the area position and size are included with name `kKeyDrawingRect`. - `FlushDraw(json_object *object)` args: { 'kKeyDrawingName': 'application name' } @@ -670,7 +741,9 @@ that is *signal* the compositor that its surface contains new content. drawn content as the window manager is ready to activate a new layout (i.e. a new surface geometry). -
Sample
+
+ +Sample ============ In order to enable application to use the `WM` surface registration