aboutsummaryrefslogtreecommitdiffstats
path: root/docs/05_Component_Documentation/Application_Framework
diff options
context:
space:
mode:
Diffstat (limited to 'docs/05_Component_Documentation/Application_Framework')
-rw-r--r--docs/05_Component_Documentation/Application_Framework/01_Introduction.md164
-rw-r--r--docs/05_Component_Documentation/Application_Framework/02_Application_Startup.md248
-rw-r--r--docs/05_Component_Documentation/Application_Framework/03_Creating_a_New_Application.md233
-rw-r--r--docs/05_Component_Documentation/Application_Framework/04_Application_Sandboxing.md92
-rwxr-xr-xdocs/05_Component_Documentation/Application_Framework/images/application_switching.msc29
-rw-r--r--docs/05_Component_Documentation/Application_Framework/images/application_switching.pngbin0 -> 31633 bytes
-rwxr-xr-xdocs/05_Component_Documentation/Application_Framework/images/start_and_activation.msc30
-rw-r--r--docs/05_Component_Documentation/Application_Framework/images/start_and_activation.pngbin0 -> 36479 bytes
8 files changed, 796 insertions, 0 deletions
diff --git a/docs/05_Component_Documentation/Application_Framework/01_Introduction.md b/docs/05_Component_Documentation/Application_Framework/01_Introduction.md
new file mode 100644
index 0000000..32c6bb0
--- /dev/null
+++ b/docs/05_Component_Documentation/Application_Framework/01_Introduction.md
@@ -0,0 +1,164 @@
+---
+title: Introduction
+---
+
+# Foreword
+
+AGL has worked at providing the components of an application framework for many
+years. However, the implementation used up until the `lamprey` release was retired
+starting with the `marlin` release, and replaced with a redesigned one.
+However, this new implementation does not aim to be a 1:1 replacement, and as such
+it does not provide all of the features of the previous framework. Some of those
+will be added back over time, while others have been discarded in favor of more
+modern and/or widely-used alternatives.
+
+With the `needlefish` release, further evolution of the replacement framework included:
+
+- Using [gRPC IPC](https://grpc.io/about) for the application launcher API.
+ The interim D-Bus based API was deprecated at this time, and removed in the
+ `ricefish` release.
+- Using only systemd unit metadata in the application launcher instead of using
+ [Desktop Entry specification](https://www.freedesktop.org/wiki/Specifications/desktop-entry-spec/)
+ to list applications, and relying entirely on systemd for the application
+ lifecycle, rather than spawning them directly.
+
+# Introduction
+
+With a goal of being the provider of an integrated solution to build up on, it
+is useful for AGL to define a reliable and well-specified method for managing
+the deployment and integration of applications and services, as well as the way
+they can interact with the rest of the system.
+
+This is achieved by providing a common set of rules and components, known as
+the application framework. By documenting those rules, application developers can
+have a good understanding of the requirements for creating and packaging applications
+targeting AGL-based systems that leverage the upstream application framework components.
+Likewise, system developers and integrators have a clear path for including such
+applications in AGL-based products.
+
+The application framework's scope extends to the following areas:
+
+- system services integration and lifecycle management
+- user-level application lifecycle management
+- inter-process communication
+
+In order to be as simple as possible and avoid any unneeded custom
+implementation, the application framework relies mainly on third-party
+technologies and/or software components. They include:
+
+- [systemd](https://www.freedesktop.org/wiki/Software/systemd/): system
+ services and user session services management
+
+- [gRPC](https://grpc.io/about): inter-process communication, new recommmended
+ system-wide IPC, which should be used instead of D-Bus.
+
+Note that while there are many open source software projects in the desktop Linux
+space using [D-Bus](https://www.freedesktop.org/wiki/Software/dbus/) for inter-process
+communication, AGL has decided to avoid using it for new development projects for the
+following reasons:
+
+- It has proven challenging in the past to manage dependencies between and the
+ start-up of system and per-user D-Bus services in AGL.
+- Managing the security of D-Bus APIs involves the use of PolicyKit, which is
+ somewhat heavyweight and not widely understood. As well, providing D-Bus
+ access to applications running inside containers or other sandbox schemes can
+ be significantly more complicated than e.g. using gRPC with authorization token
+ access control.
+- D-Bus is not widely used in application development ecosystems outside of desktop
+ Linux. This matters when engaging with application developers in newer ecosystems
+ such as web applications or Flutter.
+
+AGL also provides reference implementations whenever possible and relevant,
+located in the [meta-agl](../../04_Developer_Guides/02_AGL_Layers/02_meta_agl.md)
+layer under `meta-app-framework`. At the moment, the application framework
+contains two such components:
+
+- `agl-session`: `systemd` unit files for user sessions management
+- `applaunchd`: application launcher service
+
+# Service Management
+
+Both system and user services are managed by `systemd`, which provides a number
+of important features, such as dependency management or service monitoring:
+when starting a service, `systemd` will ensure any other units this service
+depends on are available, and otherwise start those dependencies. Similarly,
+`systemd` can automatically restart a crashed service, ensuring minimal
+downtime.
+
+`systemd` also provides an efficient first layer of security through its
+[sandboxing](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Sandboxing)
+and other security-related options.
+
+It is also well integrated with D-Bus and can be used for a more fine-grained
+control over D-Bus activated services. By delegating the actual service start-up
+to `systemd`, developers can take advantage of its advanced features, allowing
+for improved reliability and security.
+
+Each service should be represented by a `systemd` unit file installed to the
+appropriate location. More details can be obtained from the [Creating a New
+Service](../../04_Developer_Guides/03_Creating_a_New_Service.md) document.
+
+# User Session Management
+
+Similarly, user sessions and the services they rely on are also managed by
+`systemd`. Prior to the `ricefish` release, AGL used a user session for the
+`agl-driver` user for the running of user facing applications, including the
+compositor. This has been replaced with using system units that use the
+`User` directive. The reason for this is two-fold:
+
+- Several useful systemd sandboxing features are unavailable to user session
+ units, or would require the use of unprivileged namespace mounting. The
+ latter is not necessarily available in vendor BSP kernels, and the security
+ characteristics of it are still a matter of some debate.
+- Encoding dependencies between user session and system units is sometimes
+ not straightforward or impossible.
+
+# Inter-process Communication
+
+In order to provide a language-independent, "standard", IPC mechanism and avoid
+the need for maintaining custom bindings for each programming language to be
+used on top of AGL, the application framework previously promoted the use of
+[D-Bus](https://www.freedesktop.org/wiki/Software/dbus/) as the preferred way
+for applications to interact with services. Starting with `needlefish` release,
+this has changed to recommending [gRPC](https://grpc.io) for our system-wide IPC,
+with D-Bus being kept to provide functionality to services and applications
+which haven't transitioned yet to using gRPC.
+
+Most services already included in AGL provide one or several D-Bus interfaces,
+and can therefore interact with D-Bus capable applications and services
+without requiring any additional component. Those services include, among
+others:
+
+- [ConnMan](https://git.kernel.org/pub/scm/network/connman/connman.git/):
+ network connectivity
+
+- [BlueZ](http://www.bluez.org/): Bluetooth connectivity
+
+- [oFono](https://git.kernel.org/pub/scm/network/ofono/ofono.git): telephony
+ and modem management
+
+- [GeoClue](https://gitlab.freedesktop.org/geoclue/geoclue/-/wikis/home):
+ geolocation
+
+Similarly, ongoing work involves expanding various services to expose a
+gRPC interface.
+
+# Application Launcher Service
+
+The Application Framework used to follow the guidelines of the [Desktop Entry
+specification](https://www.freedesktop.org/wiki/Specifications/desktop-entry-spec/)
+for application enumeration and start-up, but with the `needlefish` release
+instead it relies on systemd to provide that functionality, indirectly, by
+using the `applaunchd` application.
+
+As no simple reference implementation exists for this part of the
+specification, AGL provides an application launcher service named `applaunchd`.
+This service is part of the default user session, and as such is automatically
+started on session start-up. It can therefore be considered always available.
+
+`applaunchd` enumerates applications installed on the system and provides a
+gRPC interface for services and applications to:
+
+- query the list of available applications
+- request the start-up of a specific application
+- be notified when applications are started or terminated
diff --git a/docs/05_Component_Documentation/Application_Framework/02_Application_Startup.md b/docs/05_Component_Documentation/Application_Framework/02_Application_Startup.md
new file mode 100644
index 0000000..8594426
--- /dev/null
+++ b/docs/05_Component_Documentation/Application_Framework/02_Application_Startup.md
@@ -0,0 +1,248 @@
+---
+title: Application Launcher
+---
+
+# Introduction
+
+At system runtime, it may be necessary for applications to start other
+applications on demand. Such actions can be executed in reaction to a user
+request, or they may be needed to perform a specific task.
+
+In order to do so, running applications and services need an established way of
+discovering installed applications and executing those.
+
+In order to provide a language-independent interface for applications and
+service to use, AGL includes `applaunchd`, a system service.
+
+# Application Launcher Service
+
+The purpose of `applaunchd` is to enumerate applications available on the
+system and provide a way for other applications to query this list and start
+those on demand. It is also able to notify clients of the start-up and
+termination of applications it manages.
+
+To that effect, `applaunchd` provides a gRPC interface which other applications
+can use in order to execute those actions.
+
+*Note: `applaunchd` will only send notifications for applications it started;
+it isn't aware of applications started by other means (`systemd`, direct
+executable call...), and therefore can't send notifications for those.*
+
+## Application Discovery
+
+Applications are enumerated from systemd's list of available units based on the
+pattern `agl-app*@*.service`, and are started and controled using their systemd
+unit. Please note `applaunchd` allows only one instance of a given
+application.
+
+## Application Identifiers
+
+Each application is identified by a unique Application ID. Although this ID can
+be any valid string, it is highly recommended to use the "reverse DNS"
+convention in order to avoid potential name collisions.
+
+## gRPC Interface
+
+The interface provides methods for the following actions:
+
+- retrieve the list of available applications
+- request an application to be started
+- subscribe to status events
+
+Moreover, with the gRPC the client subscribes to a status signal to be notified
+when an application has successfully started or its execution terminated.
+
+The gRPC protobuf file provides a Request and Response arguments to RPC methods
+even though in some cases these might be empty in order to allow forward
+compatibility in case additional fields are required.
+It is a good standard practice to follow up with these recommendation when
+developing a new protobuf specification.
+
+### Application Enumeration
+
+The `ListApplications` method allows clients to retrieve the list of available
+applications.
+
+The `ListRequest` is an empty message, while `ListResponse` contains the following:
+
+```
+message AppInfo {
+ string id = 1;
+ string name = 2;
+ string icon_path = 3;
+}
+
+message ListResponse {
+ repeated AppInfo apps = 1;
+}
+```
+
+### Application Start-up
+
+Applications can be started by using the `StartApplication` method, passing the
+`StartRequest` message, defined as:
+
+```
+message StartRequest {
+ string id = 1;
+}
+```
+
+In reply, the following `StartResponse` will be returned:
+
+```
+message StartResponse {
+ bool status = 1;
+ string message = 2;
+}
+```
+
+The "message" string of `StartResponse` message will contain an error message
+in case we couldn't start the application for whatever reason, or if the "id"
+isn't a known application ID. The "status" string would be boolean set to
+boolean `TRUE` otherwise.
+
+If the application is already running, `applaunchd` won't start another
+instance, but instead reply with a `AppStatus` message setting the `status`
+string to "started".
+
+### Status Notifications
+
+The gRPC interface provides clients with a subscription model to receive
+status events. Client should subscribe to `GetStatusEvents` method to receive
+them.
+
+The `StatusRequest` is empty, while the `StatusResponse` is defined as
+following:
+
+```
+message AppStatus {
+ string id = 1;
+ string status = 2;
+}
+
+message LauncherStatus {
+}
+
+message StatusResponse {
+ oneof status {
+ AppStatus app = 1;
+ LauncherStatus launcher = 2;
+ }
+}
+```
+
+As mentioned above, the `status` string is set to "started" and is also emitted
+if `applaunchd` receives a request to start an already running application.
+This can be useful, for example, when switching between graphical applications:
+
+- the application switcher doesn't need to track the state of each application;
+ instead, it can simply send a `StartApplication` request to `applaunchd`
+ every time the user requests to switch to another application. Obviously, the
+ client needs to subscribe to get these events and act accordingly.
+- the shell client then receives the `StatusResponse` with the message `status`
+ string set to "started" indicating it that it should activate the window with
+ the corresponding `id` string, or alternatively the string `status` is
+ set to "terminated" to denote that the application has been terminated,
+ forcibly or not
+
+## Start-up, Activation, and Application Switching
+
+Application start-up, activation and application switching are sometimes
+conflated into a single operation but underneath some of these are distinct
+steps, and a bit flaky in some circumstances.
+The [AGL compositor](../02_agl_compositor.md) has
+some additional events which one can use when creating an application
+start-up & switching scheme in different run-times.
+
+Start-up of application is handled entirely by `applaunchd` service while
+activation -- the window which I want to display, but which has never been
+shown, and application switching -- bring forward an application already
+shown/displayed in the past, are operations handled entirely by the
+AGL compositor.
+
+The issue stems from the fact that underneath `applaunchd` can't make any
+guarantees when the application actually started, as it calls into libsystemd
+API to start the specific application systemd unit.
+
+If `StartApplication` can't start the systemd unit, it returns a false
+`status` boolean value and a error message in `StartResponse` message, but if
+the application is indeed started we doesn't really know the *moment* when the
+application is ready to be displayed. Additionally, the AGL compositor
+performed the activation on its own when it detected that a new application
+has been started, but that implicit activation can now be handled outside
+by the desktop run-time/shell client.
+
+*Note: Some of the run-times still rely on the compositor to perform activation
+as this synchronization part between `applaunchd` has not been implemented. The
+plan is to migrate all of remaining run-times to using this approach.*
+
+### Start-up and Activation
+
+This means that we require some sort of interaction between `StartApplication`
+method and the events sent by the AGL compositor in order to correctly handle
+start-up & activation of application.
+
+There are couple of ways of achieving that, either using Wayland native calls,
+or using the gRPC proxy interface, which underneath is using the same Wayland
+native calls.
+
+For the first approach, the AGL compositor has an `app_state` Wayland event
+which contains the application ID, and an enum `app_state` that will propagate
+the following application state events:
+
+```
+<enum name="app_state" since="3">
+ <entry name="started" value="0"/>
+ <entry name="terminated" value="1"/>
+ <entry name="activated" value="2"/>
+ <entry name="deactivated" value="3"/>
+</enum>
+```
+
+The `started` event can be used in correlation with the `StartApplication`
+method from `applaunchd` such that upon received the `started` even, it can
+explicitly activate that particular appid in order for the compositor to
+display it. See [AGL compositor](../02_agl_compositor.md)
+about how activation should be handled.
+
+*Note: These can only be received if by the client shell which binds to the
+agl_shell interface*.
+
+Alternatively, when using the gRPC proxy one can register to receive these
+status events similar to the `applaunchd` events, subscribing to
+`AppStatusState` method from the grpc-proxy helper application, which has the
+following protobuf messages:
+
+```
+message AppStateRequest {
+}
+message AppStateResponse {
+ int32 state = 1;
+ string app_id = 2;
+}
+```
+
+The integer state maps to the `enum app_state` from the Wayland protocol, so
+they are a 1:1 match.
+
+Here's the state diagram for the Qt homescreen implementation of the
+application start-up:
+
+![Application_start](images/start_and_activation.png)
+
+### Application Switching
+
+With the compositor providing application status events, it might seem that the
+`applaunchd`'s, `GetStatusEvents` might be redundant, but in fact it is being
+used to perform application switching. The run-time/shell client would in fact
+subscribe to `GetStatusEvents` and each application wanting to switch to another
+application would basically call `StartApplication`. That would eventually reach
+the run-time/shell-client and have a handler that would ultimately activate the
+application ID.
+
+![Application_switching](images/application_switching.png)
+
+*Note: In practice, the run-time/shell-client would subscribe to both `applaunchd`
+and to the AGL compositor, either Wayland native events, or using the gPRC-proxy
+helper client, although the diagrams show them partly decoupled*.
diff --git a/docs/05_Component_Documentation/Application_Framework/03_Creating_a_New_Application.md b/docs/05_Component_Documentation/Application_Framework/03_Creating_a_New_Application.md
new file mode 100644
index 0000000..aa528b1
--- /dev/null
+++ b/docs/05_Component_Documentation/Application_Framework/03_Creating_a_New_Application.md
@@ -0,0 +1,233 @@
+---
+title: Creating a New Application
+---
+
+In the context of AGL, "applications" are usually considered to be standalone
+user facing infotainment applications that can be started in addition to the
+default "homescreen" or similar user interface that will always be present.
+Such applications can be enumerated and executed with `applaunchd`, the AGL
+[application launcher service](02_Application_Startup.md). The following
+sections walk through what is required to add an application to an AGL image
+that uses applaunchd, as well as discussion of developer conveniences that
+AGL provides to simplify doing so in the Yocto build environment.
+
+# Basic Requirements
+
+As described in the [applaunchd documentation](02_Application_Startup.md#application-discovery),
+applications need to have a systemd system unit with a name matching the pattern `agl-app*@*.service`.
+The portion of the unit name between `@` and `.service` is used as the application identifier
+(see [Application Identifiers](02_Application_Startup.md#application-identifiers)).
+The use of `@` in the unit filename indicates the use of a template unit, which `applaunchd`
+assumes will be used for applications (see below). Template unit files are discussed in the
+systemd unit file [man page](https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Description).
+
+The requirements on the unit file contents are:
+
+- The `Description` field is used as the desired display name of the application.
+ It is recommended that this be kept short, ideally to one or two words, in order to
+ avoid issues when applications are listed in a UI.
+- While not a hard requirement, ideally the `User` field is used to specify running
+ the application as a non-privileged user. In the AGL demonstration images, the
+ `agl-driver` user is used.
+
+Blah blah icon...
+
+# Graphical Application Requirements
+
+In addition, graphical applications need to comply with a few more requirements:
+
+1. Each application must set a Wayland application ID appropriately as soon as its main window
+is created.
+2. The `app-id` used must match the application identifier specified in the systemd unit filename.
+
+Doing so will ensure other software can associate the actual `app-id` to the proper application.
+
+*Note: application ID's are set using the [XDG toplevel](https://wayland-book.com/xdg-shell-basics/xdg-toplevel.html)
+Wayland interface.*
+
+# Application Templates
+
+To provide a working example of application template units, AGL includes templates
+for generic, Flutter, and web applications as part of the `applaunchd` recipe in the
+`meta-app-framework` layer in [meta-agl](../../04_Developer_Guides/02_AGL_Layers/02_meta_agl.md).
+If applaunchd is built into an image using the recipe, these templates will be available
+for applications to use for their systemd units by creating a symlink that includes the
+application identifier. To simplify this, a `BitBake` class named `agl-app` is included in
+the layer for use in application recipes. The different templates and their configuration
+will be discussed further in the following sections.
+
+## Generic Graphical Application Template
+
+The `agl-app@.service` template unit is intended for simple standalone graphical applications.
+It makes the following assumptions by default:
+
+- The application executable name is the same as the application identifier, and the
+ executable is available via the default `PATH`.
+- The application `Description` will be the application identifier.
+- The application should run as the `agl-driver` user.
+
+If using the `agl-app` class in a recipe (with `inherit agl-app`), these defaults can be
+changed via the variables:
+
+- `AGL_APP_NAME`: overrides the value of the `Description` field to set the desired
+ application display name.
+- `AGL_APP_EXEC`: overrides the application executable name.
+
+If set, these variables will trigger the generation of one or more systemd `drop-in`
+override files by the logic in the `agl-app` class. The use of `drop-in` configuration
+files is discussed in the systemd unit file [man page](https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Description).
+
+Additionally, the variable `AGL_APP_ID` may be used to override the assumption that the
+application identifier is the same as the recipe name. If specified, its value should be
+the desired application identifier.
+
+The following is a partial example BitBake recipe using the template for an application named
+`foo`:
+
+```text
+
+SUMMARY = "foo application"
+HOMEPAGE = "https://git.automotivelinux.org/apps/foo"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=ae6497158920d9524cf208c09cc4c984"
+
+PV = "1.0+git${SRCREV}"
+
+SRC_URI = "git://git.automotivelinux.org/apps/foo;protocol=https;branch=master"
+SRCREV = "abcdef012"
+
+S = "${WORKDIR}/git"
+
+inherit agl-app
+
+AGL_APP_NAME = "Foo"
+
+<Other application build configuration>
+```
+
+Note that this assumes that the recipe is named `foo_git.bb`. If the recipe was instead named
+something like `foo-app_git.bb`, then `AGL_APP_ID = "foo"` would need to be added.
+
+## Flutter Application Template
+
+The `agl-app-flutter@.service` template unit is intended for Flutter graphical applications
+that use the `flutter-auto` Flutter embedder. It makes the following assumptions by default:
+
+- The Flutter application name in `pubspec.yaml` is the same as the application identifier,
+and the application bundle will be installed under the directory:
+ ```text
+ /usr/share/flutter/<application identifier>/<Flutter version>/<Flutter runtime type>
+ ```
+ For example:
+ ```text
+ /usr/share/flutter/flutter_hvac/3.3.7/release
+ ```
+
+- The application `Description` will be the application identifier.
+- The application should run as the `agl-driver` user.
+
+If using the `agl-app` class in a recipe (with `inherit agl-app`), the use of the Flutter
+template can be triggered by setting the variable `AGL_APP_TEMPLATE` to `agl-app-flutter`,
+and the above defaults can be changed via the variables:
+
+- `AGL_APP_NAME`: overrides the value of the `Description` field to set the desired
+ application display name.
+
+If set, this will trigger the generation of a systemd `drop-in` override file by the logic
+in the `agl-app` class. The use of `drop-in` configuration files is discussed in the systemd
+unit file [man page](https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Description).
+
+Additionally, the variable `AGL_APP_ID` may be used to override the assumption that the
+application identifier is the same as the recipe name. If specified, its value should be
+the desired application identifier and Flutter application / bundle name.
+
+The following is an example BitBake recipe using the template for a Flutter application
+named `foo`:
+
+```text
+
+SUMMARY = "Flutter foo application"
+HOMEPAGE = "https://git.automotivelinux.org/apps/flutter-foo"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://License.md;md5=f712ede8d4f845976061925d1416fc40"
+
+PV = "1.0+git${SRCREV}"
+
+SRC_URI = "git://git.automotivelinux.org/apps/flutter-foo;protocol=https;branch=master"
+SRCREV = "abcdef012"
+
+S = "${WORKDIR}/git"
+
+inherit flutter-app agl-app
+
+PUBSPEC_APPNAME = "foo"
+FLUTTER_APPLICATION_INSTALL_PREFIX = "/flutter"
+
+AGL_APP_TEMPLATE = "agl-app-flutter"
+AGL_APP_NAME = "Foo"
+```
+
+Note that this assumes that the recipe is named `foo_git.bb`, and that the application name
+in the Flutter `pubspec.yaml` is `foo`. If the recipe was instead named something like
+`flutter-foo_git.bb`, then `AGL_APP_ID = "foo"` would need to be added.
+
+## Web Application Template
+
+The `agl-app-web@.service` template unit is intended for web applications run using the
+Web Application Manager (WAM) service. It makes the following assumptions by default:
+
+- The web application bundle directory name is the same as the application identifier, and the
+ bundle will be installed in the directory hierarchy:
+ ```
+ /usr/lib/wam_apps/<application identifier>
+ ```
+ For example:
+ ```
+ /usr/lib/wam_apps/webapps-hvac
+ ```
+- The application `Description` will be the application identifier.
+- The application should run as the `agl-driver` user.
+
+If using the `agl-app` class in a recipe (with `inherit agl-app`), the use of the Flutter
+template can be triggered by setting the variable `AGL_APP_TEMPLATE` to `agl-app-web`,
+and the above defaults can be changed via the variables:
+
+- `AGL_APP_NAME`: overrides the value of the `Description` field to set the desired
+ application display name.
+- `AGL_APP_WAM_DIR`: overrides the application bundle directory name. This can be used if
+ the application bundle name does not match the application identifier.
+
+If set, these variables will trigger the generation of one or more systemd `drop-in`
+override files by the logic in the `agl-app` class. The use of `drop-in` configuration
+files is discussed in the systemd unit file [man page](https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Description).
+
+Additionally, the variable `AGL_APP_ID` may be used to override the assumption that the
+application identifier is the same as the recipe name.
+
+The following is a partial example BitBake recipe using the template for a web application
+named `foo`:
+
+```text
+
+SUMMARY = "Web foo application"
+HOMEPAGE = "https://git.automotivelinux.org/apps/web-foo"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"
+
+PV = "1.0+git${SRCREV}"
+
+SRC_URI = "git://git.automotivelinux.org/apps/web-foo;protocol=https;branch=master"
+SRCREV = "abcdef012"
+
+S = "${WORKDIR}/git"
+
+inherit agl-app
+
+AGL_APP_TEMPLATE = "agl-app-web"
+AGL_APP_NAME = "Foo"
+
+<Other web application build configuration>
+```
+
+Note that this assumes that the recipe is named `foo_git.bb`. If the recipe was instead named
+something like `foo-web_git.bb`, then `AGL_APP_ID = "foo"` would need to be added.
diff --git a/docs/05_Component_Documentation/Application_Framework/04_Application_Sandboxing.md b/docs/05_Component_Documentation/Application_Framework/04_Application_Sandboxing.md
new file mode 100644
index 0000000..356c0eb
--- /dev/null
+++ b/docs/05_Component_Documentation/Application_Framework/04_Application_Sandboxing.md
@@ -0,0 +1,92 @@
+---
+title: Application Sandboxing
+---
+
+One of the motivations for leveraging systemd in `applaunchd` was to allow the use of its
+advanced features such as [sandboxing](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Sandboxing),
+[system call filtering](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#System%20Call%20Filtering),
+[process limits](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Process%20Properties), and
+Linux CGroup configuration via [slices](https://www.freedesktop.org/software/systemd/man/systemd.slice.html).
+The scope of potential systemd configurations involving these options is broad, and so far AGL has focused on providing
+some simple examples of basic sandboxing integrated with the application templates discussed above.
+
+## Network Access Restriction
+
+The systemd [`PrivateNetwork`](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateNetwork=)
+service configuration option can be used to disable network access for the service started by a unit file.
+The `applaunchd` packaging installs a systemd drop-in configuration file named `no-network.conf` in the
+directory `/usr/lib/systemd/system/sandboxing` that may be used to disable network access with `PrivateNetwork`.
+To use it, `no-network.conf` should be symlinked in an appropriate unit file drop-in override directory per
+systemd naming expectations (see systemd unit file
+[man page](https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Description)).
+The following is a `BitBake` recipe snippet showing installation of the drop-in for an application named `foo`
+that is using the generic application template:
+
+```text
+...
+
+inherit agl-app
+
+AGL_APP_NAME = "Foo"
+
+do_install() {
+ # Enable systemd sandboxing override as a demonstration
+ install -d ${D}${systemd_system_unitdir}/agl-app@${AGL_APP_ID}.service.d/
+ ln -sf ${systemd_system_unitdir}/sandboxing/no-network.conf ${D}${systemd_system_unitdir}/agl-app@${AGL_APP_ID}.service.d/
+}
+
+FILES:${PN} = " \
+ ${sysconfdir}/systemd/system/agl-app@${AGL_APP_ID}.service.d \
+"
+
+...
+```
+
+This results in a `/usr/lib/systemd/system/agl-app@foo.service.d/no-network.conf` symlink being created
+in the `foo` packaging, disabling network access when `foo` is started by `applaunchd` or directly via
+`systemctl` on the command line.
+
+## Private Temporary Directories
+
+The systemd [`PrivateTmp`](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateTmp=)
+service configuration option can be used to prevent access to the host `/tmp` and `/var/tmp` directories
+for the service started by a unit file. The service will instead have private temporary mounts of these
+directories in a new mount namespace. The `applaunchd` packaging installs a systemd drop-in configuration
+file named `private-tmp.conf` in the directory `/usr/lib/systemd/system/sandboxing` that may be used to
+create private temporary directory mounts with `PrivateTmp`. To use it, `private-tmp.conf` should be
+symlinked in an appropriate unit file drop-in override directory per systemd naming expectations (see
+systemd unit file [man page](https://www.freedesktop.org/software/systemd/man/systemd.unit.html#Description)).
+See above for an example `BitBake` recipe snippet showing installation of a drop-in file when using the
+generic application template.
+
+## Other Sandboxing Options
+
+In addition to the above, some other notable systemd sandbox options worth further consideration for
+applications include:
+
+- [PrivateDevices](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateDevices=)
+ This option could be used to remove access to device files in /dev for applications that do not
+ require them, but it is likely that `DeviceAllow` may also need to be used to enable functionality in
+ some applications.
+- [ProtectSystem](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectSystem=)
+ The default and `full` modes of this option likely can be enabled with little impact to most
+ applications, as they should not need write access to the directories that are made read-only.
+ Using the `strict` option would need investigation into interactions with usage of directory
+ hierarchies like `/run`.
+- [ProtectHome](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectHome=)
+ This option seems worthwhile if the system ends up with more than one active user for running
+ applications, but interactions with default application caching and configuration locations
+ needs to be investigated. It is likely that enforcing use of locations outside of `/home`
+ for these would need to be settled upon and documented for application developers. For
+ example using the [XDG directory scheme](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
+ similar to the previous AGL application framework.
+- [ReadWritePaths, etc.](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ReadWritePaths=)
+ These options provide a more fine-grained approach to some of the above ones, and could be
+ used to enable something like an application only seeing its own files and the contents of
+ a specific set of directories like `/etc` and `/usr/lib`. Implementing such would likely
+ require settling on a custom application installation hierarchy as was done in the previous
+ AGL application framework.
+
+The above list is not exhaustive, and does not include some other likely possibilities involving
+system call filtering and resource limits. Future AGL releases may expand the examples provided
+with `applaunchd` along these lines.
diff --git a/docs/05_Component_Documentation/Application_Framework/images/application_switching.msc b/docs/05_Component_Documentation/Application_Framework/images/application_switching.msc
new file mode 100755
index 0000000..ceeab7c
--- /dev/null
+++ b/docs/05_Component_Documentation/Application_Framework/images/application_switching.msc
@@ -0,0 +1,29 @@
+#!/usr/bin/mscgen -Tpng
+
+msc {
+ hscale="1.5";
+
+ u [label = "touch/pointer event" ],
+ l [label = "launcher app" ],
+ s [label = "runtime/shell-client"],
+ a [label = "applaunchd" ],
+ g [label = "gRPC-proxy" ],
+ c [label = "compositor" ],
+ d [label = "libsystemd"];
+
+ |||;
+
+ --- [label = "initial phase - subscribe for signal/status events, assume app_id already started" ];
+
+ s >> a [label = "subscribe for applaunchd GetStatusEvents"];
+
+ --- [label = "handling of application switching" ];
+
+ u => l [label = "tapShortCut(appid)" ];
+ l => a [label = "StartApplication(appid)"];
+ a => d [label = "start application's systemd unit"];
+ d => a [label = "return status from starting systemd unit"];
+ a => s [label = "StartResponse(status = TRUE)"];
+ a => s [label = "StatusResponse(app_id, 'started')"];
+ s => c [label = "activate_app(app_id)"];
+}
diff --git a/docs/05_Component_Documentation/Application_Framework/images/application_switching.png b/docs/05_Component_Documentation/Application_Framework/images/application_switching.png
new file mode 100644
index 0000000..0b5584a
--- /dev/null
+++ b/docs/05_Component_Documentation/Application_Framework/images/application_switching.png
Binary files differ
diff --git a/docs/05_Component_Documentation/Application_Framework/images/start_and_activation.msc b/docs/05_Component_Documentation/Application_Framework/images/start_and_activation.msc
new file mode 100755
index 0000000..d835f8b
--- /dev/null
+++ b/docs/05_Component_Documentation/Application_Framework/images/start_and_activation.msc
@@ -0,0 +1,30 @@
+#!/usr/bin/mscgen -Tpng
+
+msc {
+ hscale="1.5";
+
+ u [label = "touch/pointer event" ],
+ s [label = "runtime/shell-client"],
+ a [label = "applaunchd" ],
+ g [label = "gRPC-proxy" ],
+ c [label = "compositor" ],
+ d [label = "libsystemd"];
+
+ |||;
+
+ --- [label = "initial phase - subscribe for signal/status events" ];
+
+ s >> g [label = "subscribe for AGL compositor AppStatusState"];
+ g >> c [label = "listen for app_state Wayland events"];
+
+ --- [label = "handling start-up & activation" ];
+
+ u => s [label = "tapShortCut(appid)" ];
+ s => a [label = "StartApplication(appid)"];
+ a => d [label = "start application's systemd unit"];
+ d => a [label = "return status from starting systemd unit"];
+ a => s [label = "StartResponse(status = TRUE)"];
+ c => g [label = "app_state(app_state = APP_STARTED)"];
+ g => s [label = "AppStatusResponse(app_id, APP_STARTED)"];
+ s => c [label = "activate_app(app_id)"];
+}
diff --git a/docs/05_Component_Documentation/Application_Framework/images/start_and_activation.png b/docs/05_Component_Documentation/Application_Framework/images/start_and_activation.png
new file mode 100644
index 0000000..593fc0e
--- /dev/null
+++ b/docs/05_Component_Documentation/Application_Framework/images/start_and_activation.png
Binary files differ