2 * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "applist.hpp"
19 #include "../include/hmi-debug.h"
21 using std::shared_ptr;
25 const static int kReserveReqSize = 10;
26 const static int kReserveCLSize = 100;
34 req_list.reserve(kReserveReqSize);
35 app2client.reserve(kReserveCLSize);
38 void AppList::addClient(const string &appid, const string &role)
40 shared_ptr<WMClient> client = std::make_shared<WMClient>(appid, role);
41 this->app2client[appid] = client;
45 void AppList::addClient(const std::string &appid, unsigned layer, unsigned surface, const std::string &role)
47 shared_ptr<WMClient> client = std::make_shared<WMClient>(appid, layer, surface, role);
48 this->app2client[appid] = client;
52 void AppList::removeClient(const string &appid)
54 this->app2client.erase(appid);
57 bool AppList::contains(const string &appid) const
59 auto result = this->app2client.find(appid);
60 return (this->app2client.end() != result) ? true : false;
63 void AppList::removeSurface(unsigned surface_id){
64 // This function may be very slow
66 for (int i = 0; i < 1000; i++)
69 for (auto &x : this->app2client)
71 HMI_DEBUG("wm", "app: %s", x.second->appID());
72 ret = x.second->removeSurfaceIfExist(surface_id);
74 HMI_DEBUG("wm", "remove surface %d from Client %s finish", surface_id, x.second->appID().c_str());
81 * @brief get WMClient object. Before call this function, must call "contains"
82 * to check the key is contained, otherwise, you have to take care of std::out_of_range.
83 * @param string[in] application id(key)
84 * @return WMClient object
86 shared_ptr<WMClient> AppList::lookUpClient(const string &appid)
88 return this->app2client.at(appid);
91 int AppList::countClient() const
93 return this->app2client.size();
96 unsigned AppList::currentRequestNumber() const
98 return this->current_req;
101 WMError AppList::popFloatingSurface(unsigned pid, unsigned *surface)
103 WMError ret = WMError::NO_ENTRY;
105 auto fwd_itr = std::remove_if(this->floating_surfaces.begin(), this->floating_surfaces.end(),
106 [pid, surface, &ret](FloatingSurface x) {
108 *surface = x.surface_id;
109 ret = WMError::SUCCESS;
116 if (fwd_itr != this->floating_surfaces.cend())
118 HMI_INFO("wm", "pop floating surface: %d", *surface);
120 this->floating_surfaces.erase(fwd_itr, this->floating_surfaces.end());
124 WMError AppList::popFloatingSurface(const std::string &appid, unsigned *surface)
126 HMI_ERROR("wm", "This function is not implemented");
127 return WMError::SUCCESS;
130 void AppList::addFloatingClient(const std::string &appid, unsigned layer, const std::string &role)
134 void AppList::addFloatingSurface(unsigned surface, unsigned pid)
136 struct FloatingSurface fsurface{surface, pid};
137 this->floating_surfaces.push_back(fsurface);
138 this->dumpFloatingSurfaces();
141 void AppList::removeFloatingSurface(unsigned surface)
143 this->dumpFloatingSurfaces();
144 auto fwd_itr = std::remove_if(this->floating_surfaces.begin(), this->floating_surfaces.end(),
145 [surface](FloatingSurface x) {
146 return x.surface_id == surface;
148 if(fwd_itr != this->floating_surfaces.cend()){
149 HMI_INFO("wm", "remove floating surface: %d", surface);
151 this->floating_surfaces.erase(fwd_itr, this->floating_surfaces.end());
154 WMError AppList::appendRole(const std::string &id, const std::string &role, unsigned surface)
156 WMError wm_err = WMError::NO_ENTRY;
157 if (this->contains(id))
159 auto x = this->lookUpClient(id);
160 x->addSurface(role, surface);
161 wm_err = WMError::SUCCESS;
166 unsigned AppList::getRequestNumber(const string &appid) const
168 for (const auto &x : this->req_list)
170 // Since app will not request twice and more, comparing appid is enough?
171 if ((x.trigger.appid == appid))
179 unsigned AppList::addAllocateRequest(WMRequest req)
181 if (this->req_list.size() == 0)
183 req.req_num = current_req;
187 HMI_SEQ_DEBUG(this->current_req, "add: %d", this->req_list.back().req_num + 1);
188 req.req_num = this->req_list.back().req_num + 1;
190 this->req_list.push_back(req);
191 return req.req_num; // return 1; if you test time_expire
194 struct WMTrigger AppList::getRequest(unsigned req_num, bool *found)
197 for (const auto &x : this->req_list)
199 if (req_num == x.req_num)
205 return WMTrigger{"", "", "", Task::TASK_INVALID};
208 const vector<struct WMAction> &AppList::getActions(unsigned req_num, bool* found)
211 for (auto &x : this->req_list)
213 if (req_num == x.req_num)
216 return x.sync_draw_req;
221 WMError AppList::setAction(unsigned req_num, const struct WMAction &action)
223 WMError result = WMError::FAIL;
224 for (auto &x : this->req_list)
226 if (req_num != x.req_num)
230 x.sync_draw_req.push_back(action);
231 result = WMError::SUCCESS;
240 * This function set action with parameters.
241 * if visible is true, it means app should be visible, so enddraw_finished parameter should be false.
242 * otherwise (visible is false) app should be invisible. Then enddraw_finished param is set to true.
243 * This function doesn't support actions for focus yet.
245 WMError AppList::setAction(unsigned req_num, const string &appid, const string &role, const string &area, bool visible)
247 WMError result = WMError::NOT_REGISTERED;
248 for (auto &x : req_list)
250 if (req_num != x.req_num)
254 bool edraw_f = (visible) ? false : true;
255 WMAction action{appid, role, area, visible, edraw_f};
257 x.sync_draw_req.push_back(action);
258 result = WMError::SUCCESS;
265 * This function checks
266 * * req_num is equal to current request number
267 * * appid and role are equeal to the appid and role stored in action list(sync_draw_req)
269 bool AppList::setEndDrawFinished(unsigned req_num, const string &appid, const string &role)
272 for (auto &x : req_list)
274 if (req_num < x.req_num)
278 if (req_num == x.req_num)
280 for (auto &y : x.sync_draw_req)
282 if (y.appid == appid && y.role == role)
284 y.end_draw_finished = true;
295 * @brief check all actions of the requested sequence is finished
296 * @param unsigned request_number
297 * @return true if all action is set.
299 bool AppList::endDrawFullfilled(unsigned req_num)
302 for (const auto &x : req_list)
304 if (req_num < x.req_num)
308 if (req_num == x.req_num)
311 for (const auto &y : x.sync_draw_req)
313 result &= y.end_draw_finished;
324 void AppList::removeRequest(unsigned req_num)
326 this->req_list.erase(remove_if(this->req_list.begin(), this->req_list.end(),
327 [req_num](WMRequest x) {
328 return x.req_num == req_num;
335 if (0 == this->current_req)
337 this->current_req = 1;
341 bool AppList::haveRequest() const
343 return !this->req_list.empty();
346 void AppList::clientDump()
348 DUMP("======= client dump =====");
349 for (const auto &x : this->app2client)
351 const auto &y = x.second;
354 DUMP("======= client dump end=====");
357 void AppList::reqDump()
359 DUMP("======= req dump =====");
360 DUMP("current request : %d", current_req);
361 for (const auto &x : req_list)
363 DUMP("requested with : %d", x.req_num);
364 DUMP("Trigger : (APPID :%s, ROLE :%s, AREA :%s, TASK: %d)",
365 x.trigger.appid.c_str(),
366 x.trigger.role.c_str(),
367 x.trigger.area.c_str(),
370 for (const auto &y : x.sync_draw_req)
373 "Action : (APPID :%s, ROLE :%s, AREA :%s, END_DRAW_FINISHED: %d)",
377 y.end_draw_finished);
380 DUMP("======= req dump end =====\n");
383 void AppList::dumpFloatingSurfaces()
385 DUMP("======= floating surface dump =====");
386 for (const auto &x : this->floating_surfaces)
388 DUMP("surface : %d, pid : %d", x.surface_id, x.pid);
390 DUMP("======= floating surface dump end =====\n");