Add gitlab issue/merge request templates
[apps/agl-service-windowmanager.git] / src / wm_client.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 <json-c/json.h>
18 #include "wm_client.hpp"
19 #include <ilm/ilm_control.h>
20
21 #define INVALID_SURFACE_ID 0
22
23 using std::string;
24 using std::vector;
25
26 namespace wm
27 {
28
29 static const char kActive[] = "active";
30 static const char kInactive[] = "inactive";
31 static const char kVisible[] = "visible";
32 static const char kInvisible[] = "invisible";
33 static const char kSyncDraw[] = "syncDraw";
34 static const char kFlushDraw[] = "flushDraw";
35 static const char kKeyDrawingName[] = "drawing_name";
36 static const char kKeyDrawingArea[] = "drawing_area";
37 static const char kKeyRole[] = "role";
38 static const char kKeyArea[] = "area";
39 static const char kKeyrole[] = "role";
40 static const char kKeyError[] = "error";
41 static const char kKeyErrorDesc[] = "errorDescription";
42 static const char kKeyX[] = "x";
43 static const char kKeyY[] = "y";
44 static const char kKeyWidth[] = "width";
45 static const char kKeyHeight[] = "height";
46 static const char kKeyDrawingRect[] = "drawing-rect";
47
48 static const vector<string> kWMEvents = {
49     // Private event for applications
50     kActive, kInactive,
51     kVisible, kInvisible,
52     kSyncDraw, kFlushDraw,
53     kKeyError};
54
55 WMClient::WMClient(const string &appid, unsigned layer, unsigned surface, const string &role)
56     : id(appid), layer(layer), is_source_set(false),
57       role2surface(0)
58 {
59     role2surface[role] = surface;
60     for (auto x : kWMEvents)
61     {
62 #if GTEST_ENABLED
63         string ev = x;
64 #else
65         afb_event_t ev = afb_api_make_event(afbBindingV3root, x.c_str());
66 #endif
67         evname2afb_event[x] = ev;
68     }
69 }
70
71 WMClient::WMClient(const string &appid, const string &role)
72     : id(appid),
73       layer(0),
74       is_source_set(false),
75       is_active(false),
76       main_role(role),
77       role2surface(0),
78       evname2afb_event(0)
79 {
80     role2surface[role] = INVALID_SURFACE_ID;
81     for (auto x : kWMEvents)
82     {
83 #if GTEST_ENABLED
84         string ev = x;
85 #else
86         afb_event_t ev = afb_api_make_event(afbBindingV3root, x.c_str());
87 #endif
88         evname2afb_event[x] = ev;
89     }
90 }
91
92 WMClient::WMClient(const string &appid, unsigned layer, const string &role)
93     : id(appid),
94       layer(layer),
95       is_source_set(false),
96       is_active(false),
97       main_role(role),
98       role2surface(0),
99       evname2afb_event(0)
100 {
101     role2surface[role] = INVALID_SURFACE_ID;
102     for (auto x : kWMEvents)
103     {
104 #if GTEST_ENABLED
105         string ev = x;
106 #else
107         afb_event_t ev = afb_api_make_event(afbBindingV3root, x.c_str());
108 #endif
109         evname2afb_event[x] = ev;
110     }
111 }
112
113 string WMClient::appID() const
114 {
115     return this->id;
116 }
117
118 string WMClient::role() const
119 {
120     return this->main_role;
121 }
122
123 void WMClient::setRole(const string& role)
124 {
125     this->main_role = role;
126 }
127
128 unsigned WMClient::layerID() const
129 {
130     return this->layer;
131 }
132
133 void WMClient::setLayerID(unsigned id)
134 {
135     this->layer = id;
136 }
137
138 unsigned WMClient::surfaceID() const
139 {
140     return this->surface;
141 }
142
143 void WMClient::registerSurface(unsigned surface)
144 {
145     this->surface = surface;
146 }
147
148 void WMClient::activate()
149 {
150     if(!this->isActive())
151         this->emitActive(true); // emit when state is changed
152     this->is_active = true;
153 }
154
155 void WMClient::deactivate()
156 {
157     if(this->isActive())
158         this->emitActive(false); // emit when state is changed
159     this->is_active = false;
160 }
161
162 /**
163  * Add surface to the client
164  *
165  * This function add main surface to the client(ivi_layer).
166  *
167  * @param     string[in] role
168  * @return    WMError
169  */
170 WMError WMClient::addSurface(unsigned surface)
171 {
172     this->surface = surface;
173     ilmErrorTypes err = ilm_layerAddSurface(this->layer, surface);
174
175     if(err == ILM_SUCCESS)
176     {
177         err = ilm_commitChanges();
178     }
179     return (err == ILM_SUCCESS) ? WMError::SUCCESS : WMError::FAIL;
180 }
181
182 void WMClient::setSurfaceSizeCorrectly()
183 {
184     this->is_source_set = true;
185 }
186
187 bool WMClient::isSourceSizeSet()
188 {
189     return this->is_source_set;
190 }
191
192 bool WMClient::removeSurfaceIfExist(unsigned surface)
193 {
194     bool ret = false;
195     if(surface == this->surface)
196     {
197         this->surface = INVALID_SURFACE_ID;
198         ret = true;
199     }
200     return ret;
201 }
202
203 bool WMClient::subscribe(afb_req_t req, const string &evname)
204 {
205     int ret = afb_req_subscribe(req, this->evname2afb_event[evname]);
206     if (ret)
207     {
208         HMI_DEBUG("Failed to subscribe %s", evname.c_str());
209         return false;
210     }
211     return true;
212 }
213
214 void WMClient::emitVisible(bool visible)
215 {
216     // error check
217     bool allow_send = false;
218     if(visible)
219     {
220         allow_send = afb_event_is_valid(this->evname2afb_event[kVisible]);
221     }
222     else
223     {
224         allow_send = afb_event_is_valid(this->evname2afb_event[kInvisible]);
225     }
226     if(allow_send)
227     {
228         json_object* j = json_object_new_object();
229         json_object_object_add(j, kKeyRole, json_object_new_string(this->role().c_str()));
230         json_object_object_add(j, kKeyDrawingName, json_object_new_string(this->role().c_str()));
231
232         if(visible)
233         {
234             afb_event_push(this->evname2afb_event[kVisible], j);
235         }
236         else
237         {
238             afb_event_push(this->evname2afb_event[kInvisible], j);
239         }
240     }
241     else
242     {
243         HMI_ERROR("Failed to send %s", __func__);
244     }
245 }
246
247 void WMClient::emitActive(bool active)
248 {
249     // error check
250     bool allow_send = false;
251     if(active)
252     {
253         allow_send = afb_event_is_valid(this->evname2afb_event[kActive]);
254     }
255     else
256     {
257         allow_send = afb_event_is_valid(this->evname2afb_event[kInactive]);
258     }
259     if(allow_send)
260     {
261         json_object* j = json_object_new_object();
262         json_object_object_add(j, kKeyRole, json_object_new_string(this->role().c_str()));
263         json_object_object_add(j, kKeyDrawingName, json_object_new_string(this->role().c_str()));
264
265         if(active)
266         {
267             afb_event_push(this->evname2afb_event[kActive], j);
268         }
269         else
270         {
271             afb_event_push(this->evname2afb_event[kInactive], j);
272         }
273     }
274     else
275     {
276         HMI_ERROR("Failed to send %s", __func__);
277     }
278 }
279
280 void WMClient::emitSyncDraw(const string& area, struct rect& r)
281 {
282     HMI_NOTICE("trace");
283     if(afb_event_is_valid(this->evname2afb_event[kSyncDraw]))
284     {
285         json_object *j_rect = json_object_new_object();
286         json_object_object_add(j_rect, kKeyX, json_object_new_int(r.x));
287         json_object_object_add(j_rect, kKeyY, json_object_new_int(r.y));
288         json_object_object_add(j_rect, kKeyWidth, json_object_new_int(r.w));
289         json_object_object_add(j_rect, kKeyHeight, json_object_new_int(r.h));
290
291         json_object* j = json_object_new_object();
292         json_object_object_add(j, kKeyRole, json_object_new_string(this->role().c_str()));
293         json_object_object_add(j, kKeyDrawingName, json_object_new_string(this->role().c_str()));
294         json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area.c_str()));
295         json_object_object_add(j, kKeyArea, json_object_new_string(this->role().c_str()));
296
297         json_object_object_add(j, kKeyDrawingRect, j_rect);
298         afb_event_push(this->evname2afb_event[kSyncDraw], j);
299     }
300     else
301     {
302         HMI_ERROR("Failed to send %s", __func__);
303     }
304 }
305
306 void WMClient::emitFlushDraw()
307 {
308     if(afb_event_is_valid(this->evname2afb_event[kFlushDraw]))
309     {
310         json_object* j = json_object_new_object();
311         json_object_object_add(j, kKeyRole, json_object_new_string(this->role().c_str()));
312         json_object_object_add(j, kKeyDrawingName, json_object_new_string(this->role().c_str()));
313         afb_event_push(this->evname2afb_event[kFlushDraw], nullptr);
314     }
315     else
316     {
317         HMI_ERROR("Failed to send %s", __func__);
318     }
319 }
320
321 void WMClient::emitError(WMError error)
322 {
323     if (!afb_event_is_valid(this->evname2afb_event[kKeyError])){
324         HMI_ERROR("event err is not valid");
325         return;
326     }
327     json_object *j = json_object_new_object();
328     json_object_object_add(j, kKeyError, json_object_new_int(error));
329     json_object_object_add(j, kKeyErrorDesc, json_object_new_string(errorDescription(error)));
330     HMI_DEBUG("error: %d, description:%s", error, errorDescription(error));
331     int ret = afb_event_push(this->evname2afb_event[kKeyError], j);
332     if (ret != 0)
333     {
334         HMI_DEBUG("afb_event_push failed: %m");
335     }
336 }
337
338 void WMClient::dumpInfo()
339 {
340     DUMP("APPID : %s", id.c_str());
341     DUMP("  LAYER : %d", layer);
342     for (const auto &x : this->role2surface)
343     {
344         DUMP("  ROLE  : %s , SURFACE : %d", x.first.c_str(), x.second);
345     }
346 }
347
348 } // namespace wm