aboutsummaryrefslogtreecommitdiffstats
path: root/docs/04_Developer_Guides
diff options
context:
space:
mode:
authorMarius Vlad <marius.vlad@collabora.com>2023-02-22 18:29:42 +0200
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>2023-03-27 11:58:23 +0000
commitb37b7187f003f409bd20cfcceb3eb0279911016d (patch)
treee51cc9c4b8f06ad37a587a01a8bd5bf922eb1716 /docs/04_Developer_Guides
parent4cc7f73109602bfe4fe05397a73afa585d3cc92d (diff)
01_Application_Framework: Add an extended version of app startup
And activation, that describes in more detail how that is handled. Bug-AGL: SPEC-4700 Signed-off-by: Marius Vlad <marius.vlad@collabora.com> Change-Id: I5f9a2764d66947c06bf8dc346dfaef72d993733f Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/documentation/+/28526 Reviewed-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org> Tested-by: Jan-Simon Moeller <jsmoeller@linuxfoundation.org>
Diffstat (limited to 'docs/04_Developer_Guides')
-rw-r--r--docs/04_Developer_Guides/01_Application_Framework/02_Application_Startup.md108
-rwxr-xr-xdocs/04_Developer_Guides/images/application_switching.msc29
-rw-r--r--docs/04_Developer_Guides/images/application_switching.pngbin0 -> 31633 bytes
-rwxr-xr-xdocs/04_Developer_Guides/images/start_and_activation.msc30
-rw-r--r--docs/04_Developer_Guides/images/start_and_activation.pngbin0 -> 36479 bytes
5 files changed, 165 insertions, 2 deletions
diff --git a/docs/04_Developer_Guides/01_Application_Framework/02_Application_Startup.md b/docs/04_Developer_Guides/01_Application_Framework/02_Application_Startup.md
index 6eeae02..56876a4 100644
--- a/docs/04_Developer_Guides/01_Application_Framework/02_Application_Startup.md
+++ b/docs/04_Developer_Guides/01_Application_Framework/02_Application_Startup.md
@@ -138,7 +138,111 @@ 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
+ 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
+ the corresponding `id` string, or alternatively the string `status` is
+ set to "terminated" to denote that the application has been terminated,
+ forcibly or not
+
+## A deeper look at 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](../../06_Component_Documentation/02_agl_compositor/) 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 & 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](../../06_Component_Documentation/02_agl_compositor/)
+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/04_Developer_Guides/images/application_switching.msc b/docs/04_Developer_Guides/images/application_switching.msc
new file mode 100755
index 0000000..ceeab7c
--- /dev/null
+++ b/docs/04_Developer_Guides/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/04_Developer_Guides/images/application_switching.png b/docs/04_Developer_Guides/images/application_switching.png
new file mode 100644
index 0000000..0b5584a
--- /dev/null
+++ b/docs/04_Developer_Guides/images/application_switching.png
Binary files differ
diff --git a/docs/04_Developer_Guides/images/start_and_activation.msc b/docs/04_Developer_Guides/images/start_and_activation.msc
new file mode 100755
index 0000000..d835f8b
--- /dev/null
+++ b/docs/04_Developer_Guides/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/04_Developer_Guides/images/start_and_activation.png b/docs/04_Developer_Guides/images/start_and_activation.png
new file mode 100644
index 0000000..593fc0e
--- /dev/null
+++ b/docs/04_Developer_Guides/images/start_and_activation.png
Binary files differ