Skip to content
Snippets Groups Projects
Commit 9a19c4d4 authored by Martyn Welch's avatar Martyn Welch Committed by Martyn Welch
Browse files

Remove obsolete documentation


The remaining documents in designs are completely obsolete. Remove these
designs to avoid confusion. The designs folder is part of the legacy
layout so remove it completely now that there's no documents. Fix any
broken links.

Signed-off-by: default avatarMartyn Welch <martyn.welch@collabora.com>
parent 82f3fcb8
No related branches found
No related tags found
1 merge request!219Review of concept documents
......@@ -85,5 +85,4 @@ platform.
* [Source code](https://gitlab.apertis.org)
* [Architectural documentation]( {{< ref "architecture" >}})
* [Development guides]( {{< ref "guides" >}} )
* [Design documents]( {{< ref "designs" >}} )
* [Concept designs]( {{< ref "concepts" >}} )
......@@ -594,8 +594,8 @@ performed.
### Attack detection
The platform should have [a heuristic for detecting whether an app has
been compromised or is malicious]( {{< ref "/attack_detection.md" >}} ).
The platform should have a heuristic for detecting whether an app has
been compromised or is malicious.
- The points described as a "probable attack" and "potential attack"
above may be used as input into this heuristic.
......@@ -612,8 +612,7 @@ been compromised or is malicious]( {{< ref "/attack_detection.md" >}} ).
- If this heuristic considers the app to be unlikely to be
compromised, the platform should allow it to run unhindered.
- *Non-requirement:* The exact design of this heuristic is outside the
scope of this document, and will be covered by a separate [Attack
detection]( {{< ref "/attack_detection.md" >}} ) design.
scope of this document, and will be covered by a separate design.
## Recommendations
......
+++
date = "2015-12-18"
weight = 100
title = "Attack detection"
aliases = [
"/old-wiki/Attack_detection"
]
+++
{{% notice warning %}}
This concept is an old work in progress.
{{% /notice %}}
The platform should have a heuristic for detecting whether an app-bundle
has been compromised or is malicious. This design document, which has
not yet been written, will collect the various possible inputs to this
heuristic, and the various actions that might be taken as a result of
the heuristic deciding that an app-bundle's behaviour is potentially or
probably malicious.
- [Egress filtering]( {{< ref "/egress_filtering.md" >}} ) is a potential
input: if an application attempts to carry out Internet connections
that are not allowed, this is suspicious behaviour.
- [Egress filtering]( {{< ref "/egress_filtering.md" >}} ) is a potential
action: if an application is detected to be malicious, its Internet
connectivity could be limited or cut off.
+++
title = "Clutter and Multitouch"
short-description = "Issues with Clutter (obsolete)"
weight = 100
toc = true
aliases = [
"/old-designs/latest/clutter.html",
"/old-designs/v2019/clutter.html",
"/old-designs/v2020/clutter.html",
"/old-designs/v2021dev3/clutter.html",
]
outputs = [ "html", "pdf-in",]
date = "2016-05-28"
+++
# Clutter and Multitouch
## Introduction
This document explains Collabora's design about several issues related
to the main UI toolkit used in Apertis: Clutter.
## Multi-touch
This section describes the support for multi-touch (MT) events and
gestures in the Apertis middle-ware. It will be explained which
requirements Collabora will support and the general architecture of MT
on Linux and X.Org.
When we mention MT in this document, we refer to the ability of
applications to react to multiple touch event streams at the same time.
By gestures, we refer to the higher-level abstraction that groups
individual touch events in a single meaningful event.
At this point of time (Q1 2012), MT and gesture functionality is
implemented in several consumer products but is only starting to be
available in frameworks of general availability such as X.Org and HTML.
As will be explained later, this is reflected in X.Org just being
released with [MT functionality],
Clutter not having MT support in a release yet, and the lack of high level gesture support in X.Org-based
toolkits. In the same vein, MT is not yet standardized in the web. This
design will discuss the challenges posed by these facts and ways of
overcoming them.
### The multi-touch stack
For the purposes of this document, the MT stack on X.Org is layered as
follows:
![](/images/multitouch_stack_in_xorg.png)
#### Compositor
The compositor has to be able to react to gestures that may happen
anywhere in the display. The X server usually delivers events to the
window where they happen, so the compositor overrides this behavior by
telling the X server that it has interest in all events regardless of
where they happen (specifically, it does so by registering a passive
grab on the root window).
The compositor will receive all events and decide for each whether it
should be handled at this level, or let it pass through to the
application to which the underlying window belongs.
For touch events, this isn't done for individual events but rather for
touch sequences. A touch sequence is the series of touch events that
starts when a finger is placed on the screen, and finished when it is
lifted. Thus, a touch sequence belongs to a single finger, and a gesture
can be composed by as many touch sequences as fingers are involved.
There is a period of time during which the compositor inspects the touch
events as they come and decides whether it should handle this particular
gesture, or if it should be ignored and passed to the application. If
the compositor decides the later, the events that had been already
delivered to the compositor will be replayed to the application.
The period of time that the compositor needs to decide whether a gesture
should be handled by applications should be as small as possible, in
order to not disrupt the user experience.
An application can tell the X server that it doesn't want to have to
wait until the compositor has let the touch sequence pass. In that case,
either the gesture shouldn't cause any visible effects in the UI, or
should be reverted in case the compositor ends up deciding to handle the
touch sequence by itself.
#### Applications
Widgets inside applications can react to MT events in a way similar to
how they react to single-touch events. Additionally, some toolkits
provide additional functionality that make it easier to react to
gestures. Widgets can either react to a few predefined gestures (tap,
panning, pinch, etc.), or they can implement their own gesture
recognizers by means of the lower level MT events.
#### UI toolkits
As mentioned before, UI toolkits provide API for reacting to MT events
and usually also functionality related to gestures. Because MT is so new
to X.Org, UI toolkits based on X.Org don't implement yet everything that
applications would need regarding MT and gestures, so for now additional
work needs to happen at the application level.
#### libXi
This library allow toolkits to communicate with the XInput extension in
the X.Org server. Communication with the X.Org server is asynchronous
and complex, so having a higher level library simplifies this
interaction.
#### X.Org server
The X.Org server delivers input events to each application based on the
coordinates of the event and the placement of the application windows.
#### evdev X.Org input driver
This input driver for X.Org uses udev to discover devices and evdev to
get input events from the kernel and posts them to the X.Org server.
If it is needed to apply a jitter-reduction filter and it's impossible
to do so in the kernel device driver, then we recommend to patch the
evdev X.Org input driver.
#### MTDev
For device drivers that use the legacy MT protocol as opposed to the new
slots protocol, the X.Org input driver will use libmtdev to translate
events from the old protocol (type A) to the new one (type B).
> See <http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt>
#### Kernel event driver (evdev)
This kernel module will emit input events in a protocol that the evdev
X.Org input driver can understand.
#### Kernel device driver
This kernel module is hardware-dependent and will interface with the
hardware and pass input events to the evdev event driver.
### Requirements
#### Multitouch event handing in Clutter applications
Clutter will have APIs for reacting to multi-touch input events and for
recognizing gestures.
The Apertis middleware will have the support that Clutter requires to
provide MT and gestures functionality, as described later in this
document.
Though it is expected that Clutter will eventually provide support for
recognizing a few basic gestures such as taps and panning, more advanced
gestures will have to be implemented outside Clutter. In the Apertis
case, recognizing additional gestures will have to be done by the
applications themselves or by the SDK API.
New gestures will be developed using the gesture framework in Clutter,
regardless of whether the gesture recognition is implemented in the SDK,
compositor or applications. In other words, new gestures can be
developed making use of the Clutter API, but the code that implements
them can belong to applications, compositors or libraries. No
modifications to Clutter are required to implement new gestures.
#### Full-screen event handing in applications
Applications should be able to handle events anywhere in the screen even
if their windows don't cover the whole of it. For example, there may be
windows belonging to the system such as a launcher panel or a status bar
in the screen, but a gesture that starts in one of the auxiliary windows
should be handled by the focused application.
#### Multi-touch event handling in Mutter
The compositor based on Mutter will be able to react to multi-touch
input events and recognize gestures using the same Clutter API as
applications.
The compositor will be able to register for MT sequences before
applications get them, so it can claim ownership over them in case a
system-wide gesture is detected. Even then, applications will be able to
get all events that happen in their windows though care needs to be
taken in case the compositor ends up claiming ownership.
#### Multitouch event handing in web applications
Although there are no approved specifications yet on how browsers should
expose MT events to web content, some browsers have started already to
provide experimental APIs and some websites are using them. Most notable
are the Safari browser on iOS and websites that target specifically
iPhone and iPad devices, though nowadays other WebKit-based browsers
implement MT events and more websites are starting to use them.
A [spec][w3-touch-spec] is being drafted by the W3C on base on the WebKit
implementation, but attention must be paid to the fact that because it's
still a draft, it may change in ways that are incompatible with WebKit's
implementation and the later may not always be in sync with the spec.
#### Support two separate touchscreens
The Apertis middleware will be able to drive two screens, each with
multi-touch support.
#### Support out-of-screen touch events
The reactive area of the touchscreen may extend past the display and the
user will be able to interact with out-of-screen UI elements.
#### Actors with bigger reactive area
So the UI is more tolerant to erratic touch events (caused for example
by a bumpy road), some actors will be reactive past the boundaries of
their representation in the screen.
### Approach
#### Multitouch event handing in Clutter applications
MT support in X.Org is very recent, so Collabora will have to update
several components (mainly belonging to X) in the stack because Precise
is not going to ship with the versions that are needed.
Clutter 1.8 had support for single-touch gestures. In 1.10, support for
multi-touch event handling landed, and it is expected that for 1.12
(August 2012), support for multi-touch gestures will be added. It's also
planned to have support for rotation and pinch gestures in
[Clutter 1.12].
#### Full-screen event handing in applications
In order for applications to be able to handle events anywhere in the
screen even if their windows do not cover the whole of it, applications
will have to set grabs on the other visible windows, even if they don't
belong to the application process.
So in the case that the currently-focused application is displayed along
with a launcher panel and a status bar, the application process should
set a grab on those windows for the events that it is interested in.
When another application becomes focused, the first one releases the
grab and the second takes it.
In order to make sure that the second application takes the grab as soon
as possible, it should try calling XIGrabTouchBegin repeatedly until it
stops failing with BadAccess (this will happen once the previously
focused application has removed its grab).
So the compositor can still handle system-level gestures as explained in
2.3.3, it will have to set a grab on an invisible window that is the
parent of each additional window.
This is so complex because this scenario is a bit removed from the
design of event delivery in X. In Wayland, as the compositor is also the
display server and has total control over event delivery, it could
redirect events to application windows instead of to the panels.
#### Multi-touch event handling in Mutter
Current releases of Mutter use XLib for event management, which doesn't
support multi-touch. To Collabora's knowledge, there aren't as of yet
any Mutter-based products that make use of system-wide multi-touch
gestures.
> See <https://wiki.gnome.org/GnomeOS/Design/Whiteboards/Touchscreen#Mutter_problems>
Collabora has [modified][tomeu-multitouch]
Mutter to allow plugins to register for touch events and to pass them to Clutter so subclasses of
ClutterGestureAction can be used.
Though applications are able to start receiving MT events even before
the compositor rejects ownership, Collabora recommends that applications
don't do that and instead that all efforts are directed towards having
the compositor recognize gestures as fast as possible.
Otherwise, it will be very hard to avoid glitches in the user experience
when the compositor decides to handle a gesture and the application
already started to react to it.
By limiting system-wide gestures to those with 4 or 5 fingers as iOS 5
does (what Apple calls *multitasking gestures*), the compositor should
be able to decide whether to take ownership of a MT sequence with a
minimal delay and without applications having to do anything on their
side. Gestures with less than 4 fingers will be considered as intended
for applications and the compositor will decline ownership immediately.
This diagram illustrates how the different components interact when
handling touch events:
![](/images/event_delivery.png)
If there is a window that gets placed on top of the others
(specifically, the “busy” indicator animation) and it shouldn't get any
events, it can be marked as such with the XShapeCombineRegion call,
passing an empty region and the ShapeInput destKind.
> See <http://article.gmane.org/gmane.comp.kde.devel.kwin/19992>
This way, any events that the compositor doesn't intercept will be delivered to the
currently-focused application.
#### Multi-touch event handing in web applications
Collabora will implement the port specific bits of MT in WebKit-Clutter
to ensure that it has state-of-the-art WebKit MT support, but won't be
changing the behavior of the generic WebKit implementation nor working
on the specification level.
Collabora won't be implementing any high-level gesture support because
they are far from being specified and its support in browsers is very
experimental.
#### Support two separate touchscreens
There is support in X.Org for arbitrarily matching input devices to
screens, though the configuration [isn't straightforward][xorg-transfo-matrix].
Collabora will test the simultaneous support of 2 touch-screens and produce
documentation about how to configure X.Org in this regard during the
development phase of the project.
#### Support out-of-screen touch events
Regarding out-of-screen events support, we propose writing a daemon that
listens for events from the touchscreen kernel driver and that, based on
its configuration, translates those to key presses for special key codes
that correspond to each button.
As the X evdev driver will also get those events, it has to be
configured to ignore touch events outside the screen area.
In the SDK, a wrapper around Xephyr will be provided that synthesizes
key events when buttons around the Xephyr screen are pressed, simulating
the ones in the real hardware.
#### Actors with bigger reactive area
Clutter actors tell the Clutter framework in which area of the screen
they are sensitive to pointer events. This area usually matches the area
that the actor uses to display itself, but the actor could choose to
mark a bigger area as its reactive area.
Though the Clutter maintainer has recommended this approach, he warns
that the optimization that culls actors based on their paint volumes
might get in the way in this case.
Collabora will verify that this works and communicate with the upstream
community in case any problem is discovered.
### Risks
The [DDX] driver provided by the hardware vendor should support
having a frame-buffer that is bigger than the actual display resolution,
for the out-of-screen touch events.
## Smooth panning
This section proposes an improvement to the kinetic scrolling
functionality in Mx so that panning is smooth even when the input
device's resolution is very low. This is going to affect only to Clutter
applications that use MxKineticScrollView as the container of scrollable
areas.
The problem with input devices with low resolution is that as the finger
moves during panning, the motion events received by the application are
similarly low-resolution (i.e., occurring infrequently). Given that Mx
currently updates the position in the scrolled view to match the
position of the finger, the panning movement appears "jumpy".
### Requirements
When panning, the position in the scrolled view will smoothly
interpolate to the last finger position, instead of jumping there
straight away. The visual effect would be that of the scroll position
lagging slightly behind the finger. The lower the resolution of the
touch screen, the bigger the lag.
### Approach
Collabora will rewrite the part of the [MxKineticScrollView]
widget that tracks the finger position when panning, ideally using the function
[mx_adjustment_interpolate] to animate the movement along the path between
the current position and the finger position. The time function ([ClutterAlpha])
used in the interpolation animation will be configurable, as well as the speed at which the scrolling position will
follow the finger.
### Risks
Upstream could decide to reject this feature when it is proposed for
inclusion because of the substantial added complexity to a widget
(MxKineticScrollView) that is already pretty complex. However,
preliminary discussions with the Mx maintainers show that they are
interested in gaining this functionality.
Another risk is Intel not funding all the work in Clutter that it has
committed to. In that case, Collabora may need to do the work.
## Documentation
The following items have been identified for future documentation work
later in the project:
- Add a section to the Clutter Cookbook about implementing a
ClutterGestureAction subclass.
- Best practices about MT gestures in user experience, both
system-wide and application gestures. Compare these guidelines with
the equivalent ones in iOS and Android.
- Best practices about performance with Clutter and Mx (including how
to write containers which are responsive independently of the number
of children and how to drag actors across the screen).
- Best practices about using and writing reusable UI components
(including Mx widgets), and explicitly these subjects (to be
specified further at a later stage):
- Panning actors
- Finger moves outside the “active area” of an actor (e.g., moving button of timeline in video very fast)
- Snap forward/backward to final position
- Expand/shrink of groups (sliding)
- Best practices about writing applications in which functionality and
UI are separate, so derivatives can be written by replacing the UI
and without having to modify the rest of the application.
### Design notes
The following items have been identified for future investigation and
design work later in the project and are thus not addressed in this
design:
- Support two separate touchscreens
- Support out-of-screen touch events
- Implement jitter reduction (there already has an algorithm), taking
into account that the input driver may be a binary blob
- Implement zoom via pitch gestures in Google Earth without having
access to its source
code
[MT functionality]: http://lists.x.org/archives/xorg-announce/2012-March/001846.html
[w3-touch-spec]: http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
[Clutter 1.12]: http://wiki.clutter-project.org/wiki/ClutterRoadMap#1.12
[tomeu-multitouch]: http://blog.tomeuvizoso.net/2012/09/multi-touch-gestures-in-gnome-shell.html
[xorg-transfo-matrix]: http://www.x.org/wiki/XInputCoordinateTransformationMatrixUsage
[DDX]: http://dri.freedesktop.org/wiki/DDX
[MxKineticScrollView]: http://docs.clutter-project.org/docs/mx/stable/MxKineticScrollView.html
[mx_adjustment_interpolate]: http://docs.clutter-project.org/docs/mx/stable/MxAdjustment.html#mx-adjustment-interpolate
[ClutterAlpha]: http://developer.gnome.org/clutter/stable/ClutterAlpha.html
+++
title = "List design"
short-description = "Architecture and API design for the list widgets in Apertis (unimplemented)"
weight = 100
toc = true
aliases = [
"/old-designs/latest/list.html",
"/old-designs/v2019/list.html",
"/old-designs/v2020/list.html",
"/old-designs/v2021dev3/list.html",
]
outputs = [ "html", "pdf-in",]
date = "2016-11-24"
+++
# List design
The goal of this list design document is to establish an appropriate
architecture and API design for the list widgets in the Apertis
platform.
Historically, the roller widget has provided a list widget on a cylinder
with no conceptual beginning or end and is manipulated naturally by the
user. For non-cylindrical lists there was a separate widget with a
different API and different usage. The goal is to consolidate list
operations into a base class and be able to use the same simple API to
use both cylindrical lists and non-cylindrical lists.
![](/images/roller_screenshot.png)
The above shows an example of the roller widget in use inside the music
application. There are multiple roller widgets for showing album,
artist, and song. Although they are manipulated independently, their
contents are linked.
## Terminology and concepts
### Vehicle
For the purposes of this document, a *vehicle* may be a car, car
trailer, motorbike, bus, truck tractor, truck trailer, agricultural
tractor, or agricultural trailer, amongst other things.
### System
The *system* is the infotainment computer in its entirety in place
inside the vehicle.
### User
The *user* is the person using the system, be it the driver of the
vehicle or a passenger in the vehicle.
### Widget
A *widget* is a reusable part of the user interface which can be changed
depending on location and function.
### User interface
The *user interface* is the group of all widgets in place in a certain
layout to represent a specific use-case.
### Roller
The *roller* is a list widget named after a cylinder which revolves
around its central horizontal axis. As a result of being a cylinder it
has no specific start and finish and appears endless.
### Application author
The *application author* is the developer tasked with writing an
application using the widgets described in this document. They cannot
modify the variant or the user interface library.
### Variant
A *variant* is a customised version of the system by a particular system
integrator. Usually variants are personalised with particular colour
schemes and logos and potentially different widget behaviour.
## Use cases
A variety of use cases for list design are given below.
### Common API
An application author wants to add a list widget to their application.
At that moment it is not known whether a simple list widget or a roller
widget will suit the application better. Said application author doesn't
want to have a high overhead in migrating code from one widget to
another.
### MVC separation
A group of application authors wants to be able to split the work
involved in developing their application into teams such that, adhering
to the interfaces provided, they can develop the different parts of the
application and easily put them together at the end.
### Data backend agnosticity
An application author wishes to display data stored in a database, and
does not want to duplicate this data in an intermediary data structure
in order to do so.
### Kinetic scrolling
The user wants to be able to scroll lists using their finger in such a
way that the visual response of the list is as expected. Additionally,
the system integrator wants the user to have visual feedback when the
start or end of a list is reached by the list bouncing up and back down
(the *elastic effect*). However, another system integrator wants to
disable this effect.
The user expectations include the following:
- The user expects the scroll to only occur after a natural threshold
of movement (as opposed to a tap), for the list to continue
scrolling after having removed their finger, and for the rate of
scroll to decrease with time.
- The user expects to be able to stop a scroll by tapping and holding
the scrolling area.
- The user expects a flick gesture to re-accelerate a scroll without
any visible stops in the animation.
- The user expects video elements to continue playing during a scroll.
- When there are not enough items to fill the entire height of the
list area the user expects a scroll to occur but using the elastic
effect fall back to the centre.
- The user expects a horizontal scroll gesture to not also scroll in
the vertical direction.
### Roller focus handling
In the roller widget, the user wants the concept of focus to be
highlighted by the list scrolling such that the focused row is in the
vertical centre.
Additionally, the user wants to be able to easily focus another
unfocused visible item in the list simply by pressing it.
### Animations
The user wants to have a smooth and natural experience in using either
list widget. If the scrolling stops half-way into an item and it is
required that one item is focused (see[roller focus handling]( {{< ref "#roller-focus-handling" >}} )), they want
the list to bounce a small scroll to focus said item.
### Item launching
An application author wants to be able to perform some
application-specific behaviour in response to the selecting of an item
in the list. However, they want to provide some confirmation before
launching an item in a list. They want the two step process to be:
1. The desired item is focused by scrolling to it or tapping on it.
2. The focused item is tapped again which confirms the intention to
launch it.
### Header and footer
The application author wants to add a header to the column to make it
clear exactly what is in said column. (An example can be seen in
[List design]( {{< ref "#list-design" >}} ) in the music application.)
Another system integrator wants the column names to be shown above the
widget in a footer instead of a header.
### Roller rollover
In the roller widget, by definition, the user wants to scroll from the
last item in the list back to the first without having to go all the way
back up.
Additionally, the user wants the wrap around to be made more visually
obvious with increased resistance when scrolling past the fold between
end and start again.
### Widget size
The application author wants any list widget to expand into space
allocated to it by its layout manager. If there are not enough items in
the list to fill all available space said application author wants the
remaining space to be blank, but still used by the list widget.
### Click activation
A system integrator wants to choose between single click and double
click activation (see[item launching]( {{< ref "#item-launching" >}} )) for use in the list widgets. This
is only expected once the item has already been focused (see also[roller focus handling]( {{< ref "#roller-focus-handling" >}} )).
The decision of single or double click is given to the system integrator
instead of the application author in order to retain a consistent user
experience.
### Consistent focus
The user focuses an item in the list and a new item is added. The user
expects the new item not to change the scroll position of the list and
more importantly not to change the currently focused row.
### Focus animation
An application author wants an item in the list to be able to perform an
animation after being focused.
### Mutable list
An application author wants to be able to change the contents of a list
shown in the user interface after having created the widget and shown it
in the user interface.
### UI customisation
A system integrator wants to change the look and feel of a list widget
without having to change any of the application code.
### Blur effect
A system integrator wants items in the list to be slightly blurred when
scrolling fast to exaggerate the scrolling effect. Another system
integrator wants to disable this blur.
### Scrollbar
A system integrator wants a scrollbar to be visible for controlling the
scrolling of the list. Another system integrator doesn't want the
scrollbar visible.
### Hardware scroll
A system integrator wants to use hardware buttons to facilitate moving
the focus up and down the list. The system integrator wants the list to
scroll in pages and for the focus to remain in order. For example, a
list contains items A, B, C, and D. When the *down* hardware button down
is pressed, the page moves down to show items E, F, G, and H, and the
focus moves to item E as it is the first on the page.
### On-demand item resource loading
The music application lists hundreds of albums but the application
author doesn't want the album art thumbnail to be loaded for every item
immediately as it would take too long and slow the system down. Instead,
said application author wants album art thumbnail to load only once
visible and have a placeholder picture in place until then.
### Scroll bubbles
A system integrator wants [bubbles] to appear when scrolling and
disappear when scrolling has stopped.
### Item headers
An application author wants to display items in a list but have a
logical separation into sections. For example, in a music application,
listing all tracks of an artist and separating by album.
Another application author wants said headers to stick to the top of the
widget so they are always visible, even if the first item has been
scrolled past and is no longer visible.
### List with tens of thousands of items
An application author wants to display a list containing thousands
of items, but does not want to incur the initial cost of instantiating
all the items when creating the list.
### Flow layout
An application author wants the list widget to render as a grid with
multiple items on the same line. The following video shows such a grid layout.
<video width="640" height="480" controls>
<source src="/images/album_cover_roller.mp4" type="video/mp4">
<source src="/images/album_cover_roller.ogv" type="video/ogg">
</video>
### Concurrent presentation of the same model in different list widgets
An application author wants to present the same model in two side-by-side
list widgets, possibly with different filtering or sorting.
## Non-use cases
A variety of non-use cases for the list design are given below.
### Tree views
An application author wants to show the filesystem hierarchy in their
application. They understand that multi-dimension models (or trees)
where items can be children of other items are not supported by the
Apertis list widgets (hence the name list).
### List widget without a backing model
An application wants to display a list of items in the list widget,
but does not wish to create a model and pass it to the list widget,
and would rather use helper functions in the list widget, such as
`list_add_item(List *list, ListItem *item)`.
Such an interface is not considered necessary, at least for this
version of the design document, because we want to encourage use of models
so that the UI views themselves can be rearranged more easily.
If, in the future, such an interface was considered desirable, its
API should be similar to the [`GtkListBox`] API, such as
`gtk_list_box_row_changed()`.
### Sticky header and footer
An application developer wants an actor to stick to the top or
the bottom of the list widget, and always be visible regardless
of scrolling.
This is best handled as a separate actor, sharing a common parent
with the list widget.
## Requirements
### Common API
There should be a common API between both list widgets (see[common api]( {{< ref "#common-api" >}} )).
Changing from a list widget to a roller widget or the other way around
should involve only trivial changes to the code leading to a change in
behaviour.
### MVC separation
The separation between components that use the list widgets should be
functional and enable application authors and system integrators to swap
out parts of applications easily and quickly (see[mvc separation]( {{< ref "#mvc-separation" >}} )).
The implementation of the model should be of no impact to the
functionality of the widget. As a result the widget should only refer to
the model using an interface which all models can implement.
### Data backend agnosticity
The widget should not require application authors to store their backing
model in any particular way.
### Kinetic scrolling
Both list widgets should support kinetic scrolling from user inputs (see[kinetic scrolling]( {{< ref "#kinetic-scrolling" >}} )). That is, when the user scrolls using their finger,
he or she can *flick* the list up or down and the scroll will continue
after the finger is released and gradually slow down. This animation
should feel natural to the user as if he or she is moving a wheel up or
down, with minimal friction. The animation should also be easily stopped
by tapping once.
#### Elastic effect
In the list widget with a defined start and finish, on trying to scroll
there should be visual feedback that the start or finish of the list has
been reached. This visual feedback should be accomplished using the
*elastic effect*. That is, when the bottom is reached and further
downward scrolling is attempted, an empty space slowly appears with
resistance, and pops back when the user releases their finger.
This is not necessary on the roller widget because the list loops and
there is no defined start and finish to the list.
It should be easy to turn this feature off as it may be undesired by the
system integrator (see[kinetic scrolling]( {{< ref "#kinetic-scrolling" >}} )).
### Item focus
In both list and roller widgets there should be a concept of focus which
only one item has at any one point. How to display which item has focus
depends on the widget.
### Roller focus handling
In the roller widget the focused item should always be in the vertical
centre of the widget (see[roller focus handling]( {{< ref "#roller-focus-handling" >}} )). The focused item
should visually change and even expand if necessary to demonstrate its
focused state (see also[focus animation]( {{< ref "#focus-animation" >}} )).
Changing which item is focused should be possible by clicking on another
item in the list.
### Animations
It should be possible to add animations to widgets to allow for moving
the current scroll location of the list up or down (see[animations]( {{< ref "#animations" >}} )).
This should be customisable by the system integrator and application
author depending on the application in question but should retain the
general look and feel across the entire system.
### Item launching
Focused items (see [Item focus]( {{< ref "#item-focus" >}} )) should be able to be launched using
widget-specific bindings (clicks or touches) (see [Click activation]( {{< ref "#click-activation" >}} )).
### Header and footer
It should be possible to add a header to a list to provide more context
as to what the information is showing (see[header and footer]( {{< ref "#header-and-footer" >}} ) and the
screenshot in [List design]( {{< ref "#list-design" >}} )). This should be customisable by the
application author and should be consistent across the entire system.
### Roller rollover
The rollover of the two list widgets should be different and
customisable by the system integrator (see[roller rollover]( {{< ref "#roller-rollover" >}} ) and[ui customisation]( {{< ref "#ui-customisation" >}} )).
The roller widget should roll over from the end of the list back to the
beginning again, like a cylinder would (see [List design]( {{< ref "#list-design" >}} ) and [Roller]( {{< ref "#roller" >}} )).
Additionally the system integrator should be able to customise whether
they want extra resistance in going back to the beginning. This is
visual feedback to ensure the user knows they are returning to the
beginning of the list.
The non-roller list widget should not have a rollover and should have a
well-defined start and finish, with visual effects as appropriate (see
[Elastic effect]( {{< ref "#elastic-effect" >}} )).
### Widget size
The list widgets should expand to fill out all space that has been
provided to them (see[widget size]( {{< ref "#widget-size" >}} )). They should fill any space not
required with a blank colour, specified by the variant UI customisation
(see[ui customisation]( {{< ref "#ui-customisation" >}} )).
### Consistent focus
The focus of items in a list should remain consistent despite
modification of the list contents (see[consistent focus]( {{< ref "#consistent-focus" >}} )). Adding items
before or after the currently focused item shouldn't change its focused
state.
### Focus animation
The application author and system integrator should be able to specify
whether there is an animation in selecting an item in a list (see[focus animation]( {{< ref "#focus-animation" >}} ) and[ui customisation]( {{< ref "#ui-customisation" >}} )). This could mean expanding an item to
make the item focused larger vertically and even display extra controls
which were previously hidden under the fold.
During this animation, input should not be possible.
### Mutable list
The items shown in the list widgets and their content should update
dynamically when the model backing the widget is updated (see[mutable list]( {{< ref "#mutable-list" >}} )). This should require no extra effort on the part of the
application author.
### UI customisation
Both list widgets should be visibly customisable in the same way the
rest of the system is and should honour UI customisations made by the
system integrator (see[ui customisation]( {{< ref "#ui-customisation" >}} )). In this way, the list widgets
should use CSS (see the UI Customisation Design document) for styling.
### Blur effect
The list widget should support slightly blurring list items only when
scrolling (see[blur effect]( {{< ref "#blur-effect" >}} )). It should be easily to disable this feature
by another system integrator who doesn't want the blur.
### Scrollbar
The list widget should support showing and hiding a scrollbar as
necessary (see[scrollbar]( {{< ref "#scrollbar" >}} )). It should be easy to disable this feature by
another system integrator who doesn't want to display a scrollbar.
### Hardware scroll
The list widget should support scrolling using hardware buttons and
therefore always have one item focused [hardware scroll]( {{< ref "#hardware-scroll" >}} )). Hardware
button callbacks should use the [adjustments][mx-scrollable] on the list widget to
change the subset of visible items and the appropriate list widget
function for moving the focus to the next item. Hardware button signals
are generated as described in the Hardkeys Design.
### On-demand item resource loading
Items in the list need to know when they are visible (and not past the
current scroll area) so they know when to load expensive resources, such
as thumbnails from disk (see [On-demand item resource loading]( {{< ref "#on-demand-item-resource-loading" >}} )).
### Scroll bubbles
The scrollbar (see also[scrollbar]( {{< ref "#scrollbar" >}} )) should support showing bubbles to
show the scroll position (see[scroll bubbles]( {{< ref "#scroll-bubbles" >}} )). It should be possible to
disable the bubble and change its appearance when necessary.
### Item headers
It should be possible to add separating headers to sets of items in the
list widgets (see[item headers]( {{< ref "#item-headers" >}} )). Said headers should also be sticky if
specified.
### Lazy list model
It should be possible to provide a ‘lazy list store’ to the widget,
in which items would be created on demand, when they need to be
displayed to the user.
This model could make memory usage and instantiation performance independent
of the number of items in the model.
See [List with tens of thousands of items]( {{< ref "#list-with-tens-of-thousands-of-items" >}} )
### Flow layout
It should be possible for *n* items, each of the same width and height, to be
packed in the same row of the list, where *n* is calculated as the floor of
the list width divided by the item width. There is no need for the programmer
to set *n* manually.
### Reusable model
The underlying model should not have to be duplicated in order to present it
in multiple list widgets at the same time.
See [Concurrent presentation of the same model in different list widgets]( {{< ref "#concurrent-presentation-of-the-same-model-in-different-list-widgets" >}} )
## Approach
### Adapter interface
As required by[data backend agnosticity1]( {{< ref "#data-backend-agnosticity1" >}} ), the backing data model format
should not be imposed by the list widget upon the application developer.
As such, an ‘adapter’ is required, similar to Android's [`ListAdapter`], this
adapter will make the bridge between the list widget and the data that backs
the list, by formatting data from the underlying model as list item widgets
for rendering.
The following diagram illustrates how this adapter helps decoupling the list
widget from the underlying model.
![list adapter flowchart](/images/list_adapter_flowchart.png)
> In the above example, we assume a program that simply displays a list widget
> exposing items stored in a database, and an adapter that stores strong
> references to the created list items, and will eventually cache them all
> if the list widget is fully scrolled down by the user. This is as opposed to
> the approach presented in [Lazy list model]( {{< ref "#lazy-list-model" >}} ) where memory usage is also
> taken into account.
>
> The ‘cursor’ is a representation of whatever database access API is in use,
> as most databases use cursor-based APIs for reading.
An interface for this adapter (the contents of the list widgets) is
required such that it can be swapped out easily where necessary
(see[mvc separation]( {{< ref "#mvc-separation" >}} ), [Lazy list model]( {{< ref "#lazy-list-model" >}} )).
GLib recently (since version 2.44) added an interface for this very
task. [`GListModel`] is an implementation-agnostic interface for
representing lists in a single dimension. It does not support tree
models (see [Tree views]( {{< ref "#tree-views" >}} )) and contains everything required for the
requirements specified in this document.
It should be noted that `GListModel`, which is for arbitrary containers, is
entirely unrelated to the `GList` data structure, which is for doubly linked
lists.
In addition to functions for accessing the contents of the adapter, there is
also an `items-changed` signal for notifying the view (the list widget and list
item widgets it contains; see[mvc separation]( {{< ref "#mvc-separation" >}} ))
that it should re-render as a result of something changing in the adapter.
### GtkListBox
[`GtkListBox`] is a GTK+ widget added in 3.10 as a replacement for the
very complicated [`GtkTreeView`] widget. `GtkTreeView` is used for
displaying complex trees with customisable cell renderers, but more
often lists are used instead of trees.
`GtkListBox` doesn't have a separate model backing it (but one can be
used), and each item is a `GtkListBoxRow` (which is in turn a `GtkWidget`).
This makes using the widget and modifying its contents especially easy
using the [`GtkContainer`] functions. Items can be activated (see[item launching]( {{< ref "#item-launching" >}} ) or selected (see [Item focus]( {{< ref "#item-focus" >}} )).
`GtkListBox` has been used in many GNOME applications since its addition
and has shown that its API is sufficient for most simple use cases, with
a limited number of items.
However `GtkListBox` is not scalable, as its interface requires that all its
rows be instantiated at initialisation, in order for example to add headers
to sections, and still be able to scroll accurately to any random position
in the list (random access).
As such, its API is only of a limited interest to us, particularly when it
comes to[item headers]( {{< ref "#item-headers" >}} ) or[filtering]( {{< ref "#filtering" >}} ).
### GtkFlowBox
[GtkFlowBox] is a GTK+ widget added in 3.12 as a complement to `GtkListBox`.
Its API takes a similar approach to that of `GtkListBox`: it doesn't have a
separate model backing it – but one can be used – and each item is a
`GtkFlowBoxChild` which contains the content for that item.
As with `GtkListBox`, its API is interesting to us for its approach to
reflowing children; see [Column layout]( {{< ref "#column-layout" >}} ).
### Widget size
The list widgets should expand to fill space assigned to them (see[widget size]( {{< ref "#widget-size" >}} )). This means that when there are too few items to fill space
the remaining space should be filled appropriately, but when there are
more items than can be shown at one time the list should be put into a
scrolling container.
In Clutter, actors are made to expand to fill the space they have been
assigned by setting the `x-expand` and `y-expand` properties on
`ClutterActor`. For example:
``` c
/* this actor will expand into horizontal space, but not into vertical
* space, allocated to it. */
clutter_actor_set_x_expand (first_actor, TRUE);
clutter_actor_set_y_expand (first_actor, FALSE);
/* this actor will expand into vertical space, but not into horizontal
* space, allocated to it. */
clutter_actor_set_x_expand (second_actor, FALSE);
clutter_actor_set_y_expand (second_actor, TRUE);
/* this actor will stretch to fill all allocated space, the
* default behaviour. */
clutter_actor_set_x_align (third_actor, CLUTTER_ACTOR_ALIGN_FILL);
/* this actor will be centered inside the allocation. */
clutter_actor_set_x_align (fourth_actor, CLUTTER_ACTOR_ALIGN_CENTER);
```
More details can be found in the [`ClutterActor`] documentation.
The list item widgets (as described in[adaptermodel implementation]( {{< ref "#adaptermodel-implementation" >}} )) are packed
by the list widget and so application authors have no control over their
expanding or alignment.
A suitable scrolling container to put a list widget into is the
[`MxKineticScrollView`] as it provides kinetic scrolling (see[kinetic scrolling]( {{< ref "#kinetic-scrolling" >}} )
and [Elastic effect]( {{< ref "#elastic-effect" >}} )) using touch events. Additionally, the
`MxKineticScrollView` should be put into an `MxScrollView` to get a
scrollbar where appropriate (see[scrollbar]( {{< ref "#scrollbar" >}} )).
For support of `MxKineticScrollView` the list widgets should implement the
`MxScrollable` interface, which allows getting and setting the
adjustments, and is necessary in showing a viewport into the interface
The exact dimensions in pixels for the widget shouldn't be specified by
the application author as it means changes to the appearance desired by
a system integrator are much more difficult to achieve.
### Adapter/Model implementation
As highlighted before (in [Adapter interface]( {{< ref "#adapter-interface" >}} )), the list widget should
make no assumption about how the backing data is stored. An adapter data
structure should be provided, making the bridge between the backing data
and the list widget, by returning list item actors for any given position.
The `GListModel` interface requires all its contained items to be
[`GObject`s with the same `GType`][GListModel-desc].
It is suggested that the items themselves are all instances of a new
`ListItem` class, which will inherit from `ClutterActor`, and implement
selection and activation logic.
[`GListStore`] is an object in GLib which implements `GListModel`. It
provides functions for inserting and appending items to the model but no
more. For small lists, it is suggested to either use `GListStore` directly or
implement a thin subclass to give more type safety and better-adapted function
signatures.
In these simple cases, `GListStore` will act as both the adapter *and* the
backing model, as it is storing `ListItem` widgets. For more complicated use
cases (where the same data source is being used by multiple list widgets), the
adapter and backing model must be separated, and hence `GListStore` is not
appropriate as the adapter in those cases. See [Decoupled model]( {{< ref "#decoupled-model" >}} ).
### Decoupled model
As shown in [Adapter interface]( {{< ref "#adapter-interface" >}} ), the list widget will not directly
interact with the underlying data model, but through an ‘adapter’.
The following diagram shows how the same underlying model may be queried
by two different list widgets, and their corresponding adapters.
![](/images/list_adapter_shared_model_diagram.png)
> List widgets are the outermost boxes in the diagram; the adapters are the
> next boxes inwards; and the middle box is the shared data model (a database).
>
> The ‘cursors’ in the above diagram are a representation of whatever database
> access API is in use, as most databases use cursor-based APIs for reading.
### Lazy object creation
`GListModel` allows an implementation to create items lazily (only create
or update items on screen and next to be displayed when a scroll is
initiated) for performance reasons. This is recommended for applications
with a very large number of items, so a new ListItem isn't required for
every single item in the list at initialisation.
`GListStore` does not support lazy object creation so an alternative model
will need to be implemented by applications which need to deal with
huge models.
An example for this is provided in [Alternative list adapter]( {{< ref "#alternative-list-adapter" >}} ).
### High-level helpers
Higher-level API should be provided in order to facilitate common usage
scenarios, in the form of an adapter implementation.
This adapter should be instantiatable from various common data models, through
constructors such as: `list_adapter_new_from_g_list_model` or
`list_adapter_new_from_g_list`.
This default adapter should automatically generate an appropriate UI for
the individual objects contained in the data model, with the only requirement
that they all be instances of the same GObject subclass. This requirement
should be clearly documented, as it won't be possible to enforce it at
instantiation time for certain data models, such as `GList`, without iterating
on all its nodes, thus forbidding the generic adapter from adopting a lazy
loading strategy.
The default behaviour of the adapter should be to provide a UI for all the
properties exposed by the objects (provided it knows how to handle them),
but much like the [Django admin site][django-admin-fields], it should be easy
for the user to modify which of these properties are displayed, and the
order in which they should be displayed, using a `set_fields()` method. The
suggested `set_fields()` API would take a non-empty ordered list of property
names for the properties of the objects in the model which the adapter should
display. For example, if the model contains objects which represent music
artists, and each of those objects has `name`, `genre` and `photo` properties,
the adapter would try to create row widgets which display all three
properties. If `set_fields (['name', 'genre'])` were called on the adapter, it
would instead try to only display the name and genre for the artist (name first,
genre second), and not their photo. The layout algorithm used for presenting
these properties generically in the UI is not prescribed here.
This generic adapter should expose virtual methods to allow potential
subclasses to provide their own list item widgets for properties that may or
may not be handled by the default implementation, and to provide their own list
item widgets for each of the GObjects in the model. These are represented by
`create_view_for_property()` and `create_view_for_object()` on the
[API diagram]( {{< ref "#api-diagram" >}} ).
The adapter should use weak references on the created list items, as
examplified in [Alternative list adapter]( {{< ref "#alternative-list-adapter" >}} ).
Filtering and sorting should be implemented by this adapter, with the option
for the user to provide implementations of the sorting and filtering methods,
and to trigger the sorting and filtering of the adapter. It should be clearly
documented that these operations may be expensive, as the adapter will have
no other option than iterating over the whole model.
If developers want to use the list widget with an underlying model that
allows more efficient sorting and filtering (for example a database), they
should implement their own adapter.
Refer to the [API diagram]( {{< ref "#api-diagram" >}} ) for a more formal view of the proposed API,
and to the [Generic adapter]( {{< ref "#generic-adapter" >}} ) section for a practical usage example.
### UI customisation
The list and list item widgets should be `ApertisWidget` subclasses (which
are in turn `ClutterActor`s) to take advantage of the `GtkApertisStylable`
mixin that `ApertisWidget` uses. This adds support for styling the widget
using CSS and [other style providers][GtkStyleProvider] which can be customised by
system integrators.
As the list item widgets are customisable widgets, they can appear any
way the application author wants. This means that it is up to the
application author to decide on theming decisions. Apertis-provided list
item widgets will clearly document the CSS classes that affect their
appearance.
### Sorting
Sorting the model is built into the `GListStore`. When adding a new item
to the adapter `g_list_store_insert_sorted` is used with the third
argument pointing to a function to help sort the model. All items can be
sorted at once using the `g_list_store_sort` function, passing in the
same or different sorting function.
When using an [Alternative list adapter]( {{< ref "#alternative-list-adapter" >}} ), sorting will need to be
implemented on a case-by-case basis.
### Filtering
As with `GtkListBox` when bound to a model, filtering should be implemented
by updating the contents of the adapter.
The list widget will be connected to the adapter, and will update itself
appropriately when notified of changes.
An example of this is shown in [the next section]( {{< ref "#filtering1" >}} ), the following
diagram illustrates the filtering process.
![Adapter filtering](/images/list_adapter_filtering.png)
> The ‘cursors’ in the above diagram are a representation of whatever database
> access API is in use, as most databases use cursor-based APIs for reading.
### Header and footer
The header should be a regular `ApertisWidget`, passed to the list widget as a
`header` property. It will be rendered above the body of the list widget.
Similarly, an `ApertisWidget` passed to a `footer` property will be rendered
below the body of the list widget. Using arbitrary widgets means the header’s
appearance is easily customisable. Passing them to the list widget means that
the list widget can set the widgets’ width to match that of the list.
Applications can set either, both, or neither, of the `header` and `footer`
properties. If both are set, both a header and a footer are rendered, and the
application may use different widgets in each.
### Selections
As with `GtkListBox`, it should be possible to select either one or many
items in the list (see [Item focus]( {{< ref "#item-focus" >}} )). The application author can decide
what is the behaviour of the list in question using the “selection
mode”. The values for the selection mode are none (no items can be
selected), single (at most one item can be selected), and multiple (any
number of items can be selected). A multiple selection example can be found
in the [Multiple selection]( {{< ref "#multiple-selection" >}} ) section.
The `ListItem` object has a read-write property for determining it can be
selected or not. An example that sets this property can be found
in the [Non-selectable items]( {{< ref "#non-selectable-items" >}} ) section.
The selection signals exposed by the list widget will be identical to those
exposed by `GtkListBox`, namely `item-selected` when an item is focused,
`item-activated` when the item is subsequently activated, and in the case
of multiple selection, the `selected-items-changed` signal will give the user
the full picture of the current items selected by the user, by being emitted
every time the current selection changes, and passing an updated list of
selected list items to potential callback functions.
### Item headers
Item headers are widgets used to separate items into logical groups (for
example, when showing tracks of an artist, they could be grouped in
albums with the album name as the item header).
Due to the requirement for lazy initialisation, the solution proposed
by `GtkListBox` cannot be adopted here, as it implies that all the list
items need to be instantiated ahead of time.
Our approach here is similar to [the solution][ListAdapter-separators] used
with Android's `ListAdapter`: as the adapter is decoupled from the data model,
and returns the actors that should be placed at a given position in the list,
it may also account for such headers, which should be returned as unselectable
`ListItem`s at specific positions in the adapter.
We make no assumptions as to how implementations may choose to associate
a selected list item with the data model: in the simple case, the index
of a list item may be directly usable to access the backing object it
represents, if the backing data is stored in an array, and no item header
is inserted in the adapter.
In other cases, where for example the backing data is stored in a database,
or item headers are inserted and offset the indices of the following items,
implementations may choose to store a reference to the backing object using
`g_object_set_qdata` or an external mechanism such as a `GHashTable`.
An example of item headers is shown in [the following section][Header items].
### Sticky item headers
As required for [Lazy list model]( {{< ref "#lazy-list-model" >}} ), when the list widget is scrolled to
a random point, items surrounding the viewport may not be created yet.
It is proposed that a simple API be exposed to let application developers
specify the sticky item at any point in the scrolling process, named
`list_set_sticky_func`.
The implementation will, upon scrolling the list widget, pass this function
the index of the top-most visible item, and expect it to return the `ListItem`
that should be stickied (or `NULL`).
### Blur effect
Given the `MxKineticScrollView` container does the actual scrolling, it is
the best place to implement the desired blur effect (see[blur effect]( {{< ref "#blur-effect" >}} )).
Additionally, implementing it in the container means it can be
implemented once instead of in every widget that needs to have a blur
effect.
### On-demand item resource loading
By default, list items should assume they are not in view and should not
perform expensive operations until they have been signalled by the list
widget that they are in view (see [On-demand item resource loading]( {{< ref "#on-demand-item-resource-loading" >}} )). For
example, a music application might have a long list of albums and each
item has the album cover showing. Instead of loading every single album
cover when creating the list, each list item should use a default dummy
picture in its place. When the user scrolls the list, revealing
previously hidden items, the album cover should be loaded and the
default dummy picture replaced with the newly loaded picture.
The list widget should have a way of determining the item from given
co-ordinates so that it can signal to said item when it comes into view
after a scroll event. The list item object should only perform expensive
operations when it has come into view, by reading and monitoring a
property on itself. Once visible an item will not return to the not
visible state.
### Scroll bubbles
The bubble displayed when scrolling to indicate in which category the
scroll is showing (see[scroll bubbles]( {{< ref "#scroll-bubbles" >}} )) should be added to `MxScrollBar` as
that is the widget that controls changing the scroll position.
### Roller subclass
The roller widget should be implemented as a subclass of the list widget.
The roller widget will implement the `MxScrollable` interface, setting
appropriate increment values on its adjustments, in order to ensure the
currently-focused row will always be aligned with the middle after scrolling.
As the roller subclass will implement [rollover]( {{< ref "#roller-rollover" >}} ), the
elastic effect when reaching the bottom of the list will not be used.
In addition, it will also, in its `init` method, use a `ClutterEffect` in
order to render itself as a cylinder (or ideally, as a [hexagonal prism]).
### Column layout
By default, the list widget will display as many items as fit per row, given
the list’s width and the configured item width. Properties will be provided for:
* A `row-spacing` property, setting the blank space between adjacent rows.
* A `column-spacing` property, setting the blank space between adjacent
columns.
* An `item-width` property, setting the width of all columns.
* An `item-height` property, setting the height of all rows.
Note that `GtkFlowBox` supports reflowing children of different sizes; in this
design, we only consider children of equal sizes, which simplifies the API. It
is equivalent to considering a `GtkFlowBox` with its `homogeneous` property set
to true.
So, for example, to display items in a single column (one item per row), set the
`item-width` to equal the list’s width. To implement a grid layout where some
items may be missing and gaps should be left for them, implement a custom row
widget which displays its own children in a grid; and display one such row
widget per row of the list.
We suggest the default value for `item-width` is to track the list’s width, so
that the list uses a single column unless otherwise specified.
### Focus animation
A `use-animations` property will be exposed on the list items. Upon activation,
an item with this property set to `True` will be animated to cover the whole
width and height allocated to the list widget.
Application developers may connect to the `item-activated` signal in order to
update the contents of the item, as shown in [Item activation]( {{< ref "#item-activation" >}} ).
Once the set of possible and valuable animations has become clearer, API
may be exposed to give more control to system integrators and application
developers.
### Item launching
In the roller subclass, the `item-activated` signal should only be emitted
for actors in the currently focused row. This will ensure that only items
that were scrolled to can be activated.
### API diagram
![](/images/list_api.png)
Signals are shown with a hash beforehand (for example, `#item-activated`),
with arguments listed afterwards. Properties are shown with a plus sign
beforehand and without getters or setters (`get_model()`, `set_model()`)
for brevity.
## Example API usage
### Basic usage
The following example creates a model, creates item actors for each
artist available on the system, and adds them to the model. The exact
API is purely an example but the approach to the API is to note.
As a simple example, this avoids creating a separate adapter and model, and
instead creates a model which contains the list row widgets. In more complex
examples, where data from the model is being used by multiple list widgets,
the model and adapter are separate, and the entries in the model are not
necessarily widget objects. See [Generic adapter] for such an example.
{{ ../examples/sample-list-api-usage-basic.c }}
The object created by `create_sample_artist_item` is an instance of
`ClutterActor` (or an instance of a subclass) which defines how the item
will display in the list. In that case, it is as simple as packing in a
`ClutterText` to display the name of the artist as a string.
More likely it would use a `ClutterBoxLayout` layout manager to pack
different `ClutterActor`s into a horizontal line showing properties of the
artist.
### Item activation
The following example creates a list widget using the function defined
in the previous section and connects to the `item-activated` signal to
change the list item actor.
{{ ../examples/sample-list-api-usage-item-activated.c }}
### Filtering
The following example shows how to filter the list store bound to the list
widget created using the function implemented in [Basic usage]( {{< ref "#basic-usage" >}} )
to only display items with a specific property.
{{ ../examples/sample-list-api-usage-filtering.c }}
### Multiple selection
The following example sets the selection mode to allow multiple items to
be simultaneously selected.
{{ ../examples/sample-list-api-usage-selection.c }}
### Non-selectable items
The following example makes half the items in a list impossible to select.
{{ ../examples/sample-list-api-usage-non-selectable-items.c }}
### Header items
The following example adds alphabetical header items to the list.
{{ ../examples/sample-list-api-usage-header-items.c }}
### On-demand item resource loading
The following example shows how on-demand item resource loading could be
implemented, using the model created in the first listing:
{{ ../examples/sample-list-api-usage-resource-loading.c }}
### Generic adapter
The following example shows how developers may take advantage of the proposed
generic adapter.
{{ ../examples/sample-list-adapter-api-usage.c }}
### Alternative list adapter
Authors of applications do not necessarily need to use a `GListStore` as their
adapter class. Instead they can implement the `GListModel` interface, and
pass it as the adapter for the list widget.
In the following example, we define and implement an adapter to optimise
both initialisation performance by creating `MyArtistItem`s only when required,
and memory usage by letting the `List` widget assume ownership of the created
items.
{{ ../examples/alternative_list_model.c }}
## Requirements
This design fulfils the following requirements:
-[common api1]( {{< ref "#common-api1" >}} ) — the list widget and roller widget have the same
API and any roller-specific roller API is in its own class.
-[mvc separation1]( {{< ref "#mvc-separation1" >}} ) — `GListModel` is used as an adapter to the backing
data, which storage format is not imposed to the user. The list widget
and item widgets are separate objects.
-[data backend agnosticity1]( {{< ref "#data-backend-agnosticity1" >}} ) — Applications provide list items through
an adapter, no requirement is made as to the storage format.
-[kinetic scrolling1]( {{< ref "#kinetic-scrolling1" >}} ) — use `MxKineticScrollView`.
- [Elastic effect]( {{< ref "#elastic-effect" >}} ) — use `MxKineticScrollView`.
- [Item focus]( {{< ref "#item-focus" >}} ) — list items can be selected ( [Selections]( {{< ref "#selections" >}} )).
-[roller focus handling1]( {{< ref "#roller-focus-handling1" >}} ) — this roller-specific selecting
behaviour can be added to the roller's class.
-[animations1]( {{< ref "#animations1" >}} ) — use `MxKineticScrollView`.
-[item launching1]( {{< ref "#item-launching1" >}} ) — the item-activated signal on the list widget
will signal when an item is activated.
-[header and footer1]( {{< ref "#header-and-footer1" >}} ) — `ApertisWidget`s can be set as header or footer
[header and footer2]( {{< ref "#header-and-footer2" >}} )).
-[roller rollover1]( {{< ref "#roller-rollover1" >}} ) — this roller-specific rollover behaviour can
be added to the roller's class.
-[widget size1]( {{< ref "#widget-size1" >}} ) — use `ClutterLayoutManager` and the `ClutterActor`
properties [widget size2]( {{< ref "#widget-size2" >}} )).
-[consistent focus1]( {{< ref "#consistent-focus1" >}} ) — the API asserts a consistent focus and
ensures the implementation behaves when the model changes.
-[focus animation1]( {{< ref "#focus-animation1" >}} ) — items are `ClutterActor`s which can animate
using regular Clutter API.
-[mutable list1]( {{< ref "#mutable-list1" >}} ) — use `GListStore`.
-[ui customisation1]( {{< ref "#ui-customisation1" >}} ) — subclass `ApertisWidget` and use the
`GtkStyleProvider`s.
-[blur effect1]( {{< ref "#blur-effect1" >}} ) — add a `motion-blur` property to
`MxKineticScrollView` and use that [blur effect2]( {{< ref "#blur-effect2" >}} )).
-[scrollbar1]( {{< ref "#scrollbar1" >}} ) — use the `scroll-visibility` property on the
`MxScrollView` container.
-[hardware scroll1]( {{< ref "#hardware-scroll1" >}} ) — use the adjustment on the list widget to
scroll down a page, and use the appropriate function to move the
selection on.
- [On-demand item resource loading1]( {{< ref "#on-demand-item-resource-loading1" >}} ) — ensure list widget can look
up the item based on co-ordinates, and add a property to the list
item object to denote whether it’s in view, which the list widget
updates.
-[scroll bubbles1]( {{< ref "#scroll-bubbles1" >}} ) — add support for overlay actors to
`MxScrollBar`.
-[item headers1]( {{< ref "#item-headers1" >}} ) — Added as regular `ListItem`s in the adapter, a
`list_set_sticky_func` API is exposed.
- [Lazy list model]( {{< ref "#lazy-list-model" >}} ) — see [Alternative list adapter]( {{< ref "#alternative-list-adapter" >}} ), for an example
of how application developers may implement their own model.
- [Flow layout]( {{< ref "#flow-layout" >}} ) — The number of columns is calculated by dividing the
list width by the specified item width. Padding between the resulting
columns and rows may be specified using `row-spacing` and `column-spacing`
properties.
## Summary of recommendations
As discussed in the above sections, we recommend:
- Write a list widget partially based on `GtkListBox`, which subclasses
`ApertisWidget`.
- Write a list item widget partially based on `GtkListBoxRow` which also
subclasses ApertisWidget.
- Add a `motion-blur` property to `MxKineticScrollView`.
- Expose a sticky item callback registration method.
- Add support for overlay actors to `MxScrollBar`.
- Write a Roller widget as a list widget subclass.
- Ensure new widgets are easily customisable using CSS.
- Add demo programs for the new widgets.
- Define unit tests to run manually using the example programs to
check the widgets work
correctly.
## Appendix
### Existing roller design
![](/images/roller_api_diagram1.png)
![](/images/roller_api_diagram2.png)
[bubbles]: http://i.stack.imgur.com/YyRtC.png
[mx-scrollable]: https://github.com/clutter-project/mx/blob/master/mx/mx-scrollable.h
[`GListModel`]: https://developer.gnome.org/gio/stable/GListModel.html
[`GtkListBox`]: https://developer.gnome.org/gtk3/stable/GtkListBox.html
[`GtkFlowBox`]: https://developer.gnome.org/gtk3/stable/GtkFlowBox.html
[`GtkTreeView`]: https://developer.gnome.org/gtk3/stable/GtkTreeView.html
[`GtkContainer`]: https://developer.gnome.org/gtk3/stable/GtkContainer.html
[`ClutterActor`]: https://developer.gnome.org/clutter/stable/ClutterActor.html
[`MxKineticScrollView`]: https://github.com/clutter-project/mx/blob/master/mx/mx-kinetic-scroll-view.h
[GListModel-desc]: https://developer.gnome.org/gio/stable/GListModel.html#GListModel.description
[`GListStore`]: https://developer.gnome.org/gio/stable/GListStore.html
[GtkStyleProvider]: https://developer.gnome.org/gtk3/stable/GtkStyleProvider.html
[`ListAdapter`]: https://developer.android.com/reference/android/widget/ListAdapter.html
[ListAdapter-separators]: http://stackoverflow.com/questions/18302494/how-to-add-section-separators-dividers-to-a-listview
[hexagonal prism]: http://static.kidspot.com.au/cm_assets/32906/hexagonal-prism_346x210-jpg-20151022203100.jpg~q75,dx330y198u1r1gg,c--.jpg
[django-admin-fields]: https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fields
+++
title = "SDK"
short-description = "Software Development Kit purpose and design (partially-implemented, no available app validation tool, usability can be improved)"
weight = 100
toc = true
aliases = [
"/old-designs/latest/software-development-kit.html",
"/old-designs/v2019/software-development-kit.html",
"/old-designs/v2020/software-development-kit.html",
"/old-designs/v2021dev3/software-development-kit.html",
]
outputs = [ "html", "pdf-in",]
date = "2016-05-28"
+++
# Software Development Kit
## Definitions
- **Application Binary Interface (ABI) Stability**: the library
guarantees API stability and further guarantees dependent
applications and libraries will not require any changes to
successfully link against any future release. The library may
add new public symbols freely.
- **Application Programming Interface (API) Stability**: the
library guarantees to not remove or change any public symbols in
a way that would require dependent applications or libraries to
change their source code to successfully compile and link
against later releases of the library. The library may add new
public symbols freely. Later releases of the API-stable library
may include ABI breaks which require dependent applications or
libraries to be recompiled to successfully link against the
library. Compare to **ABI Stability**.
- **Backwards compatibility**: the guarantee that a library will
not change in a way that will require existing dependent
applications or libraries to change their source code to run
against future releases of the library. This is a more general
term than ABI or API stability, so it does not necessarily imply
ABI stability.
- **Disruptive release**: a release in which backwards
compatibility is broken. Note that this term is unique to this
project. In some development contexts, the term “major release”
is used instead. However, that term is ambiguous in general.
## Software Development Kit (SDK) Purpose
The primary purpose of the special SDK system image will be to enable
Apertis application and third-party library development. It will include
development tools and documentation to make this process as simple as
possible for developers. And a significant part of this will be the
ability to run the SDK within the VirtualBox PC emulator. VirtualBox
runs on ordinary x86 hardware which tends to make development much
simpler than a process which requires building and running
in-development software directly on the target hardware which will be of
significantly lower performance relative to developer computers.
## API/ABI Stability Guarantees
Collabora will carry along open source software components' API and ABI
stability guarantees into the Apertis Reference SDK API. In most cases,
this will be a guarantee of complete API and ABI stability for all
future releases with the same major version. Because these portions of
Apertis will not be upgraded to later disruptive releases, these
portions will maintain API and ABI stability at least for each major
release of Apertis.
The platform software included in the Reference system images will be in
the form of regular Debian packages and never in the form of
application-level packages, which are described in the “Apertis
Supported API” document. Collabora will manage API/ABI stability of the
platform libraries and prevent conflicts between libraries at this
level.
See the “Apertis Supported API” document for more details of specific
components' stability guarantees and the software management of
platform, core application, and third-party application software.
## Reference System Image Composition
See the document “Apertis Build and Integration”, section “Reference
System Image Composition”.
## System Image Software Licenses
See the document “Apertis Build and Integration” for details on license
checking and compliance of software contained in the system images.
## Development Workflow
### Typical Workflow
Most developers working on specific libraries or applications will not
be strictly dependent upon the exact performance characteristics of the
device hardware. And even those who are performance-dependent may wish
to work within the SDK when they aren't strictly tuning performance, as
it will yield a much shorter development cycle.
For these most-common use cases, a typical workflow will look like:
1. modify source code in Eclipse
2. build (for x86)
3. smoke-test within the Target Simulator
4. return to step 1. if necessary
In order to test this code on the actual device, the code will need to
be cross-compiled (see the document “Apertis Build and Integration
Design”, section “App cross-compilation”). To do so, the developer would
follow the steps above with:
1. run [Install to target]( {{< ref "#install-to-target" >}} ) Eclipse plugin
2. test package contents on device
3. return to step 1. if necessary
The development workflow for the Reference and derived images themselves
will be much more low-level and are outside the scope of this document.
### On-device Workflow
Some work, particularly performance tuning and graphics-intense
application development, will require testing on a target device. The
workflow [above][Typical workflow] handles this use case, but developing on a target device
can save the time of copying files from a development machine to the
device.
This workflow will instead look like:
1. modify source code as needed
2. run [Install to target]( {{< ref "#install-to-target" >}} ) Eclipse plugin
3. test package contents on device
4. if debugging is necessary, either
1. run [Remote app debugging]( {{< ref "#remote-app-debugging" >}} ) Eclipse plugin; or
2. open secure shell (ssh) connection to target device for
multi-process or otherwise-complex debugging scenarios
5. return to step 2. if necessary
### Workflow-simplifying Plugins
Some of the workflow steps [above][Typical worflow] will be simplified by streamlining
repetitive tasks and automating as much as possible.
#### Install to Target
This Eclipse plugin will automatically:
1. build the cross-architecture Apertis app bundle
2. copy generated ARM package to target
3. Install package
It will use a sysroot staging directory (as described in the document
“Apertis Build and Integration Design”, section “App
cross-compilation”) to build the app bundle and SSH to copy and
remotely and install it on the target.
App bundle signature validation will be disabled in the Debugging and
SDK images, so the security system will not interfere with executing
in-development apps.
#### Remote App Debugging
This Eclipse plugin will connect to a target device over SSH and, using
information from the project manifest file, execute the application
within GDB. The user will be able to run GDB commands as with local
programs and will be able to interact with the application on the device
hardware itself.
This plugin will be specifically created for single application
debugging. Developers of multi-process services will need to connect to
the device manually to configure GDB and other tools appropriately, as
it would be infeasible to support a wide variety of complex setups in a
single plugin.
#### Sysroot Updater
This Eclipse plugin will check for a newer sysroot archive. If found,
the newer archive will be downloaded and installed such that it can be
used by the [Install to target]( {{< ref "#install-to-target" >}} ) plugin.
## 3D acceleration within VirtualBox
Apertis will depend heavily on the Clutter library for animations in its
toolkit and for custom animations within applications themselves.
Clutter requires a working 3D graphics stack in order to function.
Without direct hardware support, this requires a software OpenGL driver,
which is historically very slow. Our proposed SDK runtime environment,
VirtualBox, offers experimental 3D hardware “pass-through” to achieve
adequate performance. However, at the time of this writing, this support
is unreliable and works only on very limited host hardware/software
combinations.
We propose resolving this issue with the new “llvmpipe” software OpenGL
driver for the Mesa OpenGL implementation. This is the
community-supported solution to replace the current,
significantly-slower, “swrast” software driver. Both the upcoming
versions of Fedora and Ubuntu Linux distributions will rely upon the
“llvmpipe” driver as a fallback in the case of missing hardware
support. The latest development version of Ubuntu 12.04, which Collabora
is developing our Reference system images against, already defaults to
“llvmpipe”. Additionally, the “llvmpipe” driver implements more
portions of the OpenGL standard (which Clutter relies upon) than the
“swrast” driver.
In initial testing with an animated Clutter/Clutter-GTK application,
llvmpipe performance was more than adequate for development purposes. In
a VirtualBox guest with 2 CPU cores and 3 GiB of RAM, demo applications
using the Roller widget displayed approximately 20-30 frames per second
and had very good interactivity with the llvmpipe driver. In comparison,
the same program running with the swrast driver averaged 4 frames per
second and had very poor interactivity.
While this approach will not perform as well as a hardware-supported
implementation, and will vary depending on host machine specifications,
it will be the most reliable option for a wide variety of VirtualBox
host operating system, configuration, and hardware combinations.
## Simulating Multi-touch in VirtualBox
Because Apertis will support multi-touch events and most VirtualBox
hosts will only have single pointing devices, the system will need a way
to simulate multi-touch events in software. Even with adequate hardware
on the host system, VirtualBox does not support multiple cursors, so the
simulating software must be fully-contained within the system images
themselves.
### Software-based solution
We propose a software-based solution for generating multi-touch events
within the SDK. This will require a few new, small components, outlined
below.
In the intended usage, the user would use the [Multi-touch gesture generator]( {{< ref "#multi-touch-gesture-generator" >}} )
to perform a gesture over an application running in the Target
Simulator as if interacting with the hardware display(s) in an Apertis
system. The Gesture Generator will then issue commands through its
uinput device and the [Uinput Gesture Device Xorg Driver]( {{< ref "#uinput-gesture-device-xorg-driver" >}} ) will use those
commands to generate native X11 multi-touch events. Applications running
within the Target Simulator will then interpret those multi-touch events
as necessary (likely through special events in the Apertis application
toolkit).
#### Multi-touch Gesture Generator
This will be a very simple user interface with a few widgets for each
type of gesture to generate. The developer will click on a button in the
generator to start a gesture, then perform a click-drag anywhere within
VirtualBox to trigger a set of multi-touch events. The generator will
draw simple graphics on the screen to indicate the type and magnitude of
the gesture as the developer drags the mouse cursor.
![](/images/example_gesture_generator_window.png)
We anticipate the need for two gestures commonly used in popular
multi-touch user interfaces:
- **Pinch/zoom**: the movement of a thumb and forefinger toward
(zoom-out) or away (zoom-in) from each other. This gesture has a
magnitude and position. The position allows, e.g., a map application
to zoom in on the position being pinched rather than requiring a
separate zoom into the center of the viewable area, then a drag of
the map.
- Zoom-in: simulated by initiating the pinch/zoom gesture from the
Gesture Generator, then click-dragging up-right. The distance
dragged will determine the magnitude of the zoom.
- Zoom-out: the same process as for zoom-in, but in the opposite
direction
- **Rotate**: the movement of two points around an imaginary center
point. Can be performed either in a clockwise or counter-clockwise
direction. This gesture has a magnitude and position. The position
allows, e.g., a photo in a gallery app to be rotated independent of
the other photos.
- Clockwise: simulated by initiating the rotate gesture, then
click-dragging to the right. This can be imagined as drag
affecting the top of a wheel.
- Counter-clockwise: the same process as for clockwise, but in the
opposite direction.
Additional gestures could be added during the specification process, if
necessary.
![](/images/onscreen_graphics_when_generating_gestures.png)
Upon the user completing the simulated gesture, the Gesture Generator
would issue a small number of key or movement events through a special
uinput device (which we will refer to as the Uinput Gesture Device).
Uinput is a kernel feature which allows “userland” software (any
software which runs directly or indirectly on top of the kernel) to
issue character device actions, such as key presses, releases,
two-dimensional movement events, and so on. This uinput device will be
interpreted by the [Uinput Gesture Device Xorg Driver]( {{< ref "#uinput-gesture-device-xorg-driver" >}} ).
#### Uinput Gesture Device Xorg Driver
This component will interpret the input stream from our Uinput Gesture
Device and generate X11 multi-touch events. These events would, in turn,
be handled by the windows lying under the events.
#### X11 Multi-touch Event Handling
Windows belonging to applications running within the Target Simulator
will need to handle multi-touch events as they would single-touch
events, key presses, and so on. This would require to add support for
multi-touch events in the Apertis application toolkit for applications
to simply handle multi-touch events the same as single-touch events.
### Hardware-based solution
An alternative to the software-based solution [above][Software-based solution] would be to use a
hardware multi-touch pad on the host machine. This is a simpler solution
requiring less original development though it brings a risk of Windows
driver issues which would be outside of our control. Because of this, we
recommend Collabora perform further research before finalizing upon this
solution if this is preferred over the [Software-based solution]( {{< ref "#software-based-solution" >}} ).
The touch pad hardware would need to be well-supported in Linux but not
necessarily the host operating system (including Windows) because
VirtualBox supports USB pass-through. This means that output from the
touch pad would simply be copied from the host operating system into
VirtualBox, where Xorg would generate multi-touch events for us.
The best-supported multi-touch device for Linux is Apple's Magic
Trackpad. This device uses a Bluetooth connection. Many Bluetooth
receivers act as USB devices, allowing pass-through to VirtualBox. In
case a host machine does not have a built-in Bluetooth receiver or has a
Bluetooth receiver but does not route Bluetooth data through USB, an
inexpensive Bluetooth-to-USB adapter could be used.
Collabora has verified that multi-touch gestures on an Apple Magic
Trackpad plugged into a Linux host can be properly interpreted within
Debian running within VirtualBox. This suggests that a hardware-based
solution is entirely feasible.
#### Hardware Sourcing Risks
Collabora investigated risks associated with selecting a single hardware
provider for this multi-touch solution. The known risks at this point
include:
1. Apple has a history of discontinuing product lines with little
warning
2. As of this writing, there appear to be few alternative multi-touch
pointing devices which are relatively inexpensive and support
arbitrary multi-touch movements
In the worst case scenario, Apple could discontinue the Magic Trackpad
or introduce a new version which does not (immediately) work as expected
within Linux. With no immediate drop-in replacement for the Magic
Trackpad, there would not be a replacement to recommend internally and
to third-party developers using the Apertis SDK.
However, there are several mitigating factors that should make these
minor risks:
1. Inventory for existing Magic Trackpads would not disappear
immediately upon discontinuation of the product
2. Discontinuation of a stand-alone multi-touch trackpad entirely is
very unlikely due to Apple's increasingly-strong integration of
multi-touch gestures within iOS and Mac OS itself.
3. In case Apple replaces the Magic Trackpad with a Linux-incompatible
version, there is significant interest within the Linux community to
fix existing drivers to support the new version in a timely manner.
For instance, Canonical multi-touch developers use the Magic
Trackpad for their development and will share Apertis's sourcing
concerns as well.
4. As an ultimate fallback, [Multi-touch gesture generator]( {{< ref "#multi-touch-gesture-generator" >}} ) can be
recommended as an alternative source of multi-touch input.
## Third-party Application Validation Tools
### Two-step Application Validation Process
The third-party application process will contain two main validation
steps which mirror the application submission processes for Android and
iOS apps. The first, SDK-side validation checks will be performed by a
tool described below. Developers may perform SDK-side validation as
often as they like before submitting their application for approval.
This is meant to automatically catch as many errors in an application as
soon as possible to meet quality requirements for application review.
The second step of the application validation process is to validate
that an application meets the app store quality requirements. It is
recommended to set up a process where new applications automatically get
run through this same Eclipse plugin as an initial step in review. This
will guarantee applications meet the latest automated validation checks
(which may not have been met within the developer's SDK if their Eclipse
plugin were old). Developers will be able to easily stay up-to-date with
the validation tool by applying system package updates within the SDK,
so this difference can be minimized by a small amount of effort on the
developer's part. Applications which pass this initial check will then
continue to a manual evaluation process.
### App Validation Tool
To streamline the third-party application submission process (which will
be detailed in another document), Collabora will provide an Eclipse
plugin to perform a number of
SDK-side validation checks up on the application in development.
Collabora proposed checks are:
- **Application contains valid developer signing key** – developers
must create a certificate to sign their application releases so
verifying the source of application updates can be guaranteed. This
check will ensure that the certificate configured for the
application meets basic requirements on expiration date and other
criteria.
- **Manifest file is valid** – the application manifest file, which
will be used in the software management of third-party applications
on the platform, must meet a number of basic requirements including
a developer name, application categories, permissions, minimum SDK
API, and more.
- **Application builds from cleaned source tree** – this step will
delete files in the source tree which are neither included in the
project nor belong to the version control system and perform a full
release build for the ARMHF architecture. Build warnings will be
permitted but build errors will fail this check.
- **AppArmor profile is valid** – the application's AppArmor profile
definition must not contain invalid syntax or conflict with the
Apertis global AppArmor configuration
Third-party application validation will be specified in depth in another
document.
## General approach to third-party applications
In most cases, third-party applications should not need to explicitly
validate their access to specific system resources, delegating as much
as possible to the SDK API or to other parts of the system. Preferably,
these applications will specify system resource requirements in their
manifest, such as permissions the application needs to function, network
requirements, and so on. The main advantages of having these in the
manifest file are using shared code to perform some of the actual
run-time resource requests.
Note that this strategy implies a trade-off between how simple it is to
write an application and how complex the supporting SDK and system
components need to be to provide that simplicity. That is to say, it
often makes sense to impose complexity onto applications, in particular
when it's expected that only a few will have a given requirement or use
case. This general approach should be kept in mind while designing the
SDK and any other interfaces the system has with third-party
applications and their manifests.
......@@ -39,7 +39,7 @@ following conventions:
All the instructions below assume an Apertis development enviroment: either
boot the
[Apertis SDK]( {{< ref "software-development-kit.md" >}} )
[Apertis SDK]( {{< ref "virtualbox.md" >}} )
or enter the `apertis-*-package-source-builder` Docker container:
APERTIS_RELEASE=v2019pre
......
......@@ -99,7 +99,7 @@ You should then be able to SSH in using:
The recommended environment to build platform packages and application bundles
is the
[Apertis SDK]( {{< ref "software-development-kit.md" >}} ).
[Apertis SDK]( {{< ref "virtualbox.md" >}} ).
However, it is also possible to build software on the devices directly with the
preparation steps below:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment