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