2 title: Application Startup
7 At system runtime, it may be necessary for applications to start other
8 applications on demand. Such actions can be executed in reaction to a user
9 request, or they may be needed to perform a specific task.
11 In order to do so, running applications and services need an established way of
12 discovering installed applications and executing those.
14 In order to provide a language-independent interface for applications and
15 service to use, AGL includes `applaunchd`, a system service.
17 # Application launcher service
19 The purpose of `applaunchd` is to enumerate applications available on the
20 system and provide a way for other applications to query this list and start
21 those on demand. It is also able to notify clients of the startup and
22 termination of applications it manages.
24 To that effect, `applaunchd` provides a gRPC interface which other applications
25 can use in order to execute those actions.
27 *Note: `applaunchd` will only send notifications for applications it started;
28 it isn't aware of applications started by other means (`systemd`, direct
29 executable call...), and therefore can't send notifications for those.*
31 ## Application discovery
33 Applications are enumerated from systemd's list of available units based on the
34 pattern `agl-app*@*.service`, and are started and controled using their systemd
35 unit. Please note `applaunchd` allows only one instance of a given
38 ## Application identifiers
40 Each application is identified by a unique Application ID. Although this ID can
41 be any valid string, it is highly recommended to use the "reverse DNS"
42 convention in order to avoid potential name collisions.
46 The interface provides methods for the following actions:
48 - retrieve the list of available applications
49 - request an application to be started
50 - subscribe to status events
52 Moreover, with the gRPC the client subscribes to a status signal to be notified
53 when an application has successfully started or its execution terminated.
55 The gRPC protobuf file provides a Request and Response arguments to RPC methods
56 even though in some cases these might be empty in order to allow forward
57 compatibility in case additional fields are required.
58 It is a good standard practice to follow up with these recommendation when
59 developing a new protobuf specification.
63 The `ListApplications` method allows clients to retrieve the list of available
66 The `ListRequest` is an empty message, while `ListResponse` contains the following:
75 message ListResponse {
76 repeated AppInfo apps = 1;
80 ### Application startup request
82 Applications can be started by using the `StartApplication` method, passing the
83 `StartRequest` message, defined as:
86 message StartRequest {
91 In reply, the following `StartResponse` will be returned:
94 message StartResponse {
100 The "message" string of `StartResponse` message will contain an error message
101 in case we couldn't start the application for whatever reason, or if the "id"
102 isn't a known application ID. The "status" string would be boolean set to
103 boolean `TRUE` otherwise.
105 If the application is already running, `applaunchd` won't start another
106 instance, but instead reply with a `AppStatus` message setting the `status`
109 ### Status notifications
111 The gRPC interface provides clients with a subscription model to receive
112 status events. Client should subscribe to `GetStatusEvents` method to receive
115 The `StatusRequest` is empty, while the `StatusResponse` is defined as
124 message LauncherStatus {
127 message StatusResponse {
130 LauncherStatus launcher = 2;
135 As mentioned above, the `status` string is set to "started" and is also emitted
136 if `applaunchd` receives a request to start an already running application.
137 This can be useful, for example, when switching between graphical applications:
139 - the application switcher doesn't need to track the state of each application;
140 instead, it can simply send a `StartApplication` request to `applaunchd`
141 every time the user requests to switch to another application. Obviously, the
142 client needs to subscribe to get these events and act accordingly.
143 - the shell client then receives the `StatusResponse` with the message `status`
144 string set to "started" indicating it that it should activate the window with
145 the corresponding `id` string, or alternatively the string `status` is
146 set to "terminated" to denote that the application has been terminated,
149 ## A deeper look at start-up, activation and application switching
151 Application start-up, activation and application switching are sometimes
152 conflated into a single operation but underneath some of these are distinct
153 steps, and a bit flaky in some circumstances.
154 The [AGL compositor](../../06_Component_Documentation/02_agl_compositor/) has
155 some additional events which one can use when creating an application
156 start-up & switching scheme in different run-times.
158 Start-up of application is handled entirely by `applaunchd` service while
159 activation -- the window which I want to display, but which has never been
160 shown, and application switching -- bring forward an application already
161 shown/displayed in the past, are operations handled entirely by the
164 The issue stems from the fact that underneath `applaunchd` can't make any
165 guarantees when the application actually started, as it calls into libsystemd
166 API to start the specific application systemd unit.
168 If `StartApplication` can't start the systemd unit, it returns a false
169 `status` boolean value and a error message in `StartResponse` message, but if
170 the application is indeed started we doesn't really know the *moment* when the
171 application is ready to be displayed. Additionally, the AGL compositor
172 performed the activation on its own when it detected that a new application
173 has been started, but that implicit activation can now be handled outside
174 by the desktop run-time/shell client.
176 *Note: Some of the run-times still rely on the compositor to perform activation
177 as this synchronization part between `applaunchd` has not been implemented. The
178 plan is to migrate all of remaining run-times to using this approach.*
180 ### Start-up & activation
182 This means that we require some sort of interaction between `StartApplication`
183 method and the events sent by the AGL compositor in order to correctly handle
184 start-up & activation of application.
186 There are couple of ways of achieving that, either using Wayland native calls,
187 or using the gRPC proxy interface, which underneath is using the same Wayland
190 For the first approach, the AGL compositor has an `app_state` Wayland event
191 which contains the application ID, and an enum `app_state` that will propagate
192 the following application state events:
195 <enum name="app_state" since="3">
196 <entry name="started" value="0"/>
197 <entry name="terminated" value="1"/>
198 <entry name="activated" value="2"/>
199 <entry name="deactivated" value="3"/>
203 The `started` event can be used in correlation with the `StartApplication`
204 method from `applaunchd` such that upon received the `started` even, it can
205 explicitly activate that particular appid in order for the compositor to
206 display it. See [AGL compositor](../../06_Component_Documentation/02_agl_compositor/)
207 about how activation should be handled.
209 *Note: These can only be received if by the client shell which binds to the
210 agl_shell interface*.
212 Alternatively, when using the gRPC proxy one can register to receive these
213 status events similar to the `applaunchd` events, subscribing to
214 `AppStatusState` method from the grpc-proxy helper application, which has the
215 following protobuf messages:
218 message AppStateRequest {
220 message AppStateResponse {
226 The integer state maps to the `enum app_state` from the Wayland protocol, so
227 they are a 1:1 match.
229 Here's the state diagram for the Qt homescreen implementation of the
230 application start-up:
232 ![Application_start](../images/start_and_activation.png)
234 ### Application switching
236 With the compositor providing application status events, it might seem that the
237 `applaunchd`'s, `GetStatusEvents` might be redundant, but in fact it is being
238 used to perform application switching. The run-time/shell client would in fact
239 subscribe to `GetStatusEvents` and each application wanting to switch to another
240 application would basically call `StartApplication`. That would eventually reach
241 the run-time/shell-client and have a handler that would ultimately activate the
244 ![Application_switching](../images/application_switching.png)
246 *Note: In practice, the run-time/shell-client would subscribe to both `applaunchd`
247 and to the AGL compositor, either Wayland native events, or using the gPRC-proxy
248 helper client, although the diagrams show them partly decoupled*.