bdb64a99deb1e5878a87cf1dd88d04675907b1ee
[apps/agl-service-windowmanager.git] / src / applist.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 #include <iostream>
17 #include <algorithm>
18 #include "applist.hpp"
19 #include "../include/hmi-debug.h"
20
21 using std::shared_ptr;
22 using std::string;
23 using std::vector;
24
25 namespace wm
26 {
27
28 AppList::AppList()
29     : req_list(0),
30       app2client(0),
31       current_req(1)
32 {
33 }
34
35 AppList::~AppList() {}
36
37 void AppList::addClient(const string &appid, const string &role)
38 {
39     shared_ptr<WMClient> client = std::make_shared<WMClient>(appid, role);
40     this->app2client[appid] = client;
41     this->clientDump();
42 }
43
44 void AppList::addClient(const std::string &appid, unsigned layer, unsigned surface, const std::string &role)
45 {
46     shared_ptr<WMClient> client = std::make_shared<WMClient>(appid, layer, surface, role);
47     this->app2client[appid] = client;
48     this->clientDump();
49 }
50
51 void AppList::removeClient(const string &appid)
52 {
53     this->app2client.erase(appid);
54 }
55
56 bool AppList::contains(const string &appid)
57 {
58     auto result = this->app2client.find(appid);
59     return (this->app2client.end() != result) ? true : false;
60 }
61
62 void AppList::removeSurface(unsigned surface_id){
63     // This function may be very slow
64     bool ret = false;
65     for (auto &x : this->app2client)
66     {
67         ret = x.second->removeSurfaceIfExist(surface_id);
68         if(ret){
69             HMI_DEBUG("wm", "remove surface %d from Client %s finish", surface_id, x.second->appID().c_str());
70             break;
71         }
72     }
73 }
74
75 /**
76  * @brief  get WMClient object. Before call this function, must call "contains"
77  * to check the key is contained, otherwise, you have to take care of std::out_of_range.
78  * @param string[in] application id(key)
79  * @return WMClient object
80  */
81 shared_ptr<WMClient> AppList::lookUpClient(const string &appid)
82 {
83     return this->app2client.at(appid);
84 }
85
86 int AppList::countClient()
87 {
88     return this->app2client.size();
89 }
90
91 unsigned AppList::currentSequenceNumber()
92 {
93     return this->current_req;
94 }
95
96 // Is this function necessary ?
97 unsigned AppList::getSequenceNumber(const string &appid)
98 {
99     for (const auto &x : this->req_list)
100     {
101         // Since app will not request twice and more, comparing appid is enough?
102         if ((x.trigger.appid == appid))
103         {
104             return x.seq_num;
105         }
106     }
107     return 0;
108 }
109
110 unsigned AppList::addAllocateRequest(WMRequest req)
111 {
112     if (this->req_list.size() == 0)
113     {
114         req.seq_num = current_req;
115     }
116     else
117     {
118         HMI_SEQ_DEBUG(this->current_req, "add: %d", this->req_list.back().seq_num + 1);
119         req.seq_num = this->req_list.back().seq_num + 1;
120     }
121     this->req_list.push_back(req);
122     return req.seq_num; // return 1; if you test time_expire
123 }
124
125 bool AppList::requestFinished()
126 {
127     return this->req_list.empty();
128 }
129
130 struct WMTrigger AppList::getRequest(unsigned req_num)
131 {
132     for (auto &x : this->req_list)
133     {
134         if (req_num == x.seq_num)
135         {
136             return x.trigger;
137         }
138     }
139 }
140
141 const vector<struct WMAction> &AppList::getActions(unsigned req_num)
142 {
143     for (auto &x : this->req_list)
144     {
145         if (req_num == x.seq_num)
146         {
147             return x.sync_draw_req;
148         }
149     }
150 }
151
152 bool AppList::setAction(unsigned req_num, const struct WMAction &action)
153 {
154     bool result = false;
155     for (auto &x : this->req_list)
156     {
157         if (req_num != x.seq_num)
158         {
159             continue;
160         }
161         x.sync_draw_req.push_back(action);
162         result = true;
163         break;
164     }
165
166     return result;
167 }
168
169 bool AppList::setAction(unsigned req_num, const string &appid, const string &role, const string &area, bool visible)
170 {
171     bool result = false;
172     for (auto &x : req_list)
173     {
174         if (req_num != x.seq_num)
175         {
176             continue;
177         }
178         bool edraw_f = false;
179         WMAction action{appid, role, area, visible, edraw_f};
180
181         x.sync_draw_req.push_back(action);
182         result = true;
183         break;
184     }
185     return result;
186 }
187
188 bool AppList::setEndDrawFinished(unsigned req_num, const string &appid, const string &role)
189 {
190     bool result = false;
191     for (auto &x : req_list)
192     {
193         if (req_num < x.seq_num)
194         {
195             break;
196         }
197         if (req_num == x.seq_num)
198         {
199             for (auto &y : x.sync_draw_req)
200             {
201                 if (y.appid == appid && y.role == role)
202                 {
203                     y.end_draw_finished = true;
204                     result = true;
205                 }
206             }
207         }
208     }
209     this->reqDump();
210     return result;
211 }
212
213 /**
214  * @brief  check all actions of the requested sequence is finished
215  * @param  unsigned sequence_num
216  * @return true if all action is set.
217  */
218 bool AppList::endDrawFullfilled(unsigned req_num)
219 {
220     bool result = false;
221     for (const auto &x : req_list)
222     {
223         if (req_num < x.seq_num)
224         {
225             break;
226         }
227         if (req_num == x.seq_num)
228         {
229             result = true;
230             for (const auto &y : x.sync_draw_req)
231             {
232                 result &= y.end_draw_finished;
233                 if (!result)
234                 {
235                     break;
236                 }
237             }
238         }
239     }
240     return result;
241 }
242
243 void AppList::removeRequest(unsigned req_seq)
244 {
245     this->req_list.erase(remove_if(this->req_list.begin(), this->req_list.end(),
246                                    [req_seq](WMRequest x) {
247                                        return x.seq_num == req_seq;
248                                    }));
249 }
250
251 void AppList::next()
252 {
253     ++this->current_req;
254     if (0 == this->current_req)
255     {
256         this->current_req = 1;
257     }
258 }
259
260 bool AppList::haveRequest()
261 {
262     return !this->req_list.empty();
263 }
264
265 void AppList::clientDump()
266 {
267     DUMP("======= client dump =====");
268     for (const auto &x : this->app2client)
269     {
270         const auto &y = x.second;
271         y->dumpInfo();
272     }
273     DUMP("======= client dump end=====");
274 }
275
276 void AppList::reqDump()
277 {
278     DUMP("======= req dump =====");
279     DUMP("current request : %d", current_req);
280     for (const auto &x : req_list)
281     {
282         DUMP("requested with  : %d", x.seq_num);
283         DUMP("Trigger : (APPID :%s, ROLE :%s, AREA :%s, TASK: %d)",
284              x.trigger.appid.c_str(),
285              x.trigger.role.c_str(),
286              x.trigger.area.c_str(),
287              x.trigger.task);
288
289         for (const auto &y : x.sync_draw_req)
290         {
291             DUMP(
292                 "Action  : (APPID :%s, ROLE :%s, AREA :%s, END_DRAW_FINISHED: %d)",
293                 y.appid.c_str(),
294                 y.role.c_str(),
295                 y.area.c_str(),
296                 y.end_draw_finished);
297         }
298     }
299     DUMP("======= req dump end =====\n");
300 }
301 } // namespace wm