8c13f5fee49870588fe11c6e52ef7fde3a06750c
[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::unique_ptr;
24 using std::vector;
25
26 namespace wm
27 {
28
29 AppList::AppList()
30     : req_list(0),
31       client_list(0),
32       current_seq(1)
33 {
34 }
35
36 AppList::~AppList() {}
37
38 void AppList::addClient(const string &appid, const string &role)
39 {
40     shared_ptr<WMClient> client = std::make_shared<WMClient>(appid, role);
41     client_list[appid] = client;
42     client_dump();
43 }
44
45 void AppList::addClient(const std::string &appid, unsigned layer, unsigned surface, const std::string &role)
46 {
47     shared_ptr<WMClient> client = std::make_shared<WMClient>(appid, layer, surface, role);
48     client_list[appid] = client;
49     client_dump();
50 }
51
52 void AppList::removeClient(const string &appid)
53 {
54     client_list.erase(appid);
55 }
56
57 bool AppList::contains(const string &appid)
58 {
59     auto result = client_list.find(appid);
60     return (client_list.end() != result) ? true : false;
61 }
62
63 void AppList::removeSurface(unsigned surface_id){
64     // This function may be very slow
65     bool ret = false;
66     for (auto &x : client_list)
67     {
68         ret = x.second->removeSurfaceIfExist(surface_id);
69         if(ret){
70             HMI_DEBUG("wm", "remove surface %d from Client %s finish", surface_id, x.second->appID().c_str());
71             break;
72         }
73     }
74 }
75
76 /**
77  * @brief  get WMClient object. Before call this function, must call "contains"
78  * to check the key is contained, otherwise, you have to take care of std::out_of_range.
79  * @param string[in] application id(key)
80  * @return WMClient object
81  */
82 shared_ptr<WMClient> AppList::lookUpClient(const string &appid)
83 {
84     return client_list.at(appid);
85 }
86
87 int AppList::countClient()
88 {
89     return client_list.size();
90 }
91
92 unsigned AppList::currentSequenceNumber()
93 {
94     return current_seq;
95 }
96
97 // Is this function necessary ?
98 unsigned AppList::getSequenceNumber(const string &appid)
99 {
100     for (const auto &x : req_list)
101     {
102         // Since app will not request twice and more, comparing appid is enough?
103         if ((x.trigger.appid == appid))
104         {
105             return x.seq_num;
106         }
107     }
108     return 0;
109 }
110
111 unsigned AppList::addAllocateRequest(WMRequest req)
112 {
113     if (req_list.size() == 0)
114     {
115         req.seq_num = current_seq;
116     }
117     else
118     {
119         HMI_SEQ_DEBUG(current_seq, "real: %d", req_list.back().seq_num + 1);
120         req.seq_num = req_list.back().seq_num + 1;
121     }
122     req_list.push_back(req);
123     return req.seq_num; // return 1; if you test time_expire
124 }
125
126 bool AppList::requestFinished()
127 {
128     return req_list.empty();
129 }
130
131 struct WMTrigger AppList::getRequest(unsigned req_num)
132 {
133     for (auto &x : req_list)
134     {
135         if (req_num == x.seq_num)
136         {
137             return x.trigger;
138         }
139     }
140 }
141
142 const vector<struct WMAction> &AppList::getActions(unsigned req_num)
143 {
144     for (auto &x : req_list)
145     {
146         if (req_num == x.seq_num)
147         {
148             return x.sync_draw_req;
149         }
150     }
151 }
152
153 bool AppList::setAction(unsigned req_num, const struct WMAction &action)
154 {
155     bool result = false;
156     for (auto &x : req_list)
157     {
158         if (req_num != x.seq_num)
159         {
160             continue;
161         }
162         x.sync_draw_req.push_back(action);
163         result = true;
164         break;
165     }
166
167     return result;
168 }
169
170 bool AppList::setAction(unsigned req_num, const string &appid, const string &role, const string &area, bool visible)
171 {
172     bool result = false;
173     for (auto &x : req_list)
174     {
175         if (req_num != x.seq_num)
176         {
177             continue;
178         }
179         WMAction action{appid, role, area, visible, false};
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     req_dump();
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     req_list.erase(remove_if(req_list.begin(), 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_seq;
254     if (0 == this->current_seq)
255     {
256         this->current_seq = 1;
257     }
258 }
259
260 bool AppList::haveRequest()
261 {
262     return !req_list.empty();
263 }
264
265 void AppList::client_dump()
266 {
267     DUMP("======= client dump =====");
268     for (const auto &x : client_list)
269     {
270         const auto &y = x.second;
271         y->dumpInfo();
272     }
273     DUMP("======= client dump end=====");
274 }
275
276 void AppList::req_dump()
277 {
278     DUMP("======= req dump =====");
279     DUMP("current request : %d", current_seq);
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