Fix app surface is set to position (0, 0)
[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), is_source_set(false),
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_t ev = afb_api_make_event(afbBindingV3root, x.c_str());
52 #endif
53         evname2list[x] = ev;
54     }
55 }
56
57 WMClient::WMClient(const string &appid, const string &role)
58     : id(appid),
59       layer(0),
60       is_source_set(false),
61       role2surface(0),
62       evname2list(0)
63 {
64     role2surface[role] = INVALID_SURFACE_ID;
65     for (auto x : kWMEvents)
66     {
67 #if GTEST_ENABLED
68         string ev = x;
69 #else
70         afb_event_t ev = afb_api_make_event(afbBindingV3root, x.c_str());
71 #endif
72         evname2list[x] = ev;
73     }
74 }
75
76 WMClient::WMClient(const string &appid, unsigned layer, const string &role)
77     : id(appid),
78       layer(layer),
79       main_role(role),
80       role2surface(0),
81       evname2list(0)
82 {
83     role2surface[role] = INVALID_SURFACE_ID;
84     for (auto x : kWMEvents)
85     {
86 #if GTEST_ENABLED
87         string ev = x;
88 #else
89         afb_event_t ev = afb_api_make_event(afbBindingV3root, x.c_str());
90 #endif
91         evname2list[x] = ev;
92     }
93 }
94
95 string WMClient::appID() const
96 {
97     return this->id;
98 }
99
100 string WMClient::role() const
101 {
102     return this->main_role;
103 }
104
105 unsigned WMClient::layerID() const
106 {
107     return this->layer;
108 }
109
110 unsigned WMClient::surfaceID() const
111 {
112     return this->surface;
113 }
114
115 void WMClient::registerSurface(unsigned surface)
116 {
117     this->surface = surface;
118 }
119
120 /**
121  * Add surface to the client
122  *
123  * This function add main surface to the client(ivi_layer).
124  *
125  * @param     string[in] role
126  * @return    WMError
127  */
128 WMError WMClient::addSurface(unsigned surface)
129 {
130     this->surface = surface;
131     ilmErrorTypes err = ilm_layerAddSurface(this->layer, surface);
132
133     if(err == ILM_SUCCESS)
134     {
135         err = ilm_commitChanges();
136     }
137     return (err == ILM_SUCCESS) ? WMError::SUCCESS : WMError::FAIL;
138 }
139
140 void WMClient::setSurfaceSizeCorrectly()
141 {
142     this->is_source_set = true;
143 }
144
145 bool WMClient::isSourceSizeSet()
146 {
147     return this->is_source_set;
148 }
149
150 bool WMClient::removeSurfaceIfExist(unsigned surface)
151 {
152     bool ret = false;
153     if(surface == this->surface)
154     {
155         this->surface = INVALID_SURFACE_ID;
156         ret = true;
157     }
158     return ret;
159 }
160
161
162 #if GTEST_ENABLED
163 bool WMClient::subscribe(afb_req_t req, const string &evname)
164 {
165     if(evname != kKeyError){
166         HMI_DEBUG("error is only enabeled for now");
167         return false;
168     }
169     int ret = afb_req_subscribe(req, this->evname2list[evname]);
170     if (ret)
171     {
172         HMI_DEBUG("Failed to subscribe %s", evname.c_str());
173         return false;
174     }
175     return true;
176 }
177
178 void WMClient::emitError(WM_CLIENT_ERROR_EVENT ev)
179 {
180     if (!afb_event_is_valid(this->evname2list[kKeyError])){
181         HMI_ERROR("event err is not valid");
182         return;
183     }
184     json_object *j = json_object_new_object();
185     json_object_object_add(j, kKeyError, json_object_new_int(ev));
186     json_object_object_add(j, kKeyErrorDesc, json_object_new_string(kErrorDescription[ev].c_str()));
187     HMI_DEBUG("error: %d, description:%s", ev, kErrorDescription[ev].c_str());
188
189     int ret = afb_event_push(this->evname2list[kKeyError], j);
190     if (ret != 0)
191     {
192         HMI_DEBUG("afb_event_push failed: %m");
193     }
194 }
195 #endif
196
197 void WMClient::dumpInfo()
198 {
199     DUMP("APPID : %s", id.c_str());
200     DUMP("  LAYER : %d", layer);
201     for (const auto &x : this->role2surface)
202     {
203         DUMP("  ROLE  : %s , SURFACE : %d", x.first.c_str(), x.second);
204     }
205 }
206
207 } // namespace wm