Update wm_layer* : Render order change
[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 str;
90     for(const auto& ro : this->render_order)
91     {
92         str += std::to_string(ro);
93         str += ",";
94     }
95     DUMP("    render order : %s", str.c_str());
96 }
97
98 WMLayer::WMLayer(json_object* j, unsigned uuid) : tmp_state(), state(), uuid(uuid)
99 {
100     this->name = jh::getStringFromJson(j, "name");
101     this->role_list = jh::getStringFromJson(j, "role");
102     const char* type = jh::getStringFromJson(j, "type");
103     this->id_begin = static_cast<unsigned>(jh::getIntFromJson(j, "id_range_begin"));
104     this->id_end = static_cast<unsigned>(jh::getIntFromJson(j, "id_range_end"));
105
106     if (name.size() == 0 || !type)
107     {
108         HMI_ERROR("Parse Error!!");
109         exit(1);
110     }
111     if(this->id_begin > this->id_end)
112     {
113         HMI_ERROR("INVALID");
114         exit(1);
115     }
116     string str_type = type;
117     this->type = (str_type == "tile") ? MANAGEMENT_TYPE::TILE : MANAGEMENT_TYPE::STACK;
118 }
119
120 unsigned WMLayer::getNewLayerID(const string& role)
121 {
122     unsigned ret = 0;
123     if(this->name == BG_LAYER_NAME)
124         return ret;
125
126     // generate new layer id;
127     if(this->hasRole(role))
128     {
129         if(this->id_list.size() == 0)
130         {
131             ret = this->idBegin();
132             this->id_list.push_back(ret);
133         }
134         else
135         {
136             ret = this->id_list.back() + 1;
137         }
138         HMI_INFO("Generate new id: %d", ret);
139     }
140     else
141     {
142         return ret;
143     }
144
145     size_t count = std::count(id_list.begin(), id_list.end(), ret);
146     if( (ret > this->idEnd()) || (count > 1))
147     {
148         HMI_NOTICE("id %d is not available then generate new id", ret);
149         ret = 0; // reset
150         for(unsigned i = this->idBegin(); i < this->idEnd(); i++)
151         {
152             auto ret_found = std::find(id_list.begin(), id_list.end(), i);
153             if(ret_found == id_list.cend())
154             {
155                 HMI_INFO("set new id: %d", i);
156                 ret = i;
157                 break;
158             }
159         }
160     }
161
162     if(ret != 0)
163     {
164         id_list.push_back(ret);
165     }
166     else
167     {
168         HMI_ERROR("failed to get New ID");
169     }
170     return ret;
171 }
172
173 const string& WMLayer::layerName()
174 {
175     return this->name;
176 }
177
178 WMError WMLayer::setLayerState(const LayerState& l)
179 {
180     this->tmp_state = l;
181     return WMError::SUCCESS;
182 }
183
184 void WMLayer::addLayerToState(unsigned layer)
185 {
186     this->tmp_state.addLayer(layer);
187 }
188
189 void WMLayer::removeLayerFromState(unsigned layer)
190 {
191     this->tmp_state.removeLayer(layer);
192 }
193
194 void WMLayer::appendArea(const string& area)
195 {
196     this->area_list.push_back(area);
197 }
198
199 void WMLayer::terminateApp(unsigned id)
200 {
201     auto fwd_itr = std::remove_if(this->id_list.begin(), this->id_list.end(),
202         [id](unsigned elm) {
203             return elm == id;
204         });
205     this->id_list.erase(fwd_itr, this->id_list.end());
206     this->tmp_state.removeLayer(id);
207     this->state.removeLayer(id);
208     ilm_layerRemove(id);
209 }
210
211 bool WMLayer::hasLayerID(unsigned id)
212 {
213     bool ret = (id > this->idBegin() && id < this->idEnd());
214     if(!ret)
215         return ret;
216     auto itr = std::find(this->id_list.begin(), this->id_list.end(), id);
217     return (itr != this->id_list.end()) ? true : false;
218 }
219
220 bool WMLayer::hasRole(const string& role)
221 {
222     auto re = std::regex(this->role_list);
223     if (std::regex_match(role, re))
224     {
225         HMI_DEBUG("role %s matches layer %s", role.c_str(), this->name.c_str());
226         return true;
227     }
228     return false;
229 }
230
231 WMError WMLayer::commitChange()
232 {
233     this->state = this->tmp_state;
234     return WMError::SUCCESS;
235 }
236
237 void WMLayer::dump()
238 {
239     DUMP("===== wm layer status =====");
240     DUMP("Layer :%s", this->name.c_str());
241     this->tmp_state.dump();
242     this->state.dump();
243     DUMP("===== wm layer status end =====");
244
245 }
246
247 /* void WMLayer::undo()
248 {
249     this->tmp_state = this->state;
250 }
251  */
252 } // namespace wm