protocol/agl-shell.xml: Add an app_state event -- app state notification 67/27967/2
authorMarius Vlad <marius.vlad@collabora.com>
Thu, 1 Sep 2022 12:19:59 +0000 (15:19 +0300)
committerMarius Vlad <marius.vlad@collabora.com>
Wed, 14 Sep 2022 16:42:31 +0000 (19:42 +0300)
This protocol bump will notify the client binding to the agl-shell protocol
when a particular application changed its state.

This includes four (4) different events:

- started
- terminated
- activated
- deactivated

This should allow orchestrating start-up with activation as we don't
really know when it would be the proper time to activate an application
when starting up (for the first time). A started event will notify the
shell client we it can do that. These events are not sticky such that
the shell would be responsabile for keep  track of the state, if it
wants to.

Bug-AGL: SPEC-4528
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Change-Id: Id162874fa68946bb9b1db9fa356dd617a0db9eb7

protocol/agl-shell.xml
src/desktop.c
src/layout.c
src/shell.c

index 4ab71af..ad5553d 100644 (file)
@@ -22,7 +22,7 @@
     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     DEALINGS IN THE SOFTWARE.
   </copyright>
-  <interface name="agl_shell" version="2">
+  <interface name="agl_shell" version="3">
     <description summary="user interface for Automotive Grade Linux platform">
       Starting with version 2 of the protocol, the client is required to wait
       for the 'bound_ok' or 'bound_fail' events in order to proceed further.
       <entry name="right" value="3"/>
     </enum>
 
+    <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>
+
     <request name="ready">
       <description summary="client is ready to be shown">
         Tell the server that this client is ready to be shown. The server
       </description>
     </request>
 
+    <event name="app_state" since="3">
+      <description summary="event sent when an application suffered state modification">
+        Informs the client that an application has changed its state to another,
+        specified by the app_state enum. Client can use this event to track
+        current application state. For instance to know when the application has
+        started, or when terminated/stopped.
+      </description>
+      <arg name="app_id" type="string"/>
+      <arg name="state" type="uint" enum="app_state"/>
+    </event>
+
+
   </interface>
 </protocol>
index 37f4222..f28d0c9 100644 (file)
@@ -366,10 +366,15 @@ skip_output_asignment:
        weston_log("Removed surface %p, app_id %s, role %s\n", surface,
                        app_id, ivi_layout_get_surface_role_name(surface));
 
-       if (app_id && output)
+       if (app_id && output) {
                shell_advertise_app_state(output->ivi, app_id,
                                          NULL, AGL_SHELL_DESKTOP_APP_STATE_DESTROYED);
 
+               if (wl_resource_get_version(output->ivi->shell_client.resource) >= AGL_SHELL_APP_STATE_SINCE_VERSION)
+                       agl_shell_send_app_state(output->ivi->shell_client.resource,
+                                                app_id, AGL_SHELL_APP_STATE_TERMINATED);
+       }
+
        wl_list_remove(&surface->link);
 
        free(surface);
@@ -396,6 +401,13 @@ desktop_committed(struct weston_desktop_surface *dsurface,
                wl_list_init(&surface->link);
                ivi_check_pending_desktop_surface(surface);
                surface->checked_pending = true;
+
+               /* we'll do it now at commit time, because we might not have an
+                * appid by the time we've created the weston_desktop_surface
+                * */
+               if (wl_resource_get_version(ivi->shell_client.resource) >= AGL_SHELL_APP_STATE_SINCE_VERSION)
+                       agl_shell_send_app_state(ivi->shell_client.resource,
+                                                app_id, AGL_SHELL_APP_STATE_STARTED);
        }
 
        if (!surface->advertised_on_launch &&
index 15858ff..25221e2 100644 (file)
@@ -194,6 +194,7 @@ ivi_layout_activate_complete(struct ivi_output *output,
        struct weston_view *view = surf->view;
        struct weston_seat *wseat = get_ivi_shell_weston_first_seat(ivi);
        struct ivi_shell_seat *ivi_seat = get_ivi_shell_seat(wseat);
+       const char *app_id = weston_desktop_surface_get_app_id(surf->dsurface);
 
        if (weston_view_is_mapped(view)) {
                weston_layer_entry_remove(&view->layer_link);
@@ -281,8 +282,13 @@ ivi_layout_activate_complete(struct ivi_output *output,
        }
 
        weston_log("Activation completed for app_id %s, role %s, output %s\n",
-                       weston_desktop_surface_get_app_id(surf->dsurface),
+                       app_id,
                        ivi_layout_get_surface_role_name(surf), output->name);
+
+      if (wl_resource_get_version(ivi->shell_client.resource) >= AGL_SHELL_APP_STATE_SINCE_VERSION)
+               agl_shell_send_app_state(ivi->shell_client.resource,
+                                        app_id, AGL_SHELL_APP_STATE_ACTIVATED);
+
 }
 
 struct ivi_output *
@@ -1031,4 +1037,8 @@ ivi_layout_deactivate(struct ivi_compositor *ivi, const char *app_id)
                weston_view_geometry_dirty(view);
                weston_surface_damage(view->surface);
        }
+
+      if (wl_resource_get_version(ivi->shell_client.resource) >= AGL_SHELL_APP_STATE_SINCE_VERSION)
+             agl_shell_send_app_state(ivi->shell_client.resource, app_id,
+                                      AGL_SHELL_APP_STATE_DEACTIVATED);
 }
index 4ab5e42..f7ec6a2 100644 (file)
@@ -1052,10 +1052,19 @@ shell_ready(struct wl_client *client, struct wl_resource *shell_res)
        }
 
        wl_list_for_each_safe(surface, tmp, &ivi->pending_surfaces, link) {
+               const char *app_id;
+
                wl_list_remove(&surface->link);
                wl_list_init(&surface->link);
                ivi_check_pending_desktop_surface(surface);
                surface->checked_pending = true;
+               app_id = weston_desktop_surface_get_app_id(surface->dsurface);
+
+               if (app_id &&
+                   wl_resource_get_version(ivi->shell_client.resource) >=
+                   AGL_SHELL_APP_STATE_SINCE_VERSION)
+                       agl_shell_send_app_state(ivi->shell_client.resource,
+                                                app_id, AGL_SHELL_APP_STATE_STARTED);
        }
 }
 
@@ -1532,7 +1541,7 @@ int
 ivi_shell_create_global(struct ivi_compositor *ivi)
 {
        ivi->agl_shell = wl_global_create(ivi->compositor->wl_display,
-                                         &agl_shell_interface, 2,
+                                         &agl_shell_interface, 3,
                                          ivi, bind_agl_shell);
        if (!ivi->agl_shell) {
                weston_log("Failed to create wayland global.\n");