app: Listen for activation events
[apps/camera-gstreamer.git] / app / main.cpp
index 0247d3e..d3013b7 100644 (file)
 #include <unistd.h>
 #include <fcntl.h>
 #include <assert.h>
+#include <thread>
 
 #include "utils.h"
 #include "xdg-shell-client-protocol.h"
+#include "AglShellGrpcClient.h"
 
 #include <gst/gst.h>
 
@@ -41,6 +43,8 @@
 
 #define MAX_BUFFER_ALLOC       2
 
+const char* my_app_id = "camera-gstreamer";
+
 // C++ requires a cast and we in wayland we do the cast implictly
 #define WL_ARRAY_FOR_EACH(pos, array, type) \
        for (pos = (type)(array)->data; \
@@ -216,6 +220,7 @@ create_shm_buffer(struct display *display, struct buffer *buffer,
        buffer->height = height;
 
        fprintf(stdout, "Created shm buffer with width %d, height %d\n", width, height);
+
        return 0;
 }
 
@@ -571,6 +576,8 @@ create_window(struct display *display, int width, int height, const char *app_id
        window->display = display;
        window->width = width;
        window->height = height;
+       window->init_width = width;
+       window->init_height = height;
        window->surface = wl_compositor_create_surface(display->wl_compositor);
 
        if (display->wm_base) {
@@ -725,13 +732,12 @@ GstElement* create_pipeline(int* argc, char** argv[])
                snprintf(pipeline_str, sizeof(pipeline_str), "v4l2src device=%s ! video/x-raw,width=%d,height=%d ! waylandsink",
                        camera_device, width, height);
        else if (gst_pipeline_failed == TRUE) {
-               snprintf(pipeline_str, sizeof(pipeline_str), "filesrc location=%s/still-image.jpg ! decodebin ! videoconvert ! imagefreeze ! waylandsink fullscreen=true",
-                       xstr(APP_DATA_PATH), width, height);
+               snprintf(pipeline_str, sizeof(pipeline_str), "filesrc location=%s/still-image.jpg ! decodebin ! videoconvert ! imagefreeze ! waylandsink",
+                       xstr(APP_DATA_PATH));
                fallback_gst_pipeline_tried = TRUE;
        }
        else {
-               snprintf(pipeline_str, sizeof(pipeline_str), "pipewiresrc ! video/x-raw,width=%d,height=%d ! waylandsink", width,
-                       height);
+               snprintf(pipeline_str, sizeof(pipeline_str), "pipewiresrc ! waylandsink");
        }
 
        fprintf(stdout, "Using pipeline: %s\n", pipeline_str);
@@ -747,6 +753,30 @@ GstElement* create_pipeline(int* argc, char** argv[])
        return pipeline;
 }
 
+static void
+run_in_thread(GrpcClient *client)
+{
+        grpc::Status status = client->Wait();
+}
+
+static void
+app_status_callback(::agl_shell_ipc::AppStateResponse app_response, void *data)
+{
+       (void) data;
+
+       std::cout << " >> AppStateResponse app_id " <<
+               app_response.app_id() << ", with state " <<
+               app_response.state() << std::endl;
+
+       // there's no implicit deactivation for an activation of another app so
+       // assume that another application got activate we are also deactived
+       if (app_response.state() == 2 && app_response.app_id() != my_app_id) {
+               // suspend pipeline
+               std::cout << "Suspending gstreamer pipeline" << std::endl;
+       }
+}
+
+
 int main(int argc, char* argv[])
 {
        int ret = 0;
@@ -754,7 +784,20 @@ int main(int argc, char* argv[])
        struct receiver_data receiver_data = {};
        struct display* display;
        struct window* window;
-       const char* app_id = "camera-gstreamer";
+
+       // always start the grpc client
+       GrpcClient *client = new GrpcClient();
+
+       // subscribe to events to be able to suspend/pause the video
+       // feed
+       std::thread th = std::thread(run_in_thread, client);
+       client->AppStatusState(app_status_callback, &receiver_data);
+
+       // for starting the application from the beginning, with a diffrent
+       // role we need to handle that creating the main window
+       if (argc >= 2 && strcmp(argv[1], "float") == 0) {
+               client->SetAppFloat(std::string(my_app_id), 30, 400);
+       }
 
        sa.sa_sigaction = signal_int;
        sigemptyset(&sa.sa_mask);
@@ -783,7 +826,7 @@ int main(int argc, char* argv[])
        // we use the role to set a correspondence between the top level
        // surface and our application, with the previous call letting the
        // compositor know that we're one and the same
-       window = create_window(display, WINDOW_WIDTH_SIZE, WINDOW_HEIGHT_SIZE, app_id);
+       window = create_window(display, WINDOW_WIDTH_SIZE, WINDOW_HEIGHT_SIZE, my_app_id);
 
        if (!window) {
                free(gargv);