Add remote display support
[apps/agl-service-windowmanager.git] / src / wm_layer_control.cpp
index 17443de..f3f709f 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ * Copyright (c) 2018,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.
 #include "request.hpp"
 #include "json_helper.hpp"
 
-#define LC_AREA_PATH "/etc/areas.json"
-#define LC_LAYER_SETTING_PATH "/etc/layers.json"
+#define LC_AREA_FILE "areas.json"
+#define LC_LAYER_SETTING_FILE "layers.json"
 #define LC_DEFAULT_AREA "fullscreen"
+#define LC_REMOTE_DEFAULT_AREA "remote.fullscreen"
 #define BACK_GROUND_LAYER "BackGroundLayer"
 
 using std::string;
@@ -58,8 +60,8 @@ static void layerCallback_static(t_ilm_layer layer,
 
 LayerControl::LayerControl(const std::string& root)
 {
-    string area_path = root + LC_AREA_PATH;
-    string layer_path= root + LC_LAYER_SETTING_PATH;
+    string area_path(get_file_path(LC_AREA_FILE, root.c_str()));
+    string layer_path(get_file_path(LC_LAYER_SETTING_FILE, root.c_str()));
     // load layers.setting.json
     WMError ret = this->loadLayerSetting(layer_path);
     assert(ret == WMError::SUCCESS);
@@ -102,6 +104,18 @@ WMError LayerControl::init(const LayerControlCallbacks& cb)
     // Currently, 0 is only available
     this->screenID = ids[0];
 
+    if (1 < num)
+    {
+        // TODO: set remote screen id
+        HMI_INFO("There is remote screen (id:%d)", ids[1]);
+        this->remoteScreenID = ids[1];
+    }
+    else
+    {
+        HMI_INFO("There is no remote screen");
+        this->remoteScreenID = -1;
+    }
+
     rc = ilm_getPropertiesOfScreen(this->screenID, &this->screen_prop);
 
     if(rc != ILM_SUCCESS) goto lc_init_error;
@@ -118,10 +132,10 @@ lc_init_error:
     return WMError::FAIL;
 }
 
-void LayerControl::createNewLayer(unsigned id)
+void LayerControl::createNewLayer(unsigned id, bool remote)
 {
-    HMI_INFO("create new ID :%d", id);
-    struct rect rct = this->area2size[LC_DEFAULT_AREA];
+    HMI_INFO("create new ID :%d%s", id, remote ? " (For remote layer)" : "");
+    struct rect rct = this->area2size[remote ? LC_REMOTE_DEFAULT_AREA : LC_DEFAULT_AREA];
     ilm_layerCreateWithDimension(&id, rct.w, rct.h);
     //ilm_layerSetSourceRectangle(id, rct.x, rct.y, rct.w, rct.h);
     ilm_layerSetDestinationRectangle(id, this->offset_x, this->offset_y, rct.w, rct.h);
@@ -130,10 +144,11 @@ void LayerControl::createNewLayer(unsigned id)
     ilm_commitChanges();
     auto wm_layer = getWMLayer(id);
     wm_layer->addLayerToState(id);
+    wm_layer->setRemote(remote);
     this->renderLayers();
 }
 
-unsigned LayerControl::getNewLayerID(const string& role)
+unsigned LayerControl::getNewLayerID(const string& role, std::string* layer_name)
 {
     unsigned ret = 0;
     for(const auto& l: this->wm_layers)
@@ -143,6 +158,10 @@ unsigned LayerControl::getNewLayerID(const string& role)
         {
             unsigned wmlid = l->getWMLayerID();
             this->lid2wmlid[ret] = wmlid;
+            if(layer_name)
+            {
+                *layer_name = l->layerName();
+            }
             break;
         }
     }
@@ -205,17 +224,29 @@ WMError LayerControl::renderLayers()
     HMI_INFO("Commit change");
     WMError rc = WMError::SUCCESS;
 
+    bool haveRemoteDisplay = remoteScreenID > 0;
+
     // Check the number of layers
     vector<unsigned> ivi_l_ids;
+    vector<unsigned> ivi_remote_l_ids;
     for(auto& l : this->wm_layers)
     {
         auto state = l->getLayerState();
         HMI_DEBUG("layer %s", l->layerName().c_str());
-        for(const auto& id : state.getIviIdList())
+        if (!l->isRemote())
         {
-            HMI_DEBUG("Add %d", id);
-            ivi_l_ids.push_back(id);
-        }
+            for(const auto& id : state.getIviIdList())
+            {
+                HMI_DEBUG("Add %d", id);
+                ivi_l_ids.push_back(id);
+            }
+       } else if (haveRemoteDisplay) {
+            for(const auto& id : state.getIviIdList())
+            {
+                HMI_DEBUG("Add remote %d", id);
+                ivi_remote_l_ids.push_back(id);
+            }
+       }
     }
 
     // Create render order
@@ -229,12 +260,31 @@ WMError LayerControl::renderLayers()
     int count = 0;
     for(const auto& i : ivi_l_ids)
     {
-        id_array[count] = i;
-        ++count;
+        id_array[count++] = i;
+    }
+
+    t_ilm_layer* remote_id_array = nullptr;
+    if(haveRemoteDisplay && ivi_remote_l_ids.size() != 0) {
+        remote_id_array = new t_ilm_layer[ivi_remote_l_ids.size()];
+        if(remote_id_array == nullptr)
+        {
+            HMI_WARNING("short memory");
+            this->undoUpdate();
+            return WMError::FAIL;
+        }
+        count = 0;
+        for(const auto& i : ivi_remote_l_ids)
+        {
+           remote_id_array[count++] = i;
+        }
     }
 
     // Display
     ilmErrorTypes ret = ilm_displaySetRenderOrder(this->screenID, id_array, ivi_l_ids.size());
+    if(ret == ILM_SUCCESS && haveRemoteDisplay)
+    {
+        ret = ilm_displaySetRenderOrder(this->remoteScreenID, remote_id_array, ivi_remote_l_ids.size());
+    }
     if(ret != ILM_SUCCESS)
     {
         this->undoUpdate();
@@ -249,6 +299,7 @@ WMError LayerControl::renderLayers()
     }
     ilm_commitChanges();
     delete id_array;
+    delete remote_id_array;
     return rc;
 }
 
@@ -277,7 +328,7 @@ void LayerControl::undoUpdate()
 
 WMError LayerControl::loadLayerSetting(const string &path)
 {
-    HMI_DEBUG("loading WMLayer(Application Containers) Setting from %s", path);
+    HMI_DEBUG("loading WMLayer(Application Containers) Setting from %s", path.c_str());
 
     json_object *json_obj, *json_cfg;
     int ret = jh::inputJsonFilie(path.c_str(), &json_obj);
@@ -393,15 +444,18 @@ WMError LayerControl::layoutChange(const WMAction& action)
     unsigned surface = action.client->surfaceID();
 
     auto rect = this->getAreaSize(action.area);
-    HMI_DEBUG("Set layout %d, %d, %d, %d",rect.x, rect.y, rect.w, rect.h);
+    HMI_SEQ_INFO(action.req_num, "Set layout %d, %d, %d, %d",rect.x, rect.y, rect.w, rect.h);
 
     // Sometimes, ivi_wm_surface_size signal doesn't reach window manager,
     // then, Window Manager set set source size = 0.
     if(!action.client->isSourceSizeSet())
     {
         ilmSurfaceProperties sp;
-        ilm_getPropertiesOfSurface(surface, &sp);
-        if((sp.origSourceHeight != sp.sourceHeight) || (sp.origSourceWidth != sp.sourceWidth))
+        if (ILM_SUCCESS != ilm_getPropertiesOfSurface(surface, &sp))
+            return WMError::FAIL;
+
+        if  (sp.origSourceHeight != sp.sourceHeight ||
+             sp.origSourceWidth  != sp.sourceWidth)
         {
             HMI_SEQ_NOTICE(action.req_num, "set source size w:%d h%d", sp.origSourceWidth, sp.origSourceHeight);
             ilm_surfaceSetSourceRectangle(surface, 0, 0, sp.origSourceWidth, sp.origSourceHeight);
@@ -412,6 +466,7 @@ WMError LayerControl::layoutChange(const WMAction& action)
 
     ilm_surfaceSetDestinationRectangle(surface, rect.x, rect.y, rect.w, rect.h);
     ilm_commitChanges();
+    action.client->setArea(action.area);
     for(auto &wm_layer: this->wm_layers)
     {
         // Store the state who is assigned to the area
@@ -449,6 +504,48 @@ WMError LayerControl::visibilityChange(const WMAction& action)
     return ret;
 }
 
+WMError LayerControl::updateAreaList(const ChangeAreaReq& req)
+{
+    // error check
+    for(const auto& elem : req.area_req)
+    {
+        if(this->area2size.find(elem.first) == this->area2size.end())
+        {
+            HMI_ERROR("requested area %s is not registered in area list", elem.first.c_str());
+            return WMError::NOT_REGISTERED;
+        }
+    }
+    // update list
+    for(const auto& elem : req.area_req)
+    {
+        this->area2size[elem.first] = elem.second;
+    }
+    if(req.save)
+    {
+        HMI_NOTICE("Not implemented");
+        // TODO
+    }
+    return WMError::SUCCESS;
+}
+
+WMError LayerControl::getUpdateAreaList(ChangeAreaReq *req)
+{
+    for(const auto& wm_layer : this->wm_layers)
+    {
+        // get area name and compare it with elem
+        for(const auto& area : req->area_req)
+        {
+            string app = wm_layer->attachedApp(area.first);
+            if(!app.empty())
+            {
+                HMI_INFO("app %s changes area %s", app.c_str(), area.first.c_str());
+                req->update_app2area[app] = area.first;
+            }
+        }
+    }
+    return WMError::SUCCESS;
+}
+
 void LayerControl::appTerminated(const shared_ptr<WMClient> client)
 {
     for(auto& l : this->wm_layers)
@@ -557,11 +654,18 @@ WMError LayerControl::makeVisible(const shared_ptr<WMClient> client)
 {
     WMError ret = WMError::SUCCESS;
     // Don't check here wheher client is nullptr or not
-    unsigned layer = client->layerID();
+    unsigned layer_id = client->layerID();
+    auto layer = getWMLayer(layer_id);
 
-    this->moveForeGround(client);
+    if (!layer->isRemote())
+    {
+       this->moveForeGround(client);
+    }
+    else if (0 > this->remoteScreenID) {
+        return ret;
+    }
 
-    ilm_layerSetVisibility(layer, ILM_TRUE);
+    ilm_layerSetVisibility(layer_id, ILM_TRUE);
 
     return ret;
 }
@@ -570,14 +674,28 @@ WMError LayerControl::makeInvisible(const shared_ptr<WMClient> client)
 {
     WMError ret = WMError::SUCCESS;
     // Don't check here the client is not nullptr
-    unsigned layer = client->layerID();
+    unsigned layer_id = client->layerID();
+    auto layer = getWMLayer(layer_id);
 
-    bool mv_ok = this->moveBackGround(client);
+    bool set_invisible = true;
+    if (!layer->isRemote())
+    {
+        if(this->moveBackGround(client))
+        {
+            set_invisible = false;
+        }
+        else
+        {
+            HMI_INFO("make invisible client %s", client->appID().c_str());
+        }
+    }
+    else if (0 > this->remoteScreenID) {
+        return ret;
+    }
 
-    if(!mv_ok)
+    if (set_invisible)
     {
-        HMI_INFO("make invisible client %s", client->appID().c_str());
-        ilm_layerSetVisibility(layer, ILM_FALSE);
+        ilm_layerSetVisibility(layer_id, ILM_FALSE);
     }
 
     return ret;
@@ -640,4 +758,4 @@ bool LayerControl::moveForeGround(const shared_ptr<WMClient> client)
     return ret;
 }
 
-} // namespace wm
\ No newline at end of file
+} // namespace wm