Change reply timing
[apps/agl-service-windowmanager.git] / src / main.cpp
index e8ae75a..2f813a3 100644 (file)
 #include "result.hpp"
 #include "json_helper.hpp"
 #include "util.hpp"
-#include "wayland.hpp"
+#include "wayland_ivi_wm.hpp"
 
 extern "C" {
 #include <afb/afb-binding.h>
 #include <systemd/sd-event.h>
 }
 
+typedef struct wmClientCtxt{
+    std::string name;
+    wmClientCtxt(const char* appName){
+        name = appName;
+    }
+} wmClientCtxt;
+
 struct afb_instance {
    std::unique_ptr<wl::display> display;
    wm::App app;
@@ -149,6 +156,30 @@ int binding_init() noexcept {
    return -1;
 }
 
+static bool checkFirstReq(afb_req req){
+    wmClientCtxt* ctxt = (wmClientCtxt*)afb_req_context_get(req);
+    return (ctxt) ? false : true;
+}
+
+static void cbRemoveClientCtxt(void* data){
+    wmClientCtxt* ctxt = (wmClientCtxt*)data;
+    if(ctxt == nullptr){
+        return;
+    }
+    HMI_DEBUG("wm","remove app %s", ctxt->name.c_str());
+    // Lookup surfaceID and remove it because App is dead.
+    auto pSid = g_afb_instance->app.id_alloc.lookup(ctxt->name.c_str());
+    if(pSid){
+        auto sid = *pSid;
+        g_afb_instance->app.id_alloc.remove_id(sid);
+        g_afb_instance->app.layers.remove_surface(sid);
+        g_afb_instance->app.controller->sprops.erase(sid);
+        g_afb_instance->app.controller->surfaces.erase(sid);
+        HMI_DEBUG("wm", "delete surfaceID %d", sid);
+    }
+    delete ctxt;
+}
+
 void windowmanager_requestsurface(afb_req req) noexcept {
    std::lock_guard<std::mutex> guard(binding_m);
    #ifdef ST
@@ -166,7 +197,30 @@ void windowmanager_requestsurface(afb_req req) noexcept {
        return;
    }
 
+   /* Create Security Context */
+   bool isFirstReq = checkFirstReq(req);
+   if(!isFirstReq){
+       wmClientCtxt* ctxt = (wmClientCtxt*)afb_req_context_get(req);
+       HMI_DEBUG("wm", "You're %s.", ctxt->name.c_str());
+       if(ctxt->name != std::string(a_drawing_name)){
+           afb_req_fail_f(req, "failed", "Dont request with other name: %s for now", a_drawing_name);
+           HMI_DEBUG("wm", "Don't request with other name: %s for now", a_drawing_name);
+           return;
+       }
+   }
+
    auto ret = g_afb_instance->app.api_request_surface(a_drawing_name);
+
+   if(isFirstReq){
+       wmClientCtxt* ctxt = new wmClientCtxt(a_drawing_name);
+       HMI_DEBUG("wm", "create session for %s", ctxt->name.c_str());
+       afb_req_session_set_LOA(req, 1);
+       afb_req_context_set(req, ctxt, cbRemoveClientCtxt);
+   }
+   else{
+       HMI_DEBUG("wm", "session already created for %s", a_drawing_name);
+   }
+
    if (ret.is_err()) {
       afb_req_fail(req, "failed", ret.unwrap_err());
       return;
@@ -244,15 +298,18 @@ void windowmanager_activatesurface(afb_req req) noexcept {
        return;
    }
 
-   auto ret = g_afb_instance->app.api_activate_surface(a_drawing_name, a_drawing_area);
-   if (ret != nullptr) {
-      afb_req_fail(req, "failed", ret);
-      return;
-   }
+   g_afb_instance->app.api_activate_surface(a_drawing_name, a_drawing_area,
+      [&req](const char* errmsg){
+      if (errmsg != nullptr) {
+         HMI_ERROR("wm", errmsg);
+         afb_req_fail(req, "failed", errmsg);
+         return;
+      }
+      afb_req_success(req, NULL, "success");
+   });
 
-   afb_req_success(req, NULL, "success");
    } catch (std::exception &e) {
-      afb_req_fail_f(req, "failed", "Uncaught exception while calling activatesurface: %s", e.what());
+      HMI_WARNING("wm", "failed", "Uncaught exception while calling activatesurface: %s", e.what());
       return;
    }
 
@@ -275,15 +332,18 @@ void windowmanager_deactivatesurface(afb_req req) noexcept {
        return;
    }
 
-   auto ret = g_afb_instance->app.api_deactivate_surface(a_drawing_name);
-   if (ret != nullptr) {
-      afb_req_fail(req, "failed", ret);
-      return;
-   }
+   g_afb_instance->app.api_deactivate_surface(a_drawing_name,
+      [&req](const char* errmsg){
+      if (errmsg != nullptr) {
+         HMI_ERROR("wm", errmsg);
+         afb_req_fail(req, "failed", errmsg);
+         return;
+      }
+      afb_req_success(req, NULL, "success");
+   });
 
-   afb_req_success(req, NULL, "success");
    } catch (std::exception &e) {
-      afb_req_fail_f(req, "failed", "Uncaught exception while calling deactivatesurface: %s", e.what());
+      HMI_WARNING("wm", "Uncaught exception while calling deactivatesurface: %s", e.what());
       return;
    }
 }
@@ -304,16 +364,71 @@ void windowmanager_enddraw(afb_req req) noexcept {
        afb_req_fail(req, "failed", "Need char const* argument drawing_name");
        return;
    }
+   afb_req_success(req, NULL, "success");
 
-   auto ret = g_afb_instance->app.api_enddraw(a_drawing_name);
-   if (ret != nullptr) {
-      afb_req_fail(req, "failed", ret);
+   g_afb_instance->app.api_enddraw(a_drawing_name);
+
+   } catch (std::exception &e) {
+      HMI_WARNING("wm", "failed", "Uncaught exception while calling enddraw: %s", e.what());
       return;
    }
 
-   afb_req_success(req, NULL, "success");
+}
+
+void windowmanager_getdisplayinfo_thunk(afb_req req) noexcept {
+   std::lock_guard<std::mutex> guard(binding_m);
+   #ifdef ST
+   ST();
+   #endif
+   if (g_afb_instance == nullptr) {
+      afb_req_fail(req, "failed", "Binding not initialized, did the compositor die?");
+      return;
+   }
+
+   try {
+   auto ret = g_afb_instance->app.api_get_display_info();
+   if (ret.is_err()) {
+      afb_req_fail(req, "failed", ret.unwrap_err());
+      return;
+   }
+
+   afb_req_success(req, ret.unwrap(), "success");
+   } catch (std::exception &e) {
+      afb_req_fail_f(req, "failed", "Uncaught exception while calling getdisplayinfo: %s", e.what());
+      return;
+   }
+
+}
+
+void windowmanager_getareainfo_thunk(afb_req req) noexcept {
+   std::lock_guard<std::mutex> guard(binding_m);
+   #ifdef ST
+   ST();
+   #endif
+   if (g_afb_instance == nullptr) {
+      afb_req_fail(req, "failed", "Binding not initialized, did the compositor die?");
+      return;
+   }
+
+   try {
+   json_object *jreq = afb_req_json(req);
+
+   json_object *j_drawing_name = nullptr;
+   if (! json_object_object_get_ex(jreq, "drawing_name", &j_drawing_name)) {
+      afb_req_fail(req, "failed", "Need char const* argument drawing_name");
+      return;
+   }
+   char const* a_drawing_name = json_object_get_string(j_drawing_name);
+
+   auto ret = g_afb_instance->app.api_get_area_info(a_drawing_name);
+   if (ret.is_err()) {
+      afb_req_fail(req, "failed", ret.unwrap_err());
+      return;
+   }
+
+   afb_req_success(req, ret.unwrap(), "success");
    } catch (std::exception &e) {
-      afb_req_fail_f(req, "failed", "Uncaught exception while calling enddraw: %s", e.what());
+      afb_req_fail_f(req, "failed", "Uncaught exception while calling getareainfo: %s", e.what());
       return;
    }
 
@@ -508,6 +623,8 @@ const struct afb_verb_v2 windowmanager_verbs[] = {
    { "activatesurface", windowmanager_activatesurface, nullptr, nullptr, AFB_SESSION_NONE },
    { "deactivatesurface", windowmanager_deactivatesurface, nullptr, nullptr, AFB_SESSION_NONE },
    { "enddraw", windowmanager_enddraw, nullptr, nullptr, AFB_SESSION_NONE },
+   { "getdisplayinfo", windowmanager_getdisplayinfo_thunk, nullptr, nullptr, AFB_SESSION_NONE },
+   { "getareainfo", windowmanager_getareainfo_thunk, nullptr, nullptr, AFB_SESSION_NONE },
    { "wm_subscribe", windowmanager_wm_subscribe, nullptr, nullptr, AFB_SESSION_NONE },
    { "list_drawing_names", windowmanager_list_drawing_names, nullptr, nullptr, AFB_SESSION_NONE },
    { "ping", windowmanager_ping, nullptr, nullptr, AFB_SESSION_NONE },