b3e3d2c3251c4bd53c75c87ad9d14df06de37281
[apps/agl-service-windowmanager-2017.git] / src / wm_layer.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
17 #include <regex>
18 #include <ilm/ilm_control.h>
19 #include <stdlib.h>
20 #include "wm_client.hpp"
21 #include "wm_layer.hpp"
22 #include "json_helper.hpp"
23 #include "util.hpp"
24
25 using std::string;
26 using std::vector;
27 using std::unordered_map;
28
29 #define BG_LAYER_NAME "BackGroundLayer"
30
31 namespace wm
32 {
33
34 LayerState::LayerState()
35     :  render_order(),
36        area2appid()
37 {}
38
39
40 void LayerState::attachIdToArea(const string& area, const WMClient& client)
41 {
42     this->area2appid[area] = client.appID();
43     this->render_order.push_back(client.layerID());
44 }
45
46 const unordered_map<string, string> LayerState::popCurrentState()
47 {
48     unordered_map<string, string> tmp = this->area2appid;
49     this->area2appid.clear();
50     this->render_order.clear();
51     return tmp;
52 }
53
54 const unordered_map<string, string> LayerState::getCurrentState()
55 {
56     return this->area2appid;
57 }
58
59 const vector<unsigned> LayerState::getIviIdList()
60 {
61     return this->render_order;
62 }
63
64 void LayerState::addLayer(unsigned layer)
65 {
66     this->render_order.push_back(layer);
67 }
68
69 void LayerState::removeLayer(unsigned layer)
70 {
71     auto fwd_itr = std::remove_if(
72         this->render_order.begin(), this->render_order.end(),
73         [layer](unsigned elm) {
74             if(elm == layer)
75                 HMI_DEBUG("remove layer %d", elm);
76             return elm == layer;
77         }
78     );
79     this->render_order.erase(fwd_itr, this->render_order.end());
80 }
81
82 void LayerState::setArea(const string& app, const string& area)
83 {
84     this->area2appid[area] = app;
85 }
86
87 void LayerState::dump()
88 {
89     std::string ids, apps;
90     for(const auto& ro : this->render_order)
91     {
92         ids += std::to_string(ro);
93         ids += ",";
94     }
95     for(const auto& area : this->area2appid)
96     {
97         apps += area.first;
98         apps += ":";
99         apps += area.second;
100         apps += ",";
101     }
102     DUMP("    render order : %s", ids.c_str());
103     DUMP("    area, app    : %s", apps.c_str());
104 }
105
106 WMLayer::WMLayer(json_object* j, unsigned uuid) : tmp_state(), state(), uuid(uuid)
107 {
108     this->name = jh::getStringFromJson(j, "name");
109     this->role_list = jh::getStringFromJson(j, "role");
110     const char* type = jh::getStringFromJson(j, "type");
111     this->id_begin = static_cast<unsigned>(jh::getIntFromJson(j, "id_range_begin"));
112     this->id_end = static_cast<unsigned>(jh::getIntFromJson(j, "id_range_end"));
113
114     if (name.size() == 0 || !type)
115     {
116         HMI_ERROR("Parse Error!!");
117         exit(1);
118     }
119     if(this->id_begin > this->id_end)
120     {
121         HMI_ERROR("INVALID");
122         exit(1);
123     }
124     string str_type = type;
125     this->type = (str_type == "tile") ? MANAGEMENT_TYPE::TILE : MANAGEMENT_TYPE::STACK;
126 }
127
128 unsigned WMLayer::getNewLayerID(const string& role)
129 {
130     unsigned ret = 0;
131     if(this->name == BG_LAYER_NAME)
132         return ret;
133
134     // generate new layer id;
135     if(this->hasRole(role))
136     {
137         if(this->id_list.size() == 0)
138         {
139             ret = this->idBegin();
140             this->id_list.push_back(ret);
141         }
142         else
143         {
144             ret = this->id_list.back() + 1;
145         }
146         HMI_INFO("Generate new id: %d", ret);
147     }
148     else
149     {
150         return ret;
151     }
152
153     size_t count = std::count(id_list.begin(), id_list.end(), ret);
154     if( (ret > this->idEnd()) || (count > 1))
155     {
156         HMI_NOTICE("id %d is not available then generate new id", ret);
157         ret = 0; // reset
158         for(unsigned i = this->idBegin(); i < this->idEnd(); i++)
159         {
160             auto ret_found = std::find(id_list.begin(), id_list.end(), i);
161             if(ret_found == id_list.cend())
162             {
163                 HMI_INFO("set new id: %d", i);
164                 ret = i;
165                 break;
166             }
167         }
168     }
169
170     if(ret != 0)
171     {
172         id_list.push_back(ret);
173     }
174     else
175     {
176         HMI_ERROR("failed to get New ID");
177     }
178     return ret;
179 }
180
181 const string& WMLayer::layerName()
182 {
183     return this->name;
184 }
185
186 WMError WMLayer::setLayerState(const LayerState& l)
187 {
188     this->tmp_state = l;
189     return WMError::SUCCESS;
190 }
191
192 void WMLayer::addLayerToState(unsigned layer)
193 {
194     this->tmp_state.addLayer(layer);
195 }
196
197 void WMLayer::removeLayerFromState(unsigned layer)
198 {
199     this->tmp_state.removeLayer(layer);
200 }
201
202 void WMLayer::setAreaToState(const string& app, const string& area)
203 {
204     this->tmp_state.setArea(app, area);
205 }
206
207 void WMLayer::appendArea(const string& area)
208 {
209     this->area_list.push_back(area);
210 }
211
212 void WMLayer::terminateApp(unsigned id)
213 {
214     auto fwd_itr = std::remove_if(this->id_list.begin(), this->id_list.end(),
215         [id](unsigned elm) {
216             return elm == id;
217         });
218     this->id_list.erase(fwd_itr, this->id_list.end());
219     this->tmp_state.removeLayer(id);
220     this->state.removeLayer(id);
221     ilm_layerRemove(id);
222 }
223
224 bool WMLayer::hasLayerID(unsigned id)
225 {
226     bool ret = (id > this->idBegin() && id < this->idEnd());
227     if(!ret)
228         return ret;
229     auto itr = std::find(this->id_list.begin(), this->id_list.end(), id);
230     return (itr != this->id_list.end()) ? true : false;
231 }
232
233 bool WMLayer::hasRole(const string& role)
234 {
235     auto re = std::regex(this->role_list);
236     if (std::regex_match(role, re))
237     {
238         HMI_DEBUG("role %s matches layer %s", role.c_str(), this->name.c_str());
239         return true;
240     }
241     return false;
242 }
243
244 void WMLayer::update()
245 {
246     this->state = this->tmp_state;
247 }
248
249 void WMLayer::undo()
250 {
251     this->tmp_state = this->state;
252 }
253
254 void WMLayer::dump()
255 {
256     DUMP("===== wm layer status =====");
257     DUMP("Layer :%s", this->name.c_str());
258     this->tmp_state.dump();
259     this->state.dump();
260     DUMP("===== wm layer status end =====");
261
262 }
263
264 /* void WMLayer::undo()
265 {
266     this->tmp_state = this->state;
267 }
268  */
269 } // namespace wm