Update application framework documentation 84/29284/3
authorScott Murray <scott.murray@konsulko.com>
Tue, 17 Oct 2023 20:48:46 +0000 (16:48 -0400)
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>
Mon, 23 Oct 2023 16:15:43 +0000 (16:15 +0000)
Changes:
- Moved "Creating a New Service" page back over to "Developer Guides"
  since it is not application framework specific.
- Removed obsolete applaunchd D-Bus configuration documentation now
  that the functionality has been completely removed as of Pike.
- Updated the application framework introduction discussion around
  protocols to document preference for gRPC over D-Bus for AGL
  projects.
- Updated "Creating a New Application" documentation to document the
  requirements for having applications usable with applaunchd, as
  well as using the application templates, with BitBake recipe
  examples.
- Added "Application Sandboxing" section that documents the existing
  example configurations and discusses other potential configuration
  options for systemd.

Bug-AGL: SPEC-4928

Signed-off-by: Scott Murray <scott.murray@konsulko.com>
Change-Id: I6e0c0afcf571d9214df5300d2082b15fa3bb2a27
Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/documentation/+/29284
Reviewed-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org>
Tested-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org>
docs/04_Developer_Guides/03_Creating_a_New_Service.md [moved from docs/06_Component_Documentation/Application_Framework/03_Creating_a_New_Service.md with 91% similarity]
docs/06_Component_Documentation/01_AGL_components.md
docs/06_Component_Documentation/Application_Framework/01_Introduction.md
docs/06_Component_Documentation/Application_Framework/02_Application_Startup.md
docs/06_Component_Documentation/Application_Framework/02_Application_Startup_Dbus.md [deleted file]
docs/06_Component_Documentation/Application_Framework/03_Creating_a_New_Application.md [new file with mode: 0644]
docs/06_Component_Documentation/Application_Framework/04_Application_Sandboxing.md [new file with mode: 0644]
docs/06_Component_Documentation/Application_Framework/04_Creating_a_New_Application_Dbus.md [deleted file]

@@ -22,8 +22,8 @@ location, determined by the service type (system or user):
 
 - `/usr/lib/systemd/user/` for user services
 
 
 - `/usr/lib/systemd/user/` for user services
 
-Below is an example of a simple user service, running in a graphical session and
-therefore requiring a compositor to be already running before the service starts:
+Below is an example of a simple system service that requires the compositor to be
+already running before the service starts:
 
 ```
 [Unit]
 
 ```
 [Unit]
@@ -34,15 +34,8 @@ After=agl-compositor.service
 Type=simple
 ExecStart=/usr/bin/homescreen
 Restart=on-failure
 Type=simple
 ExecStart=/usr/bin/homescreen
 Restart=on-failure
-
-[Install]
-WantedBy=agl-session.target
 ```
 
 ```
 
-The `WantedBy=agl-session.target` indicates the service is part of the default AGL
-user session, as mentioned in the [Application Framework](01_Introduction.md#user-session-management)
-documentation.
-
 The `Restart=on-failure` directive ensures the service will be automatically
 restarted by `systemd` in case it crashes.
 
 The `Restart=on-failure` directive ensures the service will be automatically
 restarted by `systemd` in case it crashes.
 
index b36580d..754c0ed 100644 (file)
@@ -22,6 +22,6 @@ title: AGL Components
 - [Rule based arbitrator](04_Rule_Based_Arbitrator.md)
 
 
 - [Rule based arbitrator](04_Rule_Based_Arbitrator.md)
 
 
-### Lifecycle management
+### Application Lifecycle and Services
 
 - [Application Framework](Application_Framework/01_Introduction.md)
 
 - [Application Framework](Application_Framework/01_Introduction.md)
index 1deaec4..41759da 100644 (file)
@@ -4,75 +4,79 @@ title: Introduction
 
 # Foreword
 
 
 # Foreword
 
-The AGL Application Framework is nothing new. However, the implementation used
-up until the `lamprey` release has been retired starting with the `marlin`
-release and replaced by a redesigned Application Framework one. However, this
-new implementation isn't a 1:1 replacement, and as such it doesn't provide all
-of the features of the previous Application Framework. Some of those will be
-added back over time, others have been discarded in favor of more modern and/or
-widely-used alternatives.
-
-With the `needlefish` release, further changes have been added, including a
-[gRPC IPC](https://grpc.io/about), alongside a deprecated D-Bus one, as well as
-using as using systemd units as opposed on using
-[Desktop Entry specification](https://www.freedesktop.org/wiki/Specifications/desktop-entry-spec/)
-to list applications, and relies entirely on systemd to start application,
-rather than spawning them directly.
-
-Once all platforms transitioned to gRPC, the D-Bus functionality will be
-removed entirely, mentioning it in only in documentation for history purposes.
+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
+  `pike` 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
 
 
 # Introduction
 
-As a provider of an integrated solution to build up on, AGL needs 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.
+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
 
 This is achieved by providing a common set of rules and components, known as
-the Application Framework. By ensuring conformity to those rules, application
-developers can have a good understanding of the requirements for creating and
-packaging applications targeting AGL-based systems. Likewise, system developers
-and integrators have a clear path for including such applications in AGL-based
-products.
+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:
 
 
-The Application Framework's scope extends to the following areas:
 - system services integration and lifecycle management
 - system services integration and lifecycle management
-- user session management, including user-level applications and services
-  lifecycle management
+- user-level application lifecycle management
 - inter-process communication
 
 In order to be as simple as possible and avoid any unneeded custom
 - 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, most of those being maintained under
-the [freedesktop.org](https://www.freedesktop.org) umbrella. Those include:
-
+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
 
 
 - [systemd](https://www.freedesktop.org/wiki/Software/systemd/): system
   services and user session services management
 
-
-- [D-Bus](https://www.freedesktop.org/wiki/Software/dbus/): inter-process
-  communication, with `needlefish' release deprecated phase.
-
 - [gRPC](https://grpc.io/about): inter-process communication, new recommmended
   system-wide IPC, which should be used instead of D-Bus.
 
 - [gRPC](https://grpc.io/about): inter-process communication, new recommmended
   system-wide IPC, which should be used instead of D-Bus.
 
-
-- [Desktop Entry specification](https://www.freedesktop.org/wiki/Specifications/desktop-entry-spec/):
-  application enumeration and startup, now in deprecated phase, systemd being
-  the one would list out applications and handling start-up.
+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)
 
 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 2 such components:
+layer under `meta-app-framework`. At the moment, the application framework
+contains two such components:
 
 - `agl-session`: `systemd` unit files for user sessions management
 
 - `agl-session`: `systemd` unit files for user sessions management
-
 - `applaunchd`: application launcher service
 
 - `applaunchd`: application launcher service
 
-# Services management
+# 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:
 
 Both system and user services are managed by `systemd`, which provides a number
 of important features, such as dependency management or service monitoring:
@@ -86,62 +90,38 @@ downtime.
 and other security-related options.
 
 It is also well integrated with D-Bus and can be used for a more fine-grained
 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 startup
-to `systemd`, developers can take advantage of some of its advanced features,
-allowing for improved reliability and security.
+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
 
 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](03_Creating_a_New_Service.md) document.
+Service](../../04_Developer_Guides/03_Creating_a_New_Service.md) document.
 
 
-# User session management
+# User Session Management
 
 Similarly, user sessions and the services they rely on are also managed by
 
 Similarly, user sessions and the services they rely on are also managed by
-`systemd`.
-
-AGL provides 2 `systemd` units:
-
-
-1\. `agl-session@.service` is a template system service for managing user
-sessions; it takes a username or UID as a parameter, creating a session for the
-desired user.  Instanciating this service can be achieved by enabling
-`agl-session@USER.service`, for example by executing the following command on a
-running system:
+`systemd`.  Prior to the `pike` 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:
 
 
-```
-$ systemctl enable agl-session@USER.service
-```
+- 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.
 
 
-By default, AGL enables this service as `agl-session@agl-driver.service`,
-running as user `agl-driver`.
+# Inter-process Communication
 
 
-*Note: while you can create sessions for as many users as needed, only one
-instance of `agl-session@.service` is allowed per user.*
-
-
-2\. `agl-session.target` is a user target for managing user services and their
-dependencies. It is started by `agl-session@.service`.
-
-By default, `agl-compositor` is part of this target. It is therefore
-automatically started for user `agl-driver`.
-
-Any other service needed as part of the user session should similarly depend on
-this target by appending the following lines to their unit file:
-
-```
-[Install]
-WantedBy=agl-session.target
-```
-
-# Inter-process communication
-
-In order to provide a "standard", language-independent IPC mechanism and avoid
+In order to provide a language-independent, "standard", IPC mechanism and avoid
 the need for maintaining custom bindings for each programming language to be
 the need for maintaining custom bindings for each programming language to be
-used on top of AGL, the Application Framework used to promote the use of
+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,
 [D-Bus](https://www.freedesktop.org/wiki/Software/dbus/) as the preferred way
 for applications to interact with services. Starting with `needlefish` release,
-we instead switched to using [gRPC](https://grpc.io) for our system-wide IPC,
-with D-Bus being kept to provide functionality to services and application
+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,
 which haven't transitioned yet to using gRPC.
 
 Most services already included in AGL provide one or several D-Bus interfaces,
@@ -160,27 +140,25 @@ others:
 - [GeoClue](https://gitlab.freedesktop.org/geoclue/geoclue/-/wikis/home):
   geolocation
 
 - [GeoClue](https://gitlab.freedesktop.org/geoclue/geoclue/-/wikis/home):
   geolocation
 
-Similarly, we're in the phase of expanding various services to expose a
+Similarly, ongoing work involves expanding various services to expose a
 gRPC interface.
 
 gRPC interface.
 
-# Application launcher service
+# 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/)
 
 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 startup, but with the `needlefish` release
+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
 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 startup. It can therefore be considered always available.
+started on session start-up. It can therefore be considered always available.
 
 `applaunchd` enumerates applications installed on the system and provides a
 
 `applaunchd` enumerates applications installed on the system and provides a
-D-bus (deprecated)/gRPC interface for services and applications to:
+gRPC interface for services and applications to:
+
 - query the list of available applications
 - query the list of available applications
-- request the startup and/or activation of a specific application
+- request the start-up of a specific application
 - be notified when applications are started or terminated
 - be notified when applications are started or terminated
-
-`applaunchd` with the D-Bus interface is described with more details in
-[the following document](02_Application_Startup_Dbus.md).
index 3cd7ca0..8594426 100644 (file)
@@ -1,5 +1,5 @@
 ---
 ---
-title: Application Startup
+title: Application Launcher
 ---
 
 # Introduction
 ---
 
 # Introduction
@@ -14,11 +14,11 @@ 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.
 
 In order to provide a language-independent interface for applications and
 service to use, AGL includes `applaunchd`, a system service.
 
-# Application launcher 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
 
 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 startup and
+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
 termination of applications it manages.
 
 To that effect, `applaunchd` provides a gRPC interface which other applications
@@ -28,20 +28,20 @@ can use in order to execute those actions.
 it isn't aware of applications started by other means (`systemd`, direct
 executable call...), and therefore can't send notifications for those.*
 
 it isn't aware of applications started by other means (`systemd`, direct
 executable call...), and therefore can't send notifications for those.*
 
-## Application discovery
+## 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.
 
 
 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
+## 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.
 
 
 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
+## gRPC Interface
 
 The interface provides methods for the following actions:
 
 
 The interface provides methods for the following actions:
 
@@ -58,7 +58,7 @@ 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.
 
 It is a good standard practice to follow up with these recommendation when
 developing a new protobuf specification.
 
-### Applications list
+### Application Enumeration
 
 The `ListApplications` method allows clients to retrieve the list of available
 applications. 
 
 The `ListApplications` method allows clients to retrieve the list of available
 applications. 
@@ -77,7 +77,7 @@ message ListResponse {
 }
 ```
 
 }
 ```
 
-### Application startup request
+### Application Start-up
 
 Applications can be started by using the `StartApplication` method, passing the
 `StartRequest` message, defined as:
 
 Applications can be started by using the `StartApplication` method, passing the
 `StartRequest` message, defined as:
@@ -106,7 +106,7 @@ 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".
 
 instance, but instead reply with a `AppStatus` message setting the `status`
 string to "started".
 
-### Status notifications
+### Status Notifications
 
 The gRPC interface provides clients with a subscription model to receive
 status events. Client should subscribe to `GetStatusEvents` method to receive
 
 The gRPC interface provides clients with a subscription model to receive
 status events. Client should subscribe to `GetStatusEvents` method to receive
@@ -146,7 +146,7 @@ This can be useful, for example, when switching between graphical applications:
   set to "terminated" to denote that the application has been terminated,
   forcibly or not
 
   set to "terminated" to denote that the application has been terminated,
   forcibly or not
 
-## A deeper look at start-up, activation and application switching
+## 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
 
 Application start-up, activation and application switching are sometimes
 conflated into a single operation but underneath some of these are distinct
@@ -177,7 +177,7 @@ by the desktop run-time/shell client.
 as this synchronization part between `applaunchd` has not been implemented. The
 plan is to migrate all of remaining run-times to using this approach.*
 
 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 & activation
+### 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
 
 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
@@ -231,7 +231,7 @@ application start-up:
 
 ![Application_start](images/start_and_activation.png)
 
 
 ![Application_start](images/start_and_activation.png)
 
-### Application switching
+### 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
 
 With the compositor providing application status events, it might seem that the
 `applaunchd`'s, `GetStatusEvents` might be redundant, but in fact it is being
diff --git a/docs/06_Component_Documentation/Application_Framework/02_Application_Startup_Dbus.md b/docs/06_Component_Documentation/Application_Framework/02_Application_Startup_Dbus.md
deleted file mode 100644 (file)
index f951e0e..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
----
-title: Application Startup with D-Bus
----
-
-*Note: The that the D-Bus interface is in deprecation phase and for the time
-being only available for application & services that still rely on them. Once
-we migrate everything to gRPC, we will remove D-Bus IPC support. Please see 
-[Application Startup with gRPC](02_Application_Startup.md) for the latest
-information*
-
-# 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. The
-[Desktop Entry specification](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html)
-defines how applications can be discovered by using `.desktop` files, but there's no
-simple reference implementation for this function.
-
-In order to provide a language-independent interface for applications and service to
-use, AGL includes `applaunchd`, a user service part of the default session.
-
-*Note: as mentioned [previously](01_Introduction.md), services are managed using `systemd`
-and are therefore not in the scope of this document.*
-
-# 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 startup and termination of applications it
-manages.
-
-To that effect, `applaunchd` provides a D-Bus interface 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
-
-On startup, `applaunchd` inspects all `.desktop` files present under the `applications/`
-subfolder of any element of the `XDG_DATA_DIRS` environment variable, ignoring all entries
-containing either the `NoDisplay=true` or `Hidden=true` lines.
-
-It then looks for the following keys:
-- `Terminal`
-- `DBusActivatable`
-
-If the desktop entry file contains the `Terminal` key set to `true`, then the application
-is marked as a non-graphical one. As such, it won't be included in the applications list
-if the client requests only graphical applications.
-
-If `DBusActivatable` is set to `true`, then the application is marked as D-Bus activated.
-Additionally, `applaunchd` will search for a corresponding D-Bus service file in case this
-line is missing. This is a workaround allowing D-Bus activated applications providing
-an incomplete desktop entry file (i.e missing the `DBusActivatable` key) to be
-identified as such.
-
-### Requirements for D-Bus activation
-
-`applaunchd` will always start D-Bus activatable applications using D-Bus activation
-instead of executing the command line stated in the desktop entry file.
-
-This is handled by calling the `Activate` method of the
-[org.freedesktop.Application](https://specifications.freedesktop.org/desktop-entry-spec/1.1/ar01s07.html)
-interface with an empty argument.
-
-As a consequence, all D-Bus activatable applications **must** implement this D-Bus
-interface.
-
-## 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 and ease D-Bus integration.
-
-The application ID is set in the desktop entry file itself for
-[graphical applications](04_Creating_a_New_Application_Dbus.md#graphical-applications):
-it is the value of the `StartupWMClass` field, which must be identical to the `app-id`
-advertised through the Wayland XDG toplevel protocol. In case this field is missing
-(as is usually the case for non-graphical application), the application ID will be the
-desktop entry file name, stripped from its `.desktop` extension.
-
-## D-Bus interface
-
-The `applaunchd` D-Bus interface is named `org.automotivelinux.AppLaunch`. The object
-path for `applaunchd` is `/org/automotivelinux/AppLaunch`. The interface provides methods
-for the following actions:
-- retrieve the list of available applications; the client can choose to retrieve all
-  available applications, or only those suitable for a graphical environment
-- request an application to be started
-
-Moreover, signals are available for clients to be notified when an application has
-successfully started or its execution terminated.
-
-### Applications list
-
-The `listApplications` method allows clients to retrieve the list of available applications.
-It takes one boolean argument named `graphical`:
-- if set to `true`, only applications suitable for graphical environments are returned
-- otherwise, the list contains all applications
-
-This method returns an array of variants (type `av`), each element being a structure made up
-of 3 strings (type `(sss)`):
-- the application ID
-- the application's displayed name
-- the full path to the application icon file (or an empty string if no icon was specified in
-  the application's desktop entry file)
-
-### Application startup request
-
-Applications can be started by using the `start` method, passing the corresponding application
-ID as the only argument. This method doesn't return any data.
-
-If the application is already running, `applaunchd` won't start another instance, but instead
-emit a `started` signal to notify clients the application is ready.
-
-### Status notifications
-
-The `org.automotivelinux.AppLaunch` interface provides 2 signals clients can connect to:
-- `started` indicates an application has started
-    - for D-Bus activated applications, it is emitted upon successful completion of the
-      call to the `Activate` method of the `org.freedesktop.Application` interface
-    - for other applications, this signal is emitted as soon as the child process has been
-      successfully created
-- `terminated` is emitted when an application quits
-
-Both signals have an additional argument named `appid`, containing the ID of the application
-affected by the event.
-
-As mentioned above, the `started` signal 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 `start` request to `applaunchd` every time the user requests to switch to another
-  application
-- the desktop environment then receives the `started` signal, indicating it should activate the
-  window with the corresponding `app-id`
-
-## Testing
-
-`applaunchd` can be manually tested using the `gdbus` command-line tool:
-
-1. Query the application list (graphical applications only):
-
-```
-$ gdbus call --session --dest "org.automotivelinux.AppLaunch" \
-                       --object-path "/org/automotivelinux/AppLaunch" \
-                       --method "org.automotivelinux.AppLaunch.listApplications" \
-                       true
-```
-
-This command will output something similar to what follows:
-
-```
-([<('navigation', 'Navigation', '/usr/share/icons/hicolor/scalable/navigation.svg')>,
- <('settings', 'Settings', '/usr/share/icons/hicolor/scalable/settings.svg')>,
- <('dashboard', 'Dashboard', '/usr/share/icons/hicolor/scalable/dashboard.svg')>,
- <('hvac', 'HVAC', '/usr/share/icons/hicolor/scalable/hvac.svg')>,
- <('org.freedesktop.weston.wayland-terminal', 'Weston Terminal', '/usr/share/icons/Adwaita/scalable/apps/utilities-terminal-symbolic.svg')>],)
-```
-
-2. Request startup of the `org.freedesktop.weston.wayland-terminal` application:
-
-```
-$ gdbus call --session --dest "org.automotivelinux.AppLaunch" \
-                       --object-path "/org/automotivelinux/AppLaunch" \
-                       --method "org.automotivelinux.AppLaunch.start" \
-                       "org.freedesktop.weston.wayland-terminal"
-```
-
-3. Monitor signals emitted by `applaunchd`:
-
-```
-$ gdbus monitor --session --dest "org.automotivelinux.AppLaunch"
-```
-
-This results in the following output when starting, then exiting, the
-`org.freedesktop.weston.wayland-terminal` application:
-
-```
-Monitoring signals from all objects owned by org.automotivelinux.AppLaunch
-The name org.automotivelinux.AppLaunch is owned by :1.4
-/org/automotivelinux/AppLaunch: org.automotivelinux.AppLaunch.started ('org.freedesktop.weston.wayland-terminal',)
-/org/automotivelinux/AppLaunch: org.automotivelinux.AppLaunch.terminated ('org.freedesktop.weston.wayland-terminal',)
-```
diff --git a/docs/06_Component_Documentation/Application_Framework/03_Creating_a_New_Application.md b/docs/06_Component_Documentation/Application_Framework/03_Creating_a_New_Application.md
new file mode 100644 (file)
index 0000000..aa528b1
--- /dev/null
@@ -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/06_Component_Documentation/Application_Framework/04_Application_Sandboxing.md b/docs/06_Component_Documentation/Application_Framework/04_Application_Sandboxing.md
new file mode 100644 (file)
index 0000000..356c0eb
--- /dev/null
@@ -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/06_Component_Documentation/Application_Framework/04_Creating_a_New_Application_Dbus.md b/docs/06_Component_Documentation/Application_Framework/04_Creating_a_New_Application_Dbus.md
deleted file mode 100644 (file)
index 2ee6bdf..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
----
-title: Creating a New Application with D-bus activation
----
-
-*Note: The that the D-Bus interface is in deprecation phase and for the time
-being only available for application & services that still rely on them. Once
-we migrate everything to gRPC, we will remove D-Bus IPC support.*
-
-Applications are:
-
--  Software designed to perform a specific task during a limited amount of time.
--  Graphical interface allowing user to interact with.
-
-Applications are executed by `applaunchd`, the AGL
-[application launcher service](02_Application_Startup_Dbus.md).
-
-# Basic requirements
-
-In order to be enumerated by `applaunchd`, applications must provide the a `.desktop` file, as
-defined by the [Desktop Entry specification](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html).
-
-The desktop entry file should be installed to `/usr/share/applications` (or the `applications`
-sub-directory of any entry present in the `XDG_DATA_DIRS` environment variable) and have a
-meaningful name. It is considered good practice to use reverse-DNS notation for the desktop
-entry file name, following the recommendations of the [D-Bus specification](https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names):
-- this avoids potential name collisions with other desktop entry files
-- it makes it easier to enable [D-Bus activation](#d-bus-activation) during the application
-  development cycle if needed
-- for [graphical applications](#graphical-applications), it ensures the chosen Wayland `app-id`
-  will be unique
-
-Such a file must contain at least the following keys:
-- `Type`: desktop entry type, must be set to `Application`
-- `Name`: application name, as it should be displayed in menus and application launchers
-- `Exec`: full path to the main executable
-
-Below is an example of a minimal desktop entry file:
-
-```
-[Desktop Entry]
-Type=Application
-Name=Example Application
-Exec=/usr/bin/example-app
-```
-
-Graphical applications must also provide an `Icon` entry pointing to the application icon.
-The value for this entry must either be the full path to the icon's file or, for icons part
-of an existing [icon theme](https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html),
-the name of an element of this theme.
-
-In addition, a number of optional fields can be used to change how `applaunchd` will consider the
-application:
-- `Version`: version of the Desktop Entry Specification the file conforms to, must be `1.5`
-- `Hidden`: boolean value, if `true` the application is always ignored by `applaunchd` and
-  won't be listed nor executed
-- `Terminal`: boolean value, if `true` the application is excluded when requesting the list of
-  graphical applications from `applaunchd`
-- `DBusActivatable`: boolean value, must be `true` for [D-Bus activated applications](#d-bus-activation)
-- `Implements`: list of D-Bus interfaces the application implements, only used for D-Bus activated
-  applications.
-
-Finally, graphical applications may also define the `StartupWMClass` key in some cases. Please
-refer to the [graphical applications](#graphical-applications) section for more information.
-
-# D-Bus activation
-
-Similarly to [services](03_Creating_a_New_Service.md#d-bus-activation), applications can
-also be activated through D-Bus.
-
-Such applications must name their `.desktop` file after the D-Bus name they register. In addition,
-this file must contain the following entries:
-
-```
-DBusActivatable=true
-Implements=IFACE1;IFACE2;...
-```
-
-Where `IFACEn` are the names of the D-Bus interfaces the application implements.
-
-In addition, they must provide a D-Bus service file named `NAME.service` and installed
-to `/usr/share/dbus-1/services`.
-
-The contents of the D-Bus service file must be the following:
-
-```
-[D-BUS Service]
-Name=NAME
-Exec=/path/to/executable
-```
-
-For example, an application registering the `org.automotivelinux.Example` D-Bus name
-and implementing the `org.automotivelinux.Example.Search1` and `org.automotivelinux.Example.Execute1`
-interfaces would provide the following files:
-
-* Desktop entry (`/usr/share/applications/org.automotivelinux.Example.desktop`):
-
-```
-[Desktop Entry]
-Type=Application
-Version=1.5
-Name=Example Application
-Exec=/usr/bin/example-app
-Icon=example-icon
-Terminal=false
-DBusActivatable=true
-Implements=org.automotivelinux.Example.Search1;org.automotivelinux.Example.Execute1
-```
-
-* D-Bus service file (`/usr/share/dbus-1/services/org.automotivelinux.Example.service`):
-
-```
-[D-BUS Service]
-Name=org.automotivelinux.Example
-Exec=/usr/bin/example-app
-```
-
-*Note: in addition to their own D-Bus interface, D-Bus activated applications must also
-implement the `org.freedesktop.Application` interface as defined in the
-[Desktop Entry specification](https://specifications.freedesktop.org/desktop-entry-spec/1.1/ar01s07.html).*
-
-# Graphical applications
-
-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` must be specified in the desktop entry file by adding the following line:
-
-```
-StartupWMClass=APP_ID
-```
-
-3\. The desktop entry file must be named `APP_ID.desktop`.
-
-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.*