01e8950ab686780765ca296446789e56946cae5f
[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             return elm == layer;
75         }
76     );
77     this->render_order.erase(fwd_itr, this->render_order.end());
78 }
79
80 void LayerState::setArea(const string& app, const string& area)
81 {
82     this->area2appid[area] = app;
83 }
84
85 WMLayer::WMLayer(json_object* j, unsigned uuid) : tmp_state(), state(), uuid(uuid)
86 {
87     this->name = jh::getStringFromJson(j, "name");
88     this->role_list = jh::getStringFromJson(j, "role");
89     const char* type = jh::getStringFromJson(j, "type");
90     this->id_begin = static_cast<unsigned>(jh::getIntFromJson(j, "id_range_begin"));
91     this->id_end = static_cast<unsigned>(jh::getIntFromJson(j, "id_range_end"));
92
93     if (name.size() == 0 || !type)
94     {
95         HMI_ERROR("Parse Error!!");
96         exit(1);
97     }
98     if(this->id_begin > this->id_end)
99     {
100         HMI_ERROR("INVALID");
101         exit(1);
102     }
103     string str_type = type;
104     this->type = (str_type == "tile") ? MANAGEMENT_TYPE::TILE : MANAGEMENT_TYPE::STACK;
105 }
106
107 unsigned WMLayer::getNewLayerID(const string& role)
108 {
109     unsigned ret = 0;
110
111     // generate new layer id;
112     if(this->hasRole(role))
113     {
114         if(this->id_list.size() == 0)
115         {
116             ret = this->idBegin();
117             this->id_list.push_back(ret);
118         }
119         else
120         {
121             ret = this->id_list.back() + 1;
122         }
123         HMI_INFO("Generate new id: %d", ret);
124     }
125     else
126     {
127         return ret;
128     }
129
130     auto id_found = std::find(id_list.begin(), id_list.end(), ret);
131     if( (ret > this->idEnd()) || (id_found != id_list.cend()) )
132     {
133         HMI_NOTICE("id %d is not available then generate new id", ret);
134         ret = 0; // reset
135         for(unsigned i = this->idBegin(); i < this->idEnd(); i++)
136         {
137             auto ret_found = std::find(id_list.begin(), id_list.end(), i);
138             if(ret_found == id_list.cend())
139             {
140                 HMI_INFO("set new id: %d", i);
141                 ret = i;
142                 break;
143             }
144         }
145     }
146
147     if(ret != 0)
148     {
149         id_list.push_back(ret);
150     }
151     else
152     {
153         HMI_ERROR("failed to get New ID");
154     }
155     return ret;
156 }
157
158 const string& WMLayer::layerName()
159 {
160     return this->name;
161 }
162
163 WMError WMLayer::setLayerState(const LayerState& l)
164 {
165     this->tmp_state = l;
166     return WMError::SUCCESS;
167 }
168
169 void WMLayer::addLayer(unsigned layer)
170 {
171     this->tmp_state.addLayer(layer);
172 }
173
174 void WMLayer::appendArea(const string& area)
175 {
176     this->area_list.push_back(area);
177 }
178
179 void WMLayer::removeLayerID(unsigned id)
180 {
181     auto fwd_itr = std::remove_if(this->id_list.begin(), this->id_list.end(),
182         [id](unsigned elm) {
183             return elm == id;
184         });
185     this->id_list.erase(fwd_itr, this->id_list.end());
186 }
187
188 bool WMLayer::hasLayerID(unsigned id)
189 {
190     bool ret = (id > this->idBegin() && id < this->idEnd());
191     if(!ret)
192         return ret;
193     auto itr = std::find(this->id_list.begin(), this->id_list.end(), id);
194     return (itr != this->id_list.end()) ? true : false;
195 }
196
197 bool WMLayer::hasRole(const string& role)
198 {
199     // TODO : use virtual to avoid compare
200     if(this->name == BG_LAYER_NAME)
201         return false;
202     auto re = std::regex(this->role_list);
203     if (std::regex_match(role, re))
204     {
205         HMI_DEBUG("role %s matches layer %s", role.c_str(), this->name.c_str());
206         return true;
207     }
208     return false;
209 }
210
211 WMError WMLayer::commitChange()
212 {
213     this->state = this->tmp_state;
214     return WMError::SUCCESS;
215 }
216
217 /* void WMLayer::undo()
218 {
219     this->tmp_state = this->state;
220 }
221  */
222 } // namespace wm