Return WMError instead of bool
[apps/agl-service-windowmanager-2017.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 "util.hpp"
20 #include <ilm/ilm_control.h>
21
22 #define INVALID_SURFACE_ID 0
23
24 using std::string;
25 using std::vector;
26
27 namespace wm
28 {
29
30 static const vector<string> kWMEvents = {
31     // Private event for applications
32     "syncDraw", "flushDraw", "visible", "invisible", "active", "inactive", "error"};
33 static const vector<string> kErrorDescription = {
34     "unknown-error"};
35
36 static const char kKeyDrawingName[] = "drawing_name";
37 static const char kKeyrole[] = "role";
38 static const char kKeyError[] = "error";
39 static const char kKeyErrorDesc[] = "kErrorDescription";
40
41 WMClient::WMClient(const string &appid, unsigned layer, unsigned surface, const string &role)
42     : id(appid), layer(layer),
43       role2surface(0)
44 {
45     role2surface[role] = surface;
46     for (auto x : kWMEvents)
47     {
48 #if GTEST_ENABLED
49         string ev = x;
50 #else
51         afb_event ev = afb_daemon_make_event(x.c_str());
52 #endif
53         evname2afb_event[x] = ev;
54     }
55 }
56
57 WMClient::WMClient(const string &appid, const string &role)
58     : id(appid),
59       layer(0),
60       role2surface(0),
61       evname2afb_event(0)
62 {
63     role2surface[role] = INVALID_SURFACE_ID;
64     for (auto x : kWMEvents)
65     {
66 #if GTEST_ENABLED
67         string ev = x;
68 #else
69         afb_event ev = afb_daemon_make_event(x.c_str());
70 #endif
71         evname2afb_event[x] = ev;
72     }
73 }
74
75 WMClient::WMClient(const string &appid, unsigned layer, const string &role)
76     : id(appid),
77       layer(layer),
78       main_role(role),
79       role2surface(0),
80       evname2afb_event(0)
81 {
82     role2surface[role] = INVALID_SURFACE_ID;
83     for (auto x : kWMEvents)
84     {
85 #if GTEST_ENABLED
86         string ev = x;
87 #else
88         afb_event ev = afb_daemon_make_event(x.c_str());
89 #endif
90         evname2afb_event[x] = ev;
91     }
92 }
93
94 string WMClient::appID() const
95 {
96     return this->id;
97 }
98
99 unsigned WMClient::surfaceID(const string &role) const
100 {
101     if (0 == this->role2surface.count(role))
102     {
103         return INVALID_SURFACE_ID;
104     }
105     return this->role2surface.at(role);
106 }
107
108 std::string WMClient::role(unsigned surface) const
109 {
110     for(const auto& x : this->role2surface)
111     {
112         if(x.second == surface)
113         {
114             return x.first;
115         }
116     }
117     return std::string("");
118 }
119
120 string WMClient::role() const
121 {
122     return this->main_role;
123 }
124
125 unsigned WMClient::layerID() const
126 {
127     return this->layer;
128 }
129
130 unsigned WMClient::surfaceID() const
131 {
132     return this->surface;
133 }
134
135 void WMClient::setRole(const string& role)
136 {
137     this->role_list.clear();
138     this->role_list.push_back(role);
139 }
140
141 void WMClient::appendRole(const string& role)
142 {
143     this->role_list.push_back(role);
144 }
145
146 /**
147  * Add the pair of role and surface to the client
148  *
149  * This function set the pair of role and surface to the client.
150  * This function is used for the client which has multi surfaces.
151  * If the model and relationship for role and surface(layer)
152  * is changed, this function will be changed
153  * Current Window Manager doesn't use this function.
154  *
155  * @param     string[in] role
156  * @param     unsigned[in] surface
157  * @return    true
158  */
159 /* bool WMClient::addSurface(const string &role, unsigned surface)
160 {
161     HMI_DEBUG("Add role %s with surface %d", role.c_str(), surface);
162     if (0 != this->role2surface.count(role))
163     {
164         HMI_NOTICE("override surfaceID %d with %d", this->role2surface[role], surface);
165     }
166     this->role2surface[role] = surface;
167     return true;
168 } */
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 bool WMClient::removeSurfaceIfExist(unsigned surface)
183 {
184     bool ret = false;
185     if(surface == this->surface)
186     {
187         this->surface = INVALID_SURFACE_ID;
188         return true;
189     }
190     for (auto &x : this->role2surface)
191     {
192         if (surface == x.second)
193         {
194             HMI_INFO("Remove surface from client %s: role %s, surface: %d",
195                                 this->id.c_str(), x.first.c_str(), x.second);
196             this->role2surface.erase(x.first);
197             ret = true;
198             break;
199         }
200     }
201     return ret;
202 }
203
204 bool WMClient::removeRole(const string &role)
205 {
206     bool ret = false;
207     if (this->role2surface.count(role) != 0)
208     {
209         this->role2surface.erase(role);
210         ret = true;
211     }
212     return ret;
213 }
214
215 #if GTEST_ENABLED
216 bool WMClient::subscribe(afb_req req, const string &evname)
217 {
218     if(evname != kKeyError){
219         HMI_DEBUG("error is only enabeled for now");
220         return false;
221     }
222     int ret = afb_req_subscribe(req, this->evname2afb_event[evname]);
223     if (ret)
224     {
225         HMI_DEBUG("Failed to subscribe %s", evname.c_str());
226         return false;
227     }
228     return true;
229 }
230
231 void WMClient::emitError(WM_CLIENT_ERROR_EVENT ev)
232 {
233     if (!afb_event_is_valid(this->evname2afb_event[kKeyError])){
234         HMI_ERROR("event err is not valid");
235         return;
236     }
237     json_object *j = json_object_new_object();
238     json_object_object_add(j, kKeyError, json_object_new_int(ev));
239     json_object_object_add(j, kKeyErrorDesc, json_object_new_string(kErrorDescription[ev].c_str()));
240     HMI_DEBUG("error: %d, description:%s", ev, kErrorDescription[ev].c_str());
241
242     int ret = afb_event_push(this->evname2afb_event[kKeyError], j);
243     if (ret != 0)
244     {
245         HMI_DEBUG("afb_event_push failed: %m");
246     }
247 }
248 #endif
249
250 void WMClient::dumpInfo()
251 {
252     DUMP("APPID : %s", id.c_str());
253     DUMP("  LAYER : %d", layer);
254     for (const auto &x : this->role2surface)
255     {
256         DUMP("  ROLE  : %s , SURFACE : %d", x.first.c_str(), x.second);
257     }
258 }
259
260 } // namespace wm