+ delete g_afb_instance;
+ g_afb_instance = nullptr;
+ return -1;
+}
+
+int binding_init() noexcept
+{
+ try
+ {
+ return _binding_init();
+ }
+ catch (std::exception &e)
+ {
+ HMI_ERROR("wm", "Uncaught exception in binding_init(): %s", e.what());
+ }
+ 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->role.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);
+ }
+ g_afb_instance->app.removeClient(ctxt->name);
+ delete ctxt;
+}
+
+void windowmanager_requestsurface(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
+ {
+ const char *a_drawing_name = afb_req_value(req, "drawing_name");
+ if (!a_drawing_name)
+ {
+ afb_req_fail(req, "failed", "Need char const* argument drawing_name");
+ 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(
+ afb_req_get_application_id(req), a_drawing_name);
+
+ if (isFirstReq)
+ {
+ WMClientCtxt *ctxt = new WMClientCtxt(afb_req_get_application_id(req), 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;
+ }
+
+ afb_req_success(req, json_object_new_int(ret.unwrap()), "success");
+ }
+ catch (std::exception &e)
+ {
+ afb_req_fail_f(req, "failed", "Uncaught exception while calling requestsurface: %s", e.what());
+ return;
+ }
+}
+
+void windowmanager_requestsurfacexdg(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);
+
+ json_object *j_ivi_id = nullptr;
+ if (!json_object_object_get_ex(jreq, "ivi_id", &j_ivi_id))
+ {
+ afb_req_fail(req, "failed", "Need char const* argument ivi_id");
+ return;
+ }
+ char const *a_ivi_id = json_object_get_string(j_ivi_id);
+
+ auto ret = g_afb_instance->app.api_request_surface(
+ afb_req_get_application_id(req), a_drawing_name, a_ivi_id);
+ if (ret != nullptr)
+ {
+ afb_req_fail(req, "failed", ret);
+ return;
+ }
+
+ afb_req_success(req, NULL, "success");
+ }
+ catch (std::exception &e)
+ {
+ afb_req_fail_f(req, "failed", "Uncaught exception while calling requestsurfacexdg: %s", e.what());
+ return;
+ }
+}
+
+void windowmanager_setrole(afb_req req) noexcept
+{
+ std::lock_guard<std::mutex> guard(binding_m);
+ if (g_afb_instance == nullptr)
+ {
+ afb_req_fail(req, "failed", "Binding not initialized, did the compositor die?");
+ return;
+ }
+ try
+ {
+ unsigned pid = 0;
+ std::string appid = afb_req_get_application_id(req);
+ json_object *jreq = afb_req_json(req);
+
+ json_object *j_role = nullptr;
+ if (!json_object_object_get_ex(jreq, "role", &j_role))
+ {
+ afb_req_fail(req, "failed", "Need char const* argument role");
+ return;
+ }
+ char const *a_role = json_object_get_string(j_role);
+
+ /* Create Security Context */
+ bool isFirstReq = checkFirstReq(req);
+ /* if (!isFirstReq)
+ {
+ WMClientCtxt *ctxt = (WMClientCtxt *)afb_req_context_get(req);
+ HMI_DEBUG("wm", "Set %s into %s.", a_role, appid.c_str());
+ } */
+
+ json_object *j_pid = nullptr;
+ if (json_object_object_get_ex(jreq, "pid", &j_pid))
+ {
+ HMI_DEBUG("wm", "PID is set");
+ char const *a_pid = json_object_get_string(j_pid);
+ pid = std::stol(a_pid);
+ }
+
+ bool ret = g_afb_instance->app.api_set_role(appid.c_str(), a_role, pid);
+ if (!ret)
+ {
+ afb_req_fail(req, "failed", "Couldn't register");
+ return;
+ }
+
+ if (isFirstReq)
+ {
+ WMClientCtxt *ctxt = new WMClientCtxt(appid.c_str(), a_role);
+ HMI_DEBUG("wm", "create session for appid:%s, role: %s", ctxt->name.c_str(), ctxt->role.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", appid.c_str());
+ }
+
+ afb_req_success(req, NULL, "success");
+ }
+ catch (std::exception &e)
+ {
+ afb_req_fail_f(req, "failed", "Uncaught exception while calling requestsurfacexdg: %s", e.what());
+ return;
+ }
+}
+
+void windowmanager_activatesurface(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
+ {
+ const char *a_drawing_name = afb_req_value(req, "drawing_name");
+ if (!a_drawing_name)
+ {
+ afb_req_fail(req, "failed", "Need char const* argument drawing_name");
+ return;
+ }
+
+ const char *a_drawing_area = afb_req_value(req, "drawing_area");
+ if (!a_drawing_area)
+ {
+ afb_req_fail(req, "failed", "Need char const* argument drawing_area");
+ return;
+ }
+
+ g_afb_instance->app.api_activate_surface(
+ afb_req_get_application_id(req),
+ 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");
+ });
+ }
+ catch (std::exception &e)
+ {
+ HMI_WARNING("wm", "failed", "Uncaught exception while calling activatesurface: %s", e.what());
+ return;
+ }
+}
+
+void windowmanager_deactivatesurface(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
+ {
+ const char *a_drawing_name = afb_req_value(req, "drawing_name");
+ if (!a_drawing_name)
+ {
+ afb_req_fail(req, "failed", "Need char const* argument drawing_name");
+ return;
+ }
+
+ g_afb_instance->app.api_deactivate_surface(
+ afb_req_get_application_id(req), 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");
+ });
+ }
+ catch (std::exception &e)
+ {
+ HMI_WARNING("wm", "Uncaught exception while calling deactivatesurface: %s", e.what());
+ return;
+ }