Add setRole
[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 "hmi-debug.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 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 string WMClient::appID() const
75 {
76     return this->id;
77 }
78
79 unsigned WMClient::surfaceID(const string &role) const
80 {
81     if (0 == this->role2surface.count(role))
82     {
83         return INVALID_SURFACE_ID;
84     }
85     return this->role2surface.at(role);
86 }
87
88 std::string WMClient::role(unsigned surface) const
89 {
90     for(const auto& x : this->role2surface)
91     {
92         if(x.second == surface)
93         {
94             return x.first;
95         }
96     }
97     return std::string("");
98 }
99
100 unsigned WMClient::layerID() const
101 {
102     return this->layer;
103 }
104
105 unsigned WMClient::surfaceID() const
106 {
107     return this->surface;
108 }
109
110 const string& WMClient::getWMLayerName()
111 {
112     return this->wm_layer_name;
113 }
114
115 void WMClient::setRole(const string& role)
116 {
117     this->role_list.push_back(role);
118 }
119
120 /**
121  * Set layerID the client belongs to
122  *
123  * This function set layerID the client belongs to.
124  * But this function may not used because the layer should be fixed at constructor.
125  * So this function will be used to change layer by some reasons.
126  *
127  * @param     unsigned[in] layerID
128  * @return    None
129  * @attention WMClient can't have multiple layer
130  */
131 void WMClient::registerLayer(unsigned layer)
132 {
133     this->layer = layer;
134 }
135
136 /**
137  * Add the pair of role and surface to the client
138  *
139  * This function set the pair of role and surface to the client.
140  * This function is used for the client which has multi surfaces.
141  * If the model and relationship for role and surface(layer)
142  * is changed, this function will be changed
143  * Current Window Manager doesn't use this function.
144  *
145  * @param     string[in] role
146  * @param     unsigned[in] surface
147  * @return    true
148  */
149 bool WMClient::addSurface(const string &role, unsigned surface)
150 {
151     HMI_DEBUG("wm", "Add role %s with surface %d", role.c_str(), surface);
152     if (0 != this->role2surface.count(role))
153     {
154         HMI_NOTICE("wm", "override surfaceID %d with %d", this->role2surface[role], surface);
155     }
156     this->role2surface[role] = surface;
157     return true;
158 }
159
160 bool WMClient::removeSurfaceIfExist(unsigned surface)
161 {
162     bool ret = false;
163     for (auto &x : this->role2surface)
164     {
165         if (surface == x.second)
166         {
167             HMI_INFO("wm", "Remove surface from client %s: role %s, surface: %d",
168                                 this->id.c_str(), x.first.c_str(), x.second);
169             this->role2surface.erase(x.first);
170             ret = true;
171             break;
172         }
173     }
174     return ret;
175 }
176
177 bool WMClient::removeRole(const string &role)
178 {
179     bool ret = false;
180     if (this->role2surface.count(role) != 0)
181     {
182         this->role2surface.erase(role);
183         ret = true;
184     }
185     return ret;
186 }
187
188 #if GTEST_ENABLED
189 bool WMClient::subscribe(afb_req req, const string &evname)
190 {
191     if(evname != kKeyError){
192         HMI_DEBUG("wm", "error is only enabeled for now");
193         return false;
194     }
195     int ret = afb_req_subscribe(req, this->evname2afb_event[evname]);
196     if (ret)
197     {
198         HMI_DEBUG("wm", "Failed to subscribe %s", evname.c_str());
199         return false;
200     }
201     return true;
202 }
203
204 void WMClient::emitError(WM_CLIENT_ERROR_EVENT ev)
205 {
206     if (!afb_event_is_valid(this->evname2afb_event[kKeyError])){
207         HMI_ERROR("wm", "event err is not valid");
208         return;
209     }
210     json_object *j = json_object_new_object();
211     json_object_object_add(j, kKeyError, json_object_new_int(ev));
212     json_object_object_add(j, kKeyErrorDesc, json_object_new_string(kErrorDescription[ev].c_str()));
213     HMI_DEBUG("wm", "error: %d, description:%s", ev, kErrorDescription[ev].c_str());
214
215     int ret = afb_event_push(this->evname2afb_event[kKeyError], j);
216     if (ret != 0)
217     {
218         HMI_DEBUG("wm", "afb_event_push failed: %m");
219     }
220 }
221 #endif
222
223 void WMClient::dumpInfo()
224 {
225     DUMP("APPID : %s", id.c_str());
226     DUMP("  LAYER : %d", layer);
227     for (const auto &x : this->role2surface)
228     {
229         DUMP("  ROLE  : %s , SURFACE : %d", x.first.c_str(), x.second);
230     }
231 }
232
233 } // namespace wm