Add setRole
[apps/agl-service-windowmanager.git] / src / window_manager.cpp
index 2f8e3e9..6045eaa 100644 (file)
@@ -340,6 +340,97 @@ char const *WindowManager::api_request_surface(char const *appid, char const *dr
     return nullptr;
 }
 
+/**
+ * This function is substitute of requestSurface
+ * If surface creation is faster than application request of this function,
+ * WM will bind surfaceID with application and role.
+ * If surface creation is slower than application request of thie function,
+ * WM will put Client into pending list.
+ *
+ * Note :
+ * Application can request with pid but this is temporary solution for now.
+ * This will be removed.
+ * */
+bool WindowManager::api_set_role(char const *appid, char const *drawing_name, unsigned pid){
+    std::string id = appid;
+    std::string role = drawing_name;
+    unsigned surface = 0;
+    WMError wm_err = WMError::UNKNOWN;
+    bool ret = false;
+
+    // get layer ID which role should be in
+    auto lid = this->layers.get_layer_id(role);
+    if (!lid)
+    {
+        /**
+       * register drawing_name as fallback and make it displayed.
+       */
+        lid = this->layers.get_layer_id(std::string("fallback"));
+        HMI_DEBUG("wm", "%s is not registered in layers.json, then fallback as normal app", role.c_str());
+        if (!lid)
+        {
+            HMI_ERROR("wm", "Drawing name does not match any role, fallback is disabled");
+            return ret;
+        }
+    }
+
+    if(0 != pid){
+        // search floating surfaceID from pid if pid is designated.
+        // It is not good that application request with its pid
+        wm_err = g_app_list.popFloatingSurface(pid, &surface);
+    }
+    else{
+        // get floating surface with appid. If WM queries appid from pid,
+        // WM can bind surface and role with appid(not implemented yet)
+        //wm_err = g_app_list.popFloatingSurface(id);
+    }
+    if(wm_err != WMError::SUCCESS){
+        HMI_ERROR("wm", "No floating surface for app: %s", id.c_str());
+        g_app_list.addFloatingClient(id, *lid, role);
+        HMI_NOTICE("wm", "%s : Waiting for surface creation", id.c_str());
+        return ret;
+    }
+
+    ret = true;
+    if (g_app_list.contains(id))
+    {
+        HMI_INFO("wm", "Add role: %s with surface: %d. Client %s has multi surfaces.",
+                 role.c_str(), surface, id.c_str());
+        wm_err = g_app_list.appendRole(id, role, surface);
+        if(wm_err != WMError::SUCCESS){
+            HMI_INFO("wm", errorDescription(wm_err));
+        }
+    }
+    else{
+        HMI_INFO("wm", "Create new client: %s, surface: %d into layer: %d with role: %s",
+                 id.c_str(), surface, *lid, role.c_str());
+        g_app_list.addClient(id, *lid, surface, role);
+    }
+
+    // register pair drawing_name and ivi_id
+    this->id_alloc.register_name_id(role.c_str(), surface);
+    this->layers.add_surface(surface, *lid);
+
+    // this surface is already created
+    HMI_DEBUG("wm", "surface_id is %u, layer_id is %u", surface, *lid);
+
+    const auto &o_layer = this->layers.get_layer(*lid);
+    auto rect = o_layer.value().rect;
+    if(rect.w < 0)
+    {
+        rect.w = this->controller->output_size.w + 1 + rect.w;
+    }
+    if(rect.h < 0)
+    {
+        rect.h = this->controller->output_size.h + 1 + rect.h;
+    }
+
+    this->controller->layers[*lid]->add_surface(surface);
+    this->layout_commit();
+
+    return ret;
+}
+
 void WindowManager::api_activate_surface(char const *appid, char const *drawing_name,
                                char const *drawing_area, const reply_func &reply)
 {
@@ -352,6 +443,23 @@ void WindowManager::api_activate_surface(char const *appid, char const *drawing_
     std::string id = appid;
     std::string role = c_role;
     std::string area = drawing_area;
+
+    if(!g_app_list.contains(id))
+    {
+        reply("app doesn't request 'requestSurface' or 'setRole' yet");
+        return;
+    }
+    auto client = g_app_list.lookUpClient(id);
+
+    unsigned srfc = client->surfaceID(role);
+    if(srfc == 0)
+    {
+        HMI_ERROR("wm", "role sould be set with surface");
+        reply("role sould be set with surface");
+        return;
+    }
+    g_app_list.removeFloatingSurface(client->surfaceID());
+
     Task task = Task::TASK_ALLOCATE;
     unsigned req_num = 0;
     WMError ret = WMError::UNKNOWN;