Add setRole
[apps/agl-service-windowmanager.git] / src / window_manager.cpp
index 24b6f30..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;
@@ -608,6 +716,45 @@ void WindowManager::surface_removed(uint32_t surface_id)
     g_app_list.removeSurface(surface_id);
 }
 
+void WindowManager::surface_properties(unsigned surface_id, unsigned pid)
+{
+    HMI_DEBUG("wm", "get surface properties");
+
+    // search pid from surfaceID
+    /*json_object *response;
+    afb_service_call_sync("afm-main", "runners", nullptr, &response);
+
+    // retrieve appid from pid from application manager
+    std::string appid = "";
+    if(response == nullptr)
+    {
+        HMI_ERROR("wm", "No runners");
+    }
+    else
+    {
+        // check appid then add it to the client
+        HMI_INFO("wm", "Runners:%s", json_object_get_string(response));
+        int size = json_object_array_length(response);
+        for(int i = 0; i < size; i++)
+        {
+            json_object *j = json_object_array_get_idx(response, i);
+            const char* id = jh::getStringFromJson(j, "id");
+            int runid      = jh::getIntFromJson(j, "runid");
+            if(id && (runid > 0))
+            {
+                if(runid == pid)
+                {
+                    appid = id;
+                    break;
+                }
+            }
+        }
+    }
+    json_object_put(response);
+
+    g_app_list.addFloatingSurface(appid, surface_id, pid);*/
+}
+
 void WindowManager::removeClient(const std::string &appid)
 {
     HMI_DEBUG("wm", "Remove clinet %s from list", appid.c_str());
@@ -1553,4 +1700,9 @@ void controller_hooks::surface_destination_rectangle(uint32_t /*surface_id*/,
                                                      uint32_t /*w*/,
                                                      uint32_t /*h*/) {}
 
+void controller_hooks::surface_properties(uint32_t surface_id, uint32_t pid)
+{
+    this->wmgr->surface_properties(surface_id, pid);
+}
+
 } // namespace wm