Fix source size 0 sometimes
[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
558     // TO BE FIXED:
559     // Sometimes, ivi_wm_surface_size signal doesn't reach window manager,
560     // then, Window Manager can't set source size.
561     // This fixes it but it takes about 200ns(on R-Car M3) wastefully
562     ilmSurfaceProperties sp;
563     ilm_getPropertiesOfSurface(surface, &sp);
564     if(sp.origSourceHeight != sp.sourceHeight) {
565         HMI_SEQ_NOTICE(action.req_num, "WORK AROUND: set source size w:%d h%d", sp.origSourceWidth, sp.origSourceHeight);
566         ilm_surfaceSetSourceRectangle(surface, 0, 0, sp.origSourceWidth, sp.origSourceHeight);
567         ilm_commitChanges();
568     }
569
570     ilm_surfaceSetDestinationRectangle(surface, rect.x, rect.y, rect.w, rect.h);
571     ilm_commitChanges();
572     for(auto &wm_layer: this->wm_layers)
573     {
574         // Store the state who is assigned to the area
575         if(wm_layer->hasLayerID(layer))
576         {
577             wm_layer->setAreaToState(action.client->appID(), action.area);
578             /* TODO: manipulate state directly
579                LayerState ls = wm_layer->getLayerState();
580                ls.setArea(action.client->appID(), action.area);
581                wm_layer->dump(); */
582         }
583     }
584
585     return WMError::SUCCESS;
586 }
587
588 WMError LayerControl::visibilityChange(const WMAction& action)
589 {
590     WMError ret = WMError::FAIL;
591     if(action.client == nullptr)
592     {
593         HMI_SEQ_ERROR(action.req_num, "client may vanish");
594         return WMError::NOT_REGISTERED;
595     }
596
597     if (action.visible == TaskVisible::VISIBLE)
598     {
599         ret = this->makeVisible(action.client);
600     }
601     else if (action.visible == TaskVisible::INVISIBLE)
602     {
603         ret = this->makeInvisible(action.client);
604     }
605     else if (action.visible == TaskVisible::REMOTE_VISIBLE)
606     {
607         ret = this->makeRemoteVisible(action.client);
608     }
609     else if (action.visible == TaskVisible::REMOTE_INVISIBLE)
610     {
611         ret = this->makeRemoteInvisible(action.client);
612     }
613     else // TaskVisible::REQ_REMOTE_VISIBLE || TaskVisible::REQ_REMOTE_INVISIBLE
614     {
615         // Visibility is not change
616         ret = WMError::SUCCESS;
617     }
618
619     return ret;
620 }
621
622 void LayerControl::terminateApp(const shared_ptr<WMClient> client)
623 {
624     for(auto& l : this->wm_layers)
625     {
626         l->terminateApp(client->layerID());
627     }
628 }
629
630 void LayerControl::dispatchCreateEvent(ilmObjectType object, unsigned id, bool created)
631 {
632     if (ILM_SURFACE == object)
633     {
634         if (created)
635         {
636             ilmSurfaceProperties sp;
637             ilmErrorTypes rc;
638             rc = ilm_getPropertiesOfSurface(id, &sp);
639             if(rc != ILM_SUCCESS)
640             {
641                 HMI_ERROR("Failed to get surface %d property due to %d", id, ilm_getError());
642                 return;
643             }
644             this->cb.surfaceCreated(sp.creatorPid, id);
645             ilm_surfaceSetSourceRectangle(id, 0, 0, sp.origSourceWidth, sp.origSourceHeight);
646             ilm_surfaceAddNotification(id, surfaceCallback_static);
647             ilm_surfaceSetVisibility(id, ILM_TRUE);
648             ilm_surfaceSetType(id, ILM_SURFACETYPE_DESKTOP);
649         }
650         else
651         {
652             this->cb.surfaceDestroyed(id);
653         }
654     }
655     if (ILM_LAYER == object)
656     {
657         if(created)
658         {
659             ilm_layerAddNotification(id, layerCallback_static);
660         }
661         else
662         {
663             // Ignore here. Nothing to do currently.
664             // Process of application dead is handled by Window Manager
665             // from binder notification
666         }
667     }
668 }
669
670 void LayerControl::dispatchSurfacePropChangeEvent(unsigned id,
671         struct ilmSurfaceProperties* sprop,
672         t_ilm_notification_mask mask)
673 {
674     /*
675       ILM_NOTIFICATION_CONTENT_AVAILABLE & ILM_NOTIFICATION_CONTENT_REMOVED
676       are not handled here, handled in create/destroy event
677      */
678     if (ILM_NOTIFICATION_VISIBILITY & mask)
679     {
680         HMI_DEBUG("surface %d turns visibility %d", id, sprop->visibility);
681     }
682     if (ILM_NOTIFICATION_OPACITY & mask)
683     {
684         HMI_DEBUG("surface %d turns opacity %f", id, sprop->opacity);
685     }
686     if (ILM_NOTIFICATION_SOURCE_RECT & mask)
687     {
688         HMI_DEBUG("surface %d source rect changes", id);
689     }
690     if (ILM_NOTIFICATION_DEST_RECT & mask)
691     {
692         HMI_DEBUG("surface %d dest rect changes", id);
693     }
694     if (ILM_NOTIFICATION_CONFIGURED & mask)
695     {
696         HMI_DEBUG("surface %d size %d, %d, %d, %d", id,
697             sprop->sourceX, sprop->sourceY, sprop->origSourceWidth, sprop->origSourceHeight);
698         ilm_surfaceSetSourceRectangle(id, 0, 0, sprop->origSourceWidth, sprop->origSourceHeight);
699     }
700 }
701
702 void LayerControl::dispatchLayerPropChangeEvent(unsigned id,
703         struct ilmLayerProperties* lprop,
704         t_ilm_notification_mask mask)
705 {
706     if (ILM_NOTIFICATION_VISIBILITY & mask)
707     {
708         HMI_DEBUG("layer %d turns visibility %d", id, lprop->visibility);
709     }
710     if (ILM_NOTIFICATION_OPACITY & mask)
711     {
712         HMI_DEBUG("layer %d turns opacity %f", id, lprop->opacity);
713     }
714     if (ILM_NOTIFICATION_SOURCE_RECT & mask)
715     {
716         HMI_DEBUG("layer %d source rect changes", id);
717     }
718     if (ILM_NOTIFICATION_DEST_RECT & mask)
719     {
720         HMI_DEBUG("layer %d dest rect changes", id);
721     }
722 }
723
724 WMError LayerControl::makeVisible(const shared_ptr<WMClient> client)
725 {
726     WMError ret = WMError::SUCCESS;
727     // Don't check here the client is not nullptr
728     unsigned layer = client->layerID();
729
730     this->moveForeGround(client);
731
732     ilm_layerSetVisibility(layer, ILM_TRUE);
733
734     /* for(auto& wm_layer : this->wm_layers)
735     {
736         if(wm_layer->hasLayerID(layer))
737         {
738             LayerState ls = wm_layer->getLayerState();
739             ls.addLayer(layer);;
740         }
741     } */
742
743     // Move foreground from back ground layer
744     /* for(auto& wm_layer : this->wm_layers)
745     {
746         if(wm_layer->layerName() == "BackGroundLayer")
747         {
748             if(wm_layer->hasRole(client->role()))
749             {
750                 LayerState ls = wm_layer->getLayerState();
751                 ls.removeLayer(layer);
752             }
753             break;
754         }
755     } */
756
757     return ret;
758 }
759
760 WMError LayerControl::makeInvisible(const shared_ptr<WMClient> client)
761 {
762     WMError ret = WMError::SUCCESS;
763     unsigned layer = client->layerID(); // Don't check here the client is not nullptr
764
765     bool mv_ok = this->moveBackGround(client);
766
767     if(!mv_ok)
768     {
769         HMI_INFO("make invisible client %s", client->appID().c_str());
770         ilm_layerSetVisibility(layer, ILM_FALSE);
771     }
772
773     //ilm_layerSetDestinationRectangle(layer, 0, 0, 0, 0);
774
775     /* for(auto& wm_layer : this->wm_layers)
776     {
777         if(wm_layer->hasLayerID(layer))
778         {
779             LayerState ls = wm_layer->getLayerState();
780             ls.removeLayer(layer);;
781         }
782     } */
783
784
785
786     return ret;
787 }
788
789 WMError LayerControl::makeRemoteVisible(const shared_ptr<WMClient> client)
790 {
791     WMError ret = WMError::SUCCESS;
792     unsigned layer = client->layerID(); // Don't check here the client is not nullptr
793
794     if (0 > this->remoteScreenID)
795     {
796         return ret;
797     }
798
799     // TODO: Currently there is only one remote screen.
800     for (auto itr = this->wm_layers.begin(); itr != this->wm_layers.end(); ++itr)
801     {
802         if((*itr)->hasLayerID(layer))
803         {
804             HMI_DEBUG("Add layer:%d to remote screen:%d", layer, this->remoteScreenID);
805             this->wm_remote_layers.push_back(*itr);
806             this->wm_layers.erase(itr);
807         }
808
809         if (this->wm_layers.end() == itr)
810         {
811             HMI_DEBUG("iteretor indicates end of vector of wm_layers");
812             break;
813         }
814     }
815
816     ilm_layerSetVisibility(layer, ILM_TRUE);
817
818     return ret;
819 }
820
821 WMError LayerControl::makeRemoteInvisible(const shared_ptr<WMClient> client)
822 {
823     WMError ret = WMError::SUCCESS;
824     unsigned layer = client->layerID(); // Don't check here the client is not nullptr
825
826     if (0 > this->remoteScreenID)
827     {
828         return ret;
829     }
830
831     // TODO: Currently there is only one remote screen.
832     for (auto itr = this->wm_remote_layers.begin();
833          itr != this->wm_remote_layers.end(); ++itr)
834     {
835         if((*itr)->hasLayerID(layer))
836         {
837             HMI_DEBUG("Remove layer:%d from remote screen:%d", layer, this->remoteScreenID);
838             this->wm_layers.push_back(*itr);
839             this->wm_remote_layers.erase(itr);
840         }
841
842         if (this->wm_remote_layers.end() == itr)
843         {
844             HMI_DEBUG("iteretor indicates end of vector of wm_remote_layers");
845             break;
846         }
847     }
848
849     ilm_layerSetVisibility(layer, ILM_FALSE);
850
851     return ret;
852 }
853
854 bool LayerControl::moveBackGround(const shared_ptr<WMClient> client)
855 {
856     bool ret = false;
857
858     // Move background from foreground layer
859     auto bg = this->getWMLayer(BACK_GROUND_LAYER);
860     if(bg != nullptr)
861     {
862         HMI_DEBUG("client %s role %s", client->appID().c_str(), client->role().c_str());
863         unsigned layer = client->layerID();
864         if(bg->hasRole(client->role()))
865         {
866             HMI_INFO("%s go to background", client->appID().c_str());
867             bg->addLayerToState(layer);
868             auto wm_layer = this->getWMLayer(layer);
869             wm_layer->removeLayerFromState(layer);
870             /* TODO: manipulate state directly
871             LayerState bg_ls = bg->getLayerState();
872             bg_ls.addLayer(layer);
873             LayerState ls = wm_layer->getLayerState();
874             ls.removeLayer(layer); */
875             bg->dump();
876             wm_layer->dump();
877             ret = true;
878         }
879     }
880     return ret;
881 }
882
883 bool LayerControl::moveForeGround(const shared_ptr<WMClient> client)
884 {
885     bool ret = false;
886
887     // Move foreground from foreground layer
888     auto bg = this->getWMLayer(BACK_GROUND_LAYER);
889     if(bg != nullptr)
890     {
891         if(bg->hasRole(client->role()))
892         {
893             unsigned layer = client->layerID();
894             HMI_INFO("%s go to foreground", client->appID().c_str());
895             bg->removeLayerFromState(layer);
896             auto wm_layer = this->getWMLayer(layer);
897             wm_layer->addLayerToState(layer);
898             /* TODO: manipulate state directly
899             LayerState bg_ls = bg->getLayerState();
900             bg_ls.removeLayer(layer);
901             LayerState ls = wm_layer->getLayerState();
902             ls.addLayer(layer); */
903             bg->dump();
904             wm_layer->dump();
905             ret = true;
906         }
907     }
908     return ret;
909 }
910
911 } // namespace wm