Improve HS_ClientManager and fix issue
[apps/agl-service-homescreen.git] / src / hs-clientmanager.cpp
1 /*
2  * Copyright (c) 2018 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 <algorithm>
17 #include "hs-clientmanager.h"
18 #include "hmi-debug.h"
19
20 HS_ClientManager* HS_ClientManager::me = nullptr;
21
22 static void cbRemoveClientCtxt(void *data)
23 {
24     HS_ClientManager::instance()->removeClientCtxt(data);
25 }
26
27 /**
28  * HS_ClientManager construction function
29  *
30  * #### Parameters
31  *  - Nothing
32  *
33  * #### Return
34  * None
35  *
36  */
37 HS_ClientManager::HS_ClientManager()
38 {
39 }
40
41 /**
42  * get instance
43  *
44  * #### Parameters
45  *  - Nothing
46  *
47  * #### Return
48  * HS_ClientManager instance pointer
49  *
50  */
51 HS_ClientManager* HS_ClientManager::instance(void)
52 {
53     if(me == nullptr)
54         me = new HS_ClientManager();
55
56     return me;
57 }
58
59 /**
60  * HS_ClientManager init function
61  *
62  * #### Parameters
63  *  - Nothing
64  *
65  * #### Return
66  * init result
67  *
68  */
69 int HS_ClientManager::init(void)
70 {
71     HMI_NOTICE("homescreen-service","called.");
72 }
73
74 /**
75  * create client's afb_req_context
76  *
77  * #### Parameters
78  *  - appid: app's id
79  *
80  * #### Return
81  * HS_ClientCtxt pointer
82  *
83  */
84 HS_ClientCtxt* HS_ClientManager::createClientCtxt(afb_req_t req, std::string appid)
85 {
86     HS_ClientCtxt *ctxt = (HS_ClientCtxt *)afb_req_context_get(req);
87     if (!ctxt)
88     {
89         HMI_NOTICE("homescreen-service", "create new session for %s", appid.c_str());
90         HS_ClientCtxt *ctxt = new HS_ClientCtxt(appid.c_str());
91         afb_req_session_set_LOA(req, 1);
92         afb_req_context_set(req, ctxt, cbRemoveClientCtxt);
93     }
94     return ctxt;
95 }
96
97 /**
98  * add Client
99  *
100  * #### Parameters
101  *  - ctxt: app's id
102  *
103  * #### Return
104  * HS_Client pointer
105  *
106  */
107 HS_Client* HS_ClientManager::addClient(afb_req_t req, std::string appid)
108 {
109     return (client_list[appid] = new HS_Client(req, appid));
110 }
111
112 /**
113  * remove Client
114  *
115  * #### Parameters
116  *  - appid: app's id
117  *
118  * #### Return
119  * None
120  *
121  */
122 void HS_ClientManager::removeClient(std::string appid)
123 {
124     delete client_list[appid];
125     client_list.erase(appid);
126 }
127
128 /**
129  * remove Client from list
130  *
131  * #### Parameters
132  *  - data: HS_ClientCtxt pointer
133  *
134  * #### Return
135  * None
136  *
137  */
138 void HS_ClientManager::removeClientCtxt(void *data)
139 {
140     HS_ClientCtxt *ctxt = (HS_ClientCtxt *)data;
141     if(ctxt == nullptr)
142     {
143         HMI_ERROR("homescreen-service", "data is nullptr");
144         return;
145     }
146
147     HMI_NOTICE("homescreen-service", "remove app %s", ctxt->id.c_str());
148     std::lock_guard<std::mutex> lock(this->mtx);
149     removeClient(ctxt->id);
150     delete appid2ctxt[ctxt->id];
151     appid2ctxt.erase(ctxt->id);
152 }
153
154 /**
155  * tap_shortcut
156  *
157  * #### Parameters
158  *  - request: the request to bindings
159  *
160  * #### Return
161  * result
162  *
163  */
164 int HS_ClientManager::tap_shortcut(afb_req_t request)
165 {
166     int ret = 0;
167     const char* value = afb_req_value(request, _application_name);
168     if (value) {
169         HMI_NOTICE("homescreen-service","request params = %s.", value);
170         // first step get appid from appname, next step change appname to appid
171         std::string appid(value);
172         std::transform(appid.begin(), appid.end(), appid.begin(), ::tolower);
173         std::lock_guard<std::mutex> lock(this->mtx);
174         auto ip = client_list.find(appid);
175         if(ip != client_list.end()) {
176             ip->second->tap_shortcut(value);
177         }
178     }
179     else {
180         HMI_NOTICE("homescreen-service","Please input application_name");
181         ret = AFB_EVENT_BAD_REQUEST;
182     }
183     return ret;
184 }
185
186 /**
187  * on_screen_message
188  *
189  * #### Parameters
190  *  - request: the request to bindings
191  *
192  * #### Return
193  * result
194  *
195  */
196 int HS_ClientManager::on_screen_message(afb_req_t request)
197 {
198     int ret = 0;
199     const char* value = afb_req_value(request, _display_message);
200     if (value) {
201         HMI_NOTICE("homescreen-service","request params = %s.", value);
202         std::lock_guard<std::mutex> lock(this->mtx);
203         for(auto m : client_list) {
204             m.second->on_screen_message(request, value);
205         }
206     }
207     else {
208         HMI_NOTICE("homescreen-service","Please input display_message");
209         ret = AFB_EVENT_BAD_REQUEST;
210     }
211     return ret;
212 }
213
214 /**
215  * on_screen_reply
216  *
217  * #### Parameters
218  *  - request: the request to bindings
219  *
220  * #### Return
221  * result
222  *
223  */
224 int HS_ClientManager::on_screen_reply(afb_req_t request)
225 {
226     int ret = 0;
227     const char* value = afb_req_value(request, _reply_message);
228     if (value) {
229       HMI_NOTICE("homescreen-service","request params = %s.", value);
230       std::lock_guard<std::mutex> lock(this->mtx);
231       for(auto m : client_list) {
232         m.second->on_screen_reply(request, value);
233       }
234     }
235     else {
236         HMI_NOTICE("homescreen-service","Please input reply_message");
237         ret = AFB_EVENT_BAD_REQUEST;
238     }
239     return ret;
240 }
241
242 /**
243  * subscribe
244  *
245  * #### Parameters
246  *  - request: the request to bindings
247  *
248  * #### Return
249  * result
250  *
251  */
252 int HS_ClientManager::subscribe(afb_req_t request)
253 {
254     int ret = 0;
255     const char *value = afb_req_value(request, "event");
256     HMI_NOTICE("homescreen-service","value is %s", value);
257     if(value) {
258         std::string appid(afb_req_get_application_id(request));
259         std::transform(appid.begin(), appid.end(), appid.begin(), ::tolower);
260         std::lock_guard<std::mutex> lock(this->mtx);
261
262         HS_Client* client = nullptr;
263         auto ip = client_list.find(appid);
264         if(ip != client_list.end()) {
265             client = client_list[appid];
266         }
267         else {
268             appid2ctxt[appid] = createClientCtxt(request, appid);
269             client = addClient(request, appid);
270         }
271
272         if(client->subscribe(request, value) != 0) {
273             HMI_NOTICE("homescreen-service","subscribe failed");
274             ret = AFB_REQ_SUBSCRIBE_ERROR;
275         }
276     }
277     else {
278         HMI_NOTICE("homescreen-service","Please input event name");
279         ret = AFB_EVENT_BAD_REQUEST;
280     }
281     return ret;
282 }
283
284 /**
285  * unsubscribe
286  *
287  * #### Parameters
288  *  - request: the request to bindings
289  *
290  * #### Return
291  * result
292  *
293  */
294 int HS_ClientManager::unsubscribe(afb_req_t request)
295 {
296     const char *value = afb_req_value(request, "event");
297     HMI_NOTICE("homescreen-service","value is %s", value);
298     int ret = 0;
299     if(value) {
300         std::string appid(afb_req_get_application_id(request));
301         std::transform(appid.begin(), appid.end(), appid.begin(), ::tolower);
302         std::lock_guard<std::mutex> lock(this->mtx);
303
304         auto ip = client_list.find(appid);
305         if(ip != client_list.end()
306         && ip->second->unsubscribe(request, value) != 0) {
307             HMI_NOTICE("homescreen-service","unsubscribe failed");
308             ret = AFB_REQ_UNSUBSCRIBE_ERROR;
309         }
310     }
311     else {
312         HMI_NOTICE("homescreen-service","Please input event name");
313         ret = AFB_EVENT_BAD_REQUEST;
314     }
315     return ret;
316 }