10e99b95eb44ff3c48f3d275a9ebb9691637aa2c
[apps/agl-service-windowmanager-2017.git] / src / wm_layer_control.cpp
1 /*
2  * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <assert.h>
17 #include <unistd.h>
18 #include "wm_layer_control.hpp"
19 #include "wm_layer.hpp"
20 #include "wm_client.hpp"
21 #include "request.hpp"
22 #include "json_helper.hpp"
23
24 #define LC_AREA_PATH "/etc/areas.json"
25 #define LC_LAYER_SETTING_PATH "/etc/layers_setting.json"
26 #define LC_DEFAULT_AREA "fullscreen"
27 #define BACK_GROUND_LAYER "BackGroundLayer"
28
29 using std::string;
30 using std::vector;
31 using std::shared_ptr;
32
33 namespace wm {
34
35 LayerControl* g_lc_ctxt;
36
37 static void createCallback_static(ilmObjectType object,
38                             t_ilm_uint id,
39                             t_ilm_bool created,
40                             void* data)
41 {
42     static_cast<LayerControl*>(data)->dispatchCreateEvent(object, id, created);
43 }
44
45 static void surfaceCallback_static(t_ilm_surface surface,
46             struct ilmSurfaceProperties* surface_prop,
47             t_ilm_notification_mask mask)
48 {
49     g_lc_ctxt->dispatchSurfacePropChangeEvent(surface, surface_prop, mask);
50 }
51
52 static void layerCallback_static(t_ilm_layer layer,
53             struct ilmLayerProperties* layer_prop,
54             t_ilm_notification_mask mask)
55 {
56     g_lc_ctxt->dispatchLayerPropChangeEvent(layer, layer_prop, mask);
57 }
58
59 LayerControl::LayerControl(const std::string& root, const std::string& ecu_name)
60 {
61     string area_path = root + LC_AREA_PATH;
62     string layer_path= root + LC_LAYER_SETTING_PATH;
63     // load layers.setting.json
64     WMError ret = this->loadLayerSetting(layer_path);
65     assert(ret == WMError::SUCCESS);
66     // load areas.json
67     ret = this->loadAreasConfigFile(area_path, ecu_name);
68     assert(ret == WMError::SUCCESS);
69 }
70
71 WMError LayerControl::init(const LayerControlCallbacks& cb)
72 {
73     HMI_DEBUG("Initialize of ilm library and display");
74     t_ilm_uint num = 0;
75     t_ilm_uint *ids;
76     int cnt = 0;
77     ilmErrorTypes rc = ilm_init();
78
79     while (rc != ILM_SUCCESS)
80     {
81         cnt++;
82         if (20 <= cnt)
83         {
84             HMI_ERROR("Could not connect to compositor");
85             goto lc_init_error;
86         }
87         HMI_ERROR("Wait to start weston ...");
88         sleep(1);
89         rc = ilm_init();
90     }
91     if(rc != ILM_SUCCESS) goto lc_init_error;
92
93     // Get current screen setting
94     rc = ilm_getScreenIDs(&num, &ids);
95
96     if(rc != ILM_SUCCESS) goto lc_init_error;
97
98     for(unsigned i = 0; i < num; i++)
99     {
100         HMI_INFO("get screen: %d", ids[i]);
101     }
102     // Currently, 0 is only available
103     this->screenID = ids[0];
104
105     if (1 < num)
106     {
107         // TODO: set remote screen id
108         HMI_INFO("There is remote screen (id:%d)", ids[1]);
109         this->remoteScreenID = ids[1];
110     }
111     else
112     {
113         HMI_INFO("There is no remote screen");
114         this->remoteScreenID = -1;
115     }
116
117     rc = ilm_getPropertiesOfScreen(this->screenID, &this->screen_prop);
118
119     if(rc != ILM_SUCCESS) goto lc_init_error;
120
121     // Register Callback to Window Manager and from ILM
122     this->cb = cb;
123     ilm_registerNotification(createCallback_static, this);
124
125     return WMError::SUCCESS;
126
127 lc_init_error:
128     HMI_ERROR("Failed to initialize. Terminate WM");
129
130     return WMError::FAIL;
131 }
132
133 void LayerControl::createNewLayer(unsigned id)
134 {
135     HMI_INFO("create new ID :%d", id);
136     struct rect rct = this->area2size[LC_DEFAULT_AREA];
137     ilm_layerCreateWithDimension(&id, rct.w, rct.h);
138     //ilm_layerSetSourceRectangle(id, rct.x, rct.y, rct.w, rct.h);
139     ilm_layerSetDestinationRectangle(id, this->offset_x, this->offset_y, rct.w, rct.h);
140     ilm_layerSetOpacity(id, 1.0);
141     ilm_layerSetVisibility(id, ILM_FALSE);
142     ilm_commitChanges();
143     auto wm_layer = getWMLayer(id);
144     wm_layer->addLayerToState(id);
145     this->renderLayers();
146     this->renderLayersRemote();
147 }
148
149 void LayerControl::createNewRemoteLayer(unsigned id)
150 {
151     HMI_INFO("create new ID :%d (For remote layer)", id);
152     struct rect rct = {640, 720, 0, 0};
153     ilm_layerCreateWithDimension(&id, rct.w, rct.h);
154     //ilm_layerSetSourceRectangle(id, rct.x, rct.y, rct.w, rct.h);
155     ilm_layerSetDestinationRectangle(id, this->offset_x, this->offset_y, rct.w, rct.h);
156     ilm_layerSetOpacity(id, 1.0);
157     ilm_layerSetVisibility(id, ILM_FALSE);
158     ilm_commitChanges();
159     auto wm_layer = getWMLayer(id);
160     wm_layer->addLayerToState(id);
161     this->renderLayers();
162     this->renderLayersRemote();
163 }
164
165 unsigned LayerControl::getNewLayerID(const string& role, string* layer_name)
166 {
167     unsigned ret = 0;
168     for(const auto& l: this->wm_layers)
169     {
170         ret = l->getNewLayerID(role);
171         if(ret != 0)
172         {
173             *layer_name = l->layerName();
174             unsigned uid = l->getUuid();
175             this->lid2wmlid[ret] = uid;
176             break;
177         }
178     }
179     return ret;
180 }
181
182 shared_ptr<WMLayer> LayerControl::getWMLayer(unsigned layer)
183 {
184     unsigned uuid = this->lid2wmlid[layer];
185     return this->wm_layers[uuid];
186 }
187
188 std::shared_ptr<WMLayer> LayerControl::getWMLayer(std::string layer_name)
189 {
190     for(auto &l : this->wm_layers)
191     {
192         if(l->layerName() == layer_name)
193         {
194             return l;
195         }
196     }
197     return nullptr;
198 }
199
200 struct rect LayerControl::getAreaSize(const std::string& area)
201 {
202     return area2size[area];
203 }
204
205 void LayerControl::setupArea(const rectangle& base_rct, double scaling)
206 {
207     this->scaling = scaling;
208     this->offset_x = base_rct.left();
209     this->offset_y = base_rct.top();
210
211     for (auto &i : this->area2size)
212     {
213         i.second.x = static_cast<int>(scaling * i.second.x + 0.5);
214         i.second.y = static_cast<int>(scaling * i.second.y + 0.5);
215         i.second.w = static_cast<int>(scaling * i.second.w + 0.5);
216         i.second.h = static_cast<int>(scaling * i.second.h + 0.5);
217
218         HMI_DEBUG("area:%s size(after) : x:%d y:%d w:%d h:%d",
219             i.first.c_str(), i.second.x, i.second.y, i.second.w, i.second.h);
220     }
221 }
222
223 Screen LayerControl::getScreenInfo()
224 {
225     return Screen(this->screen_prop.screenWidth, this->screen_prop.screenHeight);
226 }
227
228 double LayerControl::scale()
229 {
230     return this->scaling;
231 }
232
233 WMError LayerControl::updateLayer(LayerState& layer_state)
234 {
235     return WMError::SUCCESS;
236 }
237
238 WMError LayerControl::renderLayers()
239 {
240     HMI_INFO("Commit change");
241     WMError rc = WMError::SUCCESS;
242
243     // Check the number of layers
244     vector<unsigned> ivi_l_ids;
245     for(auto& l : this->wm_layers)
246     {
247         auto state = l->getLayerState();
248         HMI_DEBUG("layer %s", l->layerName().c_str());
249         for(const auto& id : state.getIviIdList())
250         {
251             HMI_DEBUG("Add %d", id);
252             ivi_l_ids.push_back(id);
253         }
254     }
255
256     // Create render order
257     t_ilm_layer* id_array = new t_ilm_layer[ivi_l_ids.size()];
258     if(id_array == nullptr)
259     {
260         HMI_WARNING("short memory");
261         this->undoUpdate();
262         return WMError::FAIL;
263     }
264     int count = 0;
265     for(const auto& i : ivi_l_ids)
266     {
267         id_array[count] = i;
268         ++count;
269     }
270
271     // Display
272     ilmErrorTypes ret = ilm_displaySetRenderOrder(this->screenID, id_array, ivi_l_ids.size());
273     if(ret != ILM_SUCCESS)
274     {
275         this->undoUpdate();
276         rc = WMError::FAIL;
277     }
278     else
279     {
280         for(auto& l : this->wm_layers)
281         {
282             l->update();
283         }
284     }
285     ilm_commitChanges();
286     delete id_array;
287     return rc;
288 }
289
290 WMError LayerControl::renderLayersRemote()
291 {
292     HMI_INFO("Commit change");
293     WMError rc = WMError::SUCCESS;
294
295     if (0 > this->remoteScreenID)
296     {
297         return rc;
298     }
299
300     // Check the number of layers
301     vector<unsigned> ivi_l_ids;
302     for(auto& l : this->wm_remote_layers)
303     {
304         auto state = l->getLayerState();
305         HMI_DEBUG("layer %s", l->layerName().c_str());
306         for(const auto& id : state.getIviIdList())
307         {
308             HMI_DEBUG("Add %d", id);
309             ivi_l_ids.push_back(id);
310         }
311     }
312
313     if (0 == ivi_l_ids.size())
314     {
315         ilm_displaySetRenderOrder(this->remoteScreenID, nullptr, 0);
316         return rc;
317     }
318
319     // Create render order
320     t_ilm_layer* id_array = new t_ilm_layer[ivi_l_ids.size()];
321     if(id_array == nullptr)
322     {
323         HMI_WARNING("short memory");
324         this->undoUpdate();
325         return WMError::FAIL;
326     }
327     int count = 0;
328     for(const auto& i : ivi_l_ids)
329     {
330         id_array[count] = i;
331         ++count;
332     }
333
334     // Display
335     ilmErrorTypes ret = ilm_displaySetRenderOrder(this->remoteScreenID, id_array, ivi_l_ids.size());
336     if(ret != ILM_SUCCESS)
337     {
338         this->undoUpdate();
339         rc = WMError::FAIL;
340     }
341     else
342     {
343         for(auto& l : this->wm_remote_layers)
344         {
345             l->update();
346         }
347     }
348     ilm_commitChanges();
349     delete id_array;
350     return rc;
351 }
352
353 WMError LayerControl::setXDGSurfaceOriginSize(unsigned surface)
354 {
355     WMError ret = WMError::NOT_REGISTERED;
356     ilmSurfaceProperties prop;
357     ilmErrorTypes rc = ilm_getPropertiesOfSurface(surface, &prop);
358     if(rc == ILM_SUCCESS)
359     {
360         HMI_INFO("xdg surface info %d, %d", prop.origSourceWidth, prop.origSourceHeight);
361         ilm_surfaceSetSourceRectangle(surface, 0, 0, prop.origSourceWidth, prop.origSourceHeight);
362         ret = WMError::SUCCESS;
363     }
364     return ret;
365 }
366
367
368 void LayerControl::undoUpdate()
369 {
370     for(auto& l : this->wm_layers)
371     {
372         l->undo();
373     }
374 }
375
376 WMError LayerControl::loadLayerSetting(const string &path)
377 {
378     HMI_DEBUG("loading WMLayer(Application Containers) Setting from %s", path);
379
380     json_object *json_obj, *json_cfg;
381     int ret = jh::inputJsonFilie(path.c_str(), &json_obj);
382     if (0 > ret)
383     {
384         HMI_ERROR("Could not open %s", path.c_str());
385         return WMError::FAIL;
386     }
387     HMI_INFO("json_obj dump:%s", json_object_get_string(json_obj));
388
389     if (!json_object_object_get_ex(json_obj, "mappings", &json_cfg))
390     {
391         HMI_ERROR("Parse Error!!");
392         return WMError::FAIL;
393     }
394
395     int len = json_object_array_length(json_cfg);
396     HMI_DEBUG("json_cfg len:%d", len);
397
398     for (int i = 0; i < len; i++)
399     {
400         json_object *json_tmp = json_object_array_get_idx(json_cfg, i);
401         HMI_DEBUG("> json_tmp dump:%s", json_object_get_string(json_tmp));
402
403         this->wm_layers.emplace_back(std::make_shared<WMLayer>(json_tmp, i));
404     }
405     json_object_put(json_obj);
406
407     return WMError::SUCCESS;
408 }
409
410 WMError LayerControl::loadAreasConfigFile(const std::string& path, const std::string& ecu_name)
411 {
412     // Load areas config file
413     json_object *json_obj;
414     int ret = jh::inputJsonFilie(path.c_str(), &json_obj);
415     if (0 > ret)
416     {
417         HMI_ERROR("Could not open %s", path.c_str());
418         return WMError::FAIL;
419     }
420     HMI_INFO("json_obj dump:%s", json_object_get_string(json_obj));
421
422     // Parse ecus
423     json_object *json_cfg;
424     if (!json_object_object_get_ex(json_obj, "ecus", &json_cfg))
425     {
426         HMI_ERROR("Parse Error!!");
427         return WMError::FAIL;
428     }
429
430     int num_ecu = json_object_array_length(json_cfg);
431     HMI_DEBUG("json_cfg(ecus) len:%d", num_ecu);
432
433     const char* c_ecu_name;
434     json_object *json_ecu;
435     for (int i = 0; i < num_ecu; i++)
436     {
437         json_ecu= json_object_array_get_idx(json_cfg, i);
438
439         c_ecu_name = jh::getStringFromJson(json_ecu, "name");
440         if (nullptr == c_ecu_name)
441         {
442             HMI_ERROR("Parse Error!!");
443             return WMError::FAIL;
444         }
445
446         if (ecu_name == string(c_ecu_name))
447         {
448             break;
449         }
450         else
451         {
452             json_ecu = nullptr;
453         }
454     }
455
456     if (!json_ecu)
457     {
458         HMI_ERROR("Areas for ecu:%s is NOT exist!!", ecu_name.c_str());
459         return WMError::FAIL;
460     }
461
462     // Parse screens
463     if (!json_object_object_get_ex(json_ecu, "screens", &json_cfg))
464     {
465         HMI_ERROR("Parse Error!!");
466         return WMError::FAIL;
467     }
468
469     int num_screen = json_object_array_length(json_cfg);
470     HMI_DEBUG("json_cfg(screens) len:%d", num_screen);
471
472     int screen_id;
473     json_object *json_screen;
474     for (int i = 0; i < num_screen; i++)
475     {
476         json_screen = json_object_array_get_idx(json_cfg, i);
477         HMI_INFO("json_cfg dump:%s", json_object_get_string(json_cfg));
478
479         // TODO: Currently only one display is connected to a ECU.
480
481         screen_id = jh::getIntFromJson(json_screen, "id");
482
483         // Parse areas
484         json_object *json_tmp;
485         if (!json_object_object_get_ex(json_screen, "areas", &json_tmp))
486         {
487             HMI_ERROR("Parse Error!!");
488             return WMError::FAIL;
489         }
490
491         int num_area = json_object_array_length(json_tmp);
492         HMI_DEBUG("json_tmp(areas) len:%d", num_area);
493
494         const char *area;
495         for (int j = 0; j < num_area; j++)
496         {
497             json_object *json_area = json_object_array_get_idx(json_tmp, j);
498
499             area = jh::getStringFromJson(json_area, "name");
500             if (nullptr == area)
501             {
502                 HMI_ERROR("Parse Error!!");
503                 return WMError::FAIL;
504             }
505             HMI_DEBUG("> area:%s", area);
506
507             json_object *json_rect;
508             if (!json_object_object_get_ex(json_area, "rect", &json_rect))
509             {
510                 HMI_ERROR("Parse Error!!");
511                 return WMError::FAIL;
512             }
513
514             struct rect area_size;
515             area_size.x = jh::getIntFromJson(json_rect, "x");
516             area_size.y = jh::getIntFromJson(json_rect, "y");
517             area_size.w = jh::getIntFromJson(json_rect, "w");
518             area_size.h = jh::getIntFromJson(json_rect, "h");
519
520             this->area2size[area] = area_size;
521         }
522
523         // Check
524         for (const auto& itr : this->area2size)
525         {
526             HMI_DEBUG("area:%s x:%d y:%d w:%d h:%d",
527                       itr.first.c_str(), itr.second.x, itr.second.y,
528                       itr.second.w, itr.second.h);
529         }
530     }
531
532     // Release json_object
533     json_object_put(json_obj);
534
535     return WMError::SUCCESS;
536 }
537
538 WMError LayerControl::layoutChange(const WMAction& action)
539 {
540     if ((action.visible == TaskVisible::INVISIBLE) ||
541         (action.visible == TaskVisible::REQ_REMOTE_VISIBLE) ||
542         (action.visible == TaskVisible::REQ_REMOTE_INVISIBLE))
543     {
544         // Visibility is not change -> no redraw is required
545         return WMError::SUCCESS;
546     }
547     if(action.client == nullptr)
548     {
549         HMI_SEQ_ERROR(action.req_num, "client may vanish");
550         return WMError::NOT_REGISTERED;
551     }
552     unsigned layer = action.client->layerID();
553     unsigned surface = action.client->surfaceID();
554
555     auto rect = this->getAreaSize(action.area);
556     HMI_DEBUG("Set layout %d, %d, %d, %d",rect.x, rect.y, rect.w, rect.h);
557     ilm_commitChanges();
558     ilm_surfaceSetDestinationRectangle(surface, rect.x, rect.y, rect.w, rect.h);
559     ilm_commitChanges();
560     for(auto &wm_layer: this->wm_layers)
561     {
562         // Store the state who is assigned to the area
563         if(wm_layer->hasLayerID(layer))
564         {
565             wm_layer->setAreaToState(action.client->appID(), action.area);
566             /* TODO: manipulate state directly
567                LayerState ls = wm_layer->getLayerState();
568                ls.setArea(action.client->appID(), action.area);
569                wm_layer->dump(); */
570         }
571     }
572
573     return WMError::SUCCESS;
574 }
575
576 WMError LayerControl::visibilityChange(const WMAction& action)
577 {
578     WMError ret = WMError::FAIL;
579     if(action.client == nullptr)
580     {
581         HMI_SEQ_ERROR(action.req_num, "client may vanish");
582         return WMError::NOT_REGISTERED;
583     }
584
585     if (action.visible == TaskVisible::VISIBLE)
586     {
587         ret = this->makeVisible(action.client);
588     }
589     else if (action.visible == TaskVisible::INVISIBLE)
590     {
591         ret = this->makeInvisible(action.client);
592     }
593     else if (action.visible == TaskVisible::REMOTE_VISIBLE)
594     {
595         ret = this->makeRemoteVisible(action.client);
596     }
597     else if (action.visible == TaskVisible::REMOTE_INVISIBLE)
598     {
599         ret = this->makeRemoteInvisible(action.client);
600     }
601     else // TaskVisible::REQ_REMOTE_VISIBLE || TaskVisible::REQ_REMOTE_INVISIBLE
602     {
603         // Visibility is not change
604         ret = WMError::SUCCESS;
605     }
606
607     return ret;
608 }
609
610 void LayerControl::terminateApp(const shared_ptr<WMClient> client)
611 {
612     for(auto& l : this->wm_layers)
613     {
614         l->terminateApp(client->layerID());
615     }
616 }
617
618 void LayerControl::dispatchCreateEvent(ilmObjectType object, unsigned id, bool created)
619 {
620     if (ILM_SURFACE == object)
621     {
622         if (created)
623         {
624             ilmSurfaceProperties sp;
625             ilmErrorTypes rc;
626             rc = ilm_getPropertiesOfSurface(id, &sp);
627             if(rc != ILM_SUCCESS)
628             {
629                 HMI_ERROR("Failed to get surface %d property due to %d", id, ilm_getError());
630                 return;
631             }
632             this->cb.surfaceCreated(sp.creatorPid, id);
633             ilm_surfaceSetSourceRectangle(id, 0, 0, sp.origSourceWidth, sp.origSourceHeight);
634             ilm_surfaceAddNotification(id, surfaceCallback_static);
635             ilm_surfaceSetVisibility(id, ILM_TRUE);
636             ilm_surfaceSetType(id, ILM_SURFACETYPE_DESKTOP);
637         }
638         else
639         {
640             this->cb.surfaceDestroyed(id);
641         }
642     }
643     if (ILM_LAYER == object)
644     {
645         if(created)
646         {
647             ilm_layerAddNotification(id, layerCallback_static);
648         }
649         else
650         {
651             // Ignore here. Nothing to do currently.
652             // Process of application dead is handled by Window Manager
653             // from binder notification
654         }
655     }
656 }
657
658 void LayerControl::dispatchSurfacePropChangeEvent(unsigned id,
659         struct ilmSurfaceProperties* sprop,
660         t_ilm_notification_mask mask)
661 {
662     /*
663       ILM_NOTIFICATION_CONTENT_AVAILABLE & ILM_NOTIFICATION_CONTENT_REMOVED
664       are not handled here, handled in create/destroy event
665      */
666     if (ILM_NOTIFICATION_VISIBILITY & mask)
667     {
668         HMI_DEBUG("surface %d turns visibility %d", id, sprop->visibility);
669     }
670     if (ILM_NOTIFICATION_OPACITY & mask)
671     {
672         HMI_DEBUG("surface %d turns opacity %f", id, sprop->opacity);
673     }
674     if (ILM_NOTIFICATION_SOURCE_RECT & mask)
675     {
676         HMI_DEBUG("surface %d source rect changes", id);
677     }
678     if (ILM_NOTIFICATION_DEST_RECT & mask)
679     {
680         HMI_DEBUG("surface %d dest rect changes", id);
681     }
682     if (ILM_NOTIFICATION_CONFIGURED & mask)
683     {
684         HMI_DEBUG("surface %d size %d, %d, %d, %d", id,
685             sprop->sourceX, sprop->sourceY, sprop->origSourceWidth, sprop->origSourceHeight);
686         ilm_surfaceSetSourceRectangle(id, 0, 0, sprop->origSourceWidth, sprop->origSourceHeight);
687     }
688 }
689
690 void LayerControl::dispatchLayerPropChangeEvent(unsigned id,
691         struct ilmLayerProperties* lprop,
692         t_ilm_notification_mask mask)
693 {
694     if (ILM_NOTIFICATION_VISIBILITY & mask)
695     {
696         HMI_DEBUG("layer %d turns visibility %d", id, lprop->visibility);
697     }
698     if (ILM_NOTIFICATION_OPACITY & mask)
699     {
700         HMI_DEBUG("layer %d turns opacity %f", id, lprop->opacity);
701     }
702     if (ILM_NOTIFICATION_SOURCE_RECT & mask)
703     {
704         HMI_DEBUG("layer %d source rect changes", id);
705     }
706     if (ILM_NOTIFICATION_DEST_RECT & mask)
707     {
708         HMI_DEBUG("layer %d dest rect changes", id);
709     }
710 }
711
712 WMError LayerControl::makeVisible(const shared_ptr<WMClient> client)
713 {
714     WMError ret = WMError::SUCCESS;
715     // Don't check here the client is not nullptr
716     unsigned layer = client->layerID();
717
718     this->moveForeGround(client);
719
720     ilm_layerSetVisibility(layer, ILM_TRUE);
721
722     /* for(auto& wm_layer : this->wm_layers)
723     {
724         if(wm_layer->hasLayerID(layer))
725         {
726             LayerState ls = wm_layer->getLayerState();
727             ls.addLayer(layer);;
728         }
729     } */
730
731     // Move foreground from back ground layer
732     /* for(auto& wm_layer : this->wm_layers)
733     {
734         if(wm_layer->layerName() == "BackGroundLayer")
735         {
736             if(wm_layer->hasRole(client->role()))
737             {
738                 LayerState ls = wm_layer->getLayerState();
739                 ls.removeLayer(layer);
740             }
741             break;
742         }
743     } */
744
745     return ret;
746 }
747
748 WMError LayerControl::makeInvisible(const shared_ptr<WMClient> client)
749 {
750     WMError ret = WMError::SUCCESS;
751     unsigned layer = client->layerID(); // Don't check here the client is not nullptr
752
753     bool mv_ok = this->moveBackGround(client);
754
755     if(!mv_ok)
756     {
757         HMI_INFO("make invisible client %s", client->appID().c_str());
758         ilm_layerSetVisibility(layer, ILM_FALSE);
759     }
760
761     //ilm_layerSetDestinationRectangle(layer, 0, 0, 0, 0);
762
763     /* for(auto& wm_layer : this->wm_layers)
764     {
765         if(wm_layer->hasLayerID(layer))
766         {
767             LayerState ls = wm_layer->getLayerState();
768             ls.removeLayer(layer);;
769         }
770     } */
771
772
773
774     return ret;
775 }
776
777 WMError LayerControl::makeRemoteVisible(const shared_ptr<WMClient> client)
778 {
779     WMError ret = WMError::SUCCESS;
780     unsigned layer = client->layerID(); // Don't check here the client is not nullptr
781
782     if (0 > this->remoteScreenID)
783     {
784         return ret;
785     }
786
787     // TODO: Currently there is only one remote screen.
788     for (auto itr = this->wm_layers.begin(); itr != this->wm_layers.end(); ++itr)
789     {
790         if((*itr)->hasLayerID(layer))
791         {
792             HMI_DEBUG("Add layer:%d to remote screen:%d", layer, this->remoteScreenID);
793             this->wm_remote_layers.push_back(*itr);
794             this->wm_layers.erase(itr);
795         }
796
797         if (this->wm_layers.end() == itr)
798         {
799             HMI_DEBUG("iteretor indicates end of vector of wm_layers");
800             break;
801         }
802     }
803
804     ilm_layerSetVisibility(layer, ILM_TRUE);
805
806     return ret;
807 }
808
809 WMError LayerControl::makeRemoteInvisible(const shared_ptr<WMClient> client)
810 {
811     WMError ret = WMError::SUCCESS;
812     unsigned layer = client->layerID(); // Don't check here the client is not nullptr
813
814     if (0 > this->remoteScreenID)
815     {
816         return ret;
817     }
818
819     // TODO: Currently there is only one remote screen.
820     for (auto itr = this->wm_remote_layers.begin();
821          itr != this->wm_remote_layers.end(); ++itr)
822     {
823         if((*itr)->hasLayerID(layer))
824         {
825             HMI_DEBUG("Remove layer:%d from remote screen:%d", layer, this->remoteScreenID);
826             this->wm_layers.push_back(*itr);
827             this->wm_remote_layers.erase(itr);
828         }
829
830         if (this->wm_remote_layers.end() == itr)
831         {
832             HMI_DEBUG("iteretor indicates end of vector of wm_remote_layers");
833             break;
834         }
835     }
836
837     ilm_layerSetVisibility(layer, ILM_FALSE);
838
839     return ret;
840 }
841
842 bool LayerControl::moveBackGround(const shared_ptr<WMClient> client)
843 {
844     bool ret = false;
845
846     // Move background from foreground layer
847     auto bg = this->getWMLayer(BACK_GROUND_LAYER);
848     if(bg != nullptr)
849     {
850         HMI_DEBUG("client %s role %s", client->appID().c_str(), client->role().c_str());
851         unsigned layer = client->layerID();
852         if(bg->hasRole(client->role()))
853         {
854             HMI_INFO("%s go to background", client->appID().c_str());
855             bg->addLayerToState(layer);
856             auto wm_layer = this->getWMLayer(layer);
857             wm_layer->removeLayerFromState(layer);
858             /* TODO: manipulate state directly
859             LayerState bg_ls = bg->getLayerState();
860             bg_ls.addLayer(layer);
861             LayerState ls = wm_layer->getLayerState();
862             ls.removeLayer(layer); */
863             bg->dump();
864             wm_layer->dump();
865             ret = true;
866         }
867     }
868     return ret;
869 }
870
871 bool LayerControl::moveForeGround(const shared_ptr<WMClient> client)
872 {
873     bool ret = false;
874
875     // Move foreground from foreground layer
876     auto bg = this->getWMLayer(BACK_GROUND_LAYER);
877     if(bg != nullptr)
878     {
879         if(bg->hasRole(client->role()))
880         {
881             unsigned layer = client->layerID();
882             HMI_INFO("%s go to foreground", client->appID().c_str());
883             bg->removeLayerFromState(layer);
884             auto wm_layer = this->getWMLayer(layer);
885             wm_layer->addLayerToState(layer);
886             /* TODO: manipulate state directly
887             LayerState bg_ls = bg->getLayerState();
888             bg_ls.removeLayer(layer);
889             LayerState ls = wm_layer->getLayerState();
890             ls.addLayer(layer); */
891             bg->dump();
892             wm_layer->dump();
893             ret = true;
894         }
895     }
896     return ret;
897 }
898
899 } // namespace wm