Ensure wm_subscribe returns the correct value
[apps/agl-service-windowmanager.git] / src / window_manager.cpp
index 22f1e22..7fc47c3 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ * Copyright (c) 2019 Konsulko Group
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -167,21 +168,25 @@ result<int> WindowManager::api_request_surface(char const *appid, char const *dr
 
     if(!g_app_list.contains(str_id))
     {
-        lid = this->lc->getNewLayerID(role);
+        lid = this->generateLayerForClient(role);
         if (lid == 0)
         {
-            // register drawing_name as fallback and make it displayed.
-            lid = this->lc->getNewLayerID(string("fallback"));
-            HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
-            if (lid == 0)
-            {
-                return Err<int>("Designated role does not match any role, fallback is disabled");
-            }
+            return Err<int>("Designated role does not match any role, fallback is disabled");
         }
-        this->lc->createNewLayer(lid);
         // add client into the db
         g_app_list.addClient(str_id, lid, role);
     }
+    else
+    {
+        // This case occurs when an client calls "subscribe" before request_surface.
+        // Then application doesn't have layer and role yet.
+        auto client = g_app_list.lookUpClient(str_id);
+        if(client->layerID() == 0)
+        {
+            client->setLayerID(this->generateLayerForClient(role));
+        }
+        client->setRole(role);
+    }
 
     // generate surface ID for ivi-shell application
     auto rname = this->id_alloc.lookup(role);
@@ -224,21 +229,25 @@ char const *WindowManager::api_request_surface(char const *appid, char const *dr
 
     if(!g_app_list.contains(str_id))
     {
-        unsigned l_id = this->lc->getNewLayerID(role);
+        unsigned l_id = this->generateLayerForClient(role);
         if (l_id == 0)
         {
-            // register drawing_name as fallback and make it displayed.
-            l_id = this->lc->getNewLayerID("fallback");
-            HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
-            if (l_id == 0)
-            {
-                return "Designated role does not match any role, fallback is disabled";
-            }
+            return "Designated role does not match any role, fallback is disabled";
         }
-        this->lc->createNewLayer(l_id);
         // add client into the db
         g_app_list.addClient(str_id, l_id, role);
     }
+    else
+    {
+        // This case occurs when an client calls "subscribe" before request_surface.
+        // Then application doesn't have layer and role yet.
+        auto client = g_app_list.lookUpClient(str_id);
+        if(client->layerID() == 0)
+        {
+            client->setLayerID(this->generateLayerForClient(role));
+        }
+        client->setRole(role);
+    }
 
     auto rname = this->id_alloc.lookup(role);
 
@@ -484,9 +493,10 @@ bool WindowManager::api_subscribe(afb_req_t req, EventType event_id)
     if(event_id < Event_Val_Min || event_id > Event_Val_Max)
     {
         HMI_ERROR("not defined in Window Manager", event_id);
+        free(appid);
         return ret;
     }
-    HMI_INFO("%s subscribe %s : %d", appid, kListEventName[event_id], event_id);
+    HMI_INFO("%s subscribe %s : %d", appid, kListEventName[event_id].c_str(), event_id);
     if(event_id == Event_ScreenUpdated)
     {
         // Event_ScreenUpdated should be emitted to subscriber
@@ -500,13 +510,17 @@ bool WindowManager::api_subscribe(afb_req_t req, EventType event_id)
     else if(appid)
     {
         string id = appid;
-        free(appid);
-        auto client = g_app_list.lookUpClient(id);
-        if(client != nullptr)
+        if(!g_app_list.contains(id))
         {
-            ret = client->subscribe(req, kListEventName[event_id]);
+            g_app_list.addClient(id);
         }
+        ret = g_app_list.lookUpClient(id)->subscribe(req, kListEventName[event_id]);
+    }
+    else
+    {
+        HMI_ERROR("appid is not set");
     }
+    free(appid);
     return ret;
 }
 
@@ -699,6 +713,28 @@ void WindowManager::processError(WMError error)
     this->processNextRequest();
 }
 
+unsigned WindowManager::generateLayerForClient(const string& role)
+{
+    string l_name;
+    unsigned lid = this->lc->getNewLayerID(role, &l_name);
+    if (lid == 0)
+    {
+        // register drawing_name as fallback and make it displayed.
+        lid = this->lc->getNewLayerID(string("fallback"));
+        HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role.c_str());
+        if (lid == 0)
+        {
+            return lid;
+        }
+    }
+
+    // TODO: remote layer name is fixed
+    this->lc->createNewLayer(lid, ("Remote" == l_name));
+
+    // add client into the db
+    return lid;
+}
+
 WMError WindowManager::setRequest(const string& appid, const string &role, const string &area,
                             Task task, unsigned* req_num)
 {
@@ -804,7 +840,6 @@ WMError WindowManager::startTransition(unsigned req_num)
         for (const auto &x : actions)
         {
             this->lc->visibilityChange(x);
-            x.client->emitActive(false);
             x.client->emitVisible(false);
         }
         this->lc->renderLayers();
@@ -841,8 +876,6 @@ WMError WindowManager::doEndDraw(unsigned req_num)
                 return ret;
             }
             ret = this->lc->visibilityChange(act);
-
-            act.client->emitActive((act.visible == VISIBLE));
             act.client->emitVisible((act.visible == VISIBLE));
 
             if (ret != WMError::SUCCESS)