84f9842603839be48390f9d0d7a0ec2466f4ceab
[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 #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 string WMClient::role() const
100 {
101     return this->main_role;
102 }
103
104 unsigned WMClient::layerID() const
105 {
106     return this->layer;
107 }
108
109 unsigned WMClient::surfaceID() const
110 {
111     return this->surface;
112 }
113
114 /**
115  * Add surface to the client
116  *
117  * This function add main surface to the client(ivi_layer).
118  *
119  * @param     string[in] role
120  * @return    WMError
121  */
122 WMError WMClient::addSurface(unsigned surface)
123 {
124     this->surface = surface;
125     ilmErrorTypes err = ilm_layerAddSurface(this->layer, surface);
126
127     if(err == ILM_SUCCESS)
128     {
129         err = ilm_commitChanges();
130     }
131     return (err == ILM_SUCCESS) ? WMError::SUCCESS : WMError::FAIL;
132 }
133
134 bool WMClient::removeSurfaceIfExist(unsigned surface)
135 {
136     bool ret = false;
137     if(surface == this->surface)
138     {
139         this->surface = INVALID_SURFACE_ID;
140         ret = true;
141     }
142     return ret;
143 }
144
145 WMError WMClient::setRenderOrder(const vector<string> &order)
146 {
147     WMError ret = WMError::SUCCESS;
148     this->surface_render_order.clear();
149     for(const auto& x : order)
150     {
151         unsigned s; // surface
152         if(x == this->role())
153         {
154             s = this->surfaceID();
155         }
156         else if(this->service2surfaces.count(x) != 0)
157         {
158             s = this->service2surfaces[x];
159         }
160         else
161         {
162             ret = WMError::NOT_REGISTERED;
163             break;
164         }
165         this->surface_render_order.push_back(s);
166     }
167     if(ret == WMError::SUCCESS)
168     {
169         int count = 0;
170         t_ilm_layer* id_array = new t_ilm_surface[this->surface_render_order.size()];
171         if(id_array == nullptr)
172         {
173             HMI_WARNING("short memory");
174             ret = WMError::FAIL;
175         }
176         else
177         {
178             for(const auto& i : this->surface_render_order)
179             {
180                 id_array[count] = i;
181                 ++count;
182             }
183             ilm_layerSetRenderOrder(this->layerID(),
184                 id_array, this->surface_render_order.size());
185             delete id_array;
186         }
187     }
188     return ret;
189 }
190
191 #if GTEST_ENABLED
192 bool WMClient::subscribe(afb_req req, const string &evname)
193 {
194     if(evname != kKeyError){
195         HMI_DEBUG("error is only enabeled for now");
196         return false;
197     }
198     int ret = afb_req_subscribe(req, this->evname2afb_event[evname]);
199     if (ret)
200     {
201         HMI_DEBUG("Failed to subscribe %s", evname.c_str());
202         return false;
203     }
204     return true;
205 }
206
207 void WMClient::emitError(WM_CLIENT_ERROR_EVENT ev)
208 {
209     if (!afb_event_is_valid(this->evname2afb_event[kKeyError])){
210         HMI_ERROR("event err is not valid");
211         return;
212     }
213     json_object *j = json_object_new_object();
214     json_object_object_add(j, kKeyError, json_object_new_int(ev));
215     json_object_object_add(j, kKeyErrorDesc, json_object_new_string(kErrorDescription[ev].c_str()));
216     HMI_DEBUG("error: %d, description:%s", ev, kErrorDescription[ev].c_str());
217
218     int ret = afb_event_push(this->evname2afb_event[kKeyError], j);
219     if (ret != 0)
220     {
221         HMI_DEBUG("afb_event_push failed: %m");
222     }
223 }
224 #endif
225
226 void WMClient::dumpInfo()
227 {
228     DUMP("APPID : %s", id.c_str());
229     DUMP("  LAYER : %d", layer);
230     DUMP("  ROLE  : %s , SURFACE : %d", main_role.c_str(), surface);
231 }
232
233 } // namespace wm