10cc9bccc8a2a76d7334ad674db0760e446ee348
[apps/agl-service-homescreen.git] / src / homescreen.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 #ifndef _GNU_SOURCE
18 #define _GNU_SOURCE
19 #endif
20 #include <memory>
21 #include <algorithm>
22 #include "hs-helper.h"
23 #include "hmi-debug.h"
24 #include "hs-clientmanager.h"
25 #include "hs-appinfo.h"
26
27
28 const char _error[] = "error";
29 const char _application_id[] = "application_id";
30 const char _display_message[] = "display_message";
31 const char _reply_message[] = "reply_message";
32 const char _keyData[] = "data";
33 const char _keyId[] = "id";
34
35 struct hs_instance {
36   HS_ClientManager *client_manager;   // the connection session manager
37   HS_AppInfo *app_info;               // application info
38
39   hs_instance() : client_manager(HS_ClientManager::instance()), app_info(HS_AppInfo::instance()) {}
40   int init(afb_api_t api);
41 };
42
43 /**
44  * init function
45  *
46  * #### Parameters
47  * - api : the api serving the request
48  *
49  * #### Return
50  * 0 : init success
51  * 1 : init fail
52  *
53  */
54 int hs_instance::init(afb_api_t api)
55 {
56     if(client_manager == nullptr) {
57         HMI_ERROR("homescreen-service","FATAL ERROR: client_manager is nullptr.");
58         return -1;
59     }
60     client_manager->init();
61
62     if(app_info == nullptr) {
63         HMI_ERROR("homescreen-service","FATAL ERROR: app_info is nullptr.");
64         return -1;
65     }
66     app_info->init(api);
67
68     return 0;
69 }
70
71 static struct hs_instance *g_hs_instance;
72
73 /*
74 ********** Method of HomeScreen Service (API) **********
75 */
76
77 static void pingSample(afb_req_t request)
78 {
79    static int pingcount = 0;
80    afb_req_success_f(request, json_object_new_int(pingcount), "Ping count = %d", pingcount);
81    HMI_NOTICE("homescreen-service","Verbosity macro at level notice invoked at ping invocation count = %d", pingcount);
82    pingcount++;
83 }
84
85 /**
86  * tap_shortcut notify for homescreen
87  * When Shortcut area is tapped,  notify these applciations
88  *
89  * #### Parameters
90  * Request key
91  * - application_id   : application id
92  *
93  * #### Return
94  * None
95  *
96  */
97 static void tap_shortcut (afb_req_t request)
98 {
99     HMI_NOTICE("homescreen-service","called.");
100     int ret = 0;
101     const char* value = afb_req_value(request, _application_id);
102     if (value) {
103         HMI_NOTICE("homescreen-service","request appid = %s.", value);
104         ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
105         if(ret == AFB_REQ_NOT_STARTED_APPLICATION) {
106             std::string id = g_hs_instance->app_info->getAppProperty(value, _keyId);
107             HS_AfmMainProxy afm_proxy;
108             afm_proxy.start(request, id);
109             ret = 0;
110         }
111     }
112     else {
113         ret = AFB_EVENT_BAD_REQUEST;
114     }
115
116     if (ret) {
117         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
118     }
119     else {
120         struct json_object *res = json_object_new_object();
121         hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
122           _error,  ret);
123         afb_req_success(request, res, "afb_event_push event [tap_shortcut]");
124     }
125 }
126
127 /**
128  * HomeScreen OnScreen message
129  *
130  * #### Parameters
131  * Request key
132  * - display_message   : message for display
133  *
134  * #### Return
135  * None
136  *
137  */
138 static void on_screen_message (afb_req_t request)
139 {
140     HMI_NOTICE("homescreen-service","called.");
141     int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__);
142     if (ret) {
143         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
144     }
145     else {
146         struct json_object *res = json_object_new_object();
147         hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
148           _error,  ret);
149         afb_req_success(request, res, "afb_event_push event [on_screen_message]");
150     }
151 }
152
153 /**
154  * HomeScreen OnScreen Reply
155  *
156  * #### Parameters
157  * Request key
158  * - reply_message   : message for reply
159  *
160  * #### Return
161  * None
162  *
163  */
164 static void on_screen_reply (afb_req_t request)
165 {
166     HMI_NOTICE("homescreen-service","called.");
167     int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__);
168     if (ret) {
169         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
170     }
171     else {
172         struct json_object *res = json_object_new_object();
173         hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
174           _error,  ret);
175         afb_req_success(request, res, "afb_event_push event [on_screen_reply]");
176     }
177 }
178
179 /**
180  * Subscribe event
181  *
182  * #### Parameters
183  *  - event  : Event name. Event list is written in libhomescreen.cpp
184  *
185  * #### Return
186  * None
187  *
188  */
189 static void subscribe(afb_req_t request)
190 {
191     HMI_NOTICE("homescreen-service","called.");
192     int ret = 0;
193     std::string req_appid = std::move(get_application_id(request));
194     if(!req_appid.empty()) {
195         ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, req_appid.c_str());
196     }
197     else {
198         ret = AFB_EVENT_BAD_REQUEST;
199     }
200
201     if(ret) {
202         afb_req_fail_f(request, "afb_req_subscribe failed", "called %s.", __FUNCTION__);
203     }
204     else {
205         struct json_object *res = json_object_new_object();
206         hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
207             _error, ret);
208         afb_req_success_f(request, res, "homescreen binder subscribe.");
209     }
210 }
211
212 /**
213  * Unsubscribe event
214  *
215  * #### Parameters
216  *  - event  : Event name. Event list is written in libhomescreen.cpp
217  *
218  * #### Return
219  * None
220  *
221  */
222 static void unsubscribe(afb_req_t request)
223 {
224     HMI_NOTICE("homescreen-service","called.");
225     int ret = 0;
226     std::string req_appid = std::move(get_application_id(request));
227     if(!req_appid.empty()) {
228         ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, req_appid.c_str());
229     }
230     else {
231         ret = AFB_EVENT_BAD_REQUEST;
232     }
233
234     if(ret) {
235         afb_req_fail_f(request, "afb_req_unsubscribe failed", "called %s.", __FUNCTION__);
236     }
237     else {
238         struct json_object *res = json_object_new_object();
239         hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
240             _error, ret);
241         afb_req_success_f(request, res, "homescreen binder unsubscribe success.");
242     }
243 }
244
245 /**
246  * showWindow event
247  *
248  * #### Parameters
249  *  - request : the request
250  *
251  * #### Return
252  * None
253  *
254  */
255 static void showWindow(afb_req_t request)
256 {
257     HMI_NOTICE("homescreen-service","called.");
258     int ret = 0;
259     const char* value = afb_req_value(request, _application_id);
260     if (value) {
261         ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
262         if(ret == AFB_REQ_NOT_STARTED_APPLICATION) {
263             std::string id = g_hs_instance->app_info->getAppProperty(value, _keyId);
264             HS_AfmMainProxy afm_proxy;
265             afm_proxy.start(request, id);
266             ret = 0;
267         }
268     }
269     else {
270         ret = AFB_EVENT_BAD_REQUEST;
271     }
272
273     if (ret) {
274         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
275     }
276     else {
277         struct json_object *res = json_object_new_object();
278         hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
279           _error,  ret);
280         afb_req_success(request, res, "afb_event_push event [showWindow]");
281     }
282 }
283
284 /**
285  * hideWindow event
286  *
287  * #### Parameters
288  *  - request : the request
289  *
290  * #### Return
291  * None
292  *
293  */
294 static void hideWindow(afb_req_t request)
295 {
296     HMI_NOTICE("homescreen-service","called.");
297     int ret = 0;
298     const char* value = afb_req_value(request, _application_id);
299     if (value) {
300         ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
301     }
302     else {
303         ret = AFB_EVENT_BAD_REQUEST;
304     }
305
306     if (ret) {
307         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
308     }
309     else {
310         struct json_object *res = json_object_new_object();
311         hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
312           _error,  ret);
313         afb_req_success(request, res, "afb_event_push event [hideWindow]");
314     }
315 }
316
317 /**
318  * replyShowWindow event
319  *
320  * #### Parameters
321  *  - request : the request
322  *
323  * #### Return
324  *  None
325  *
326  */
327 static void replyShowWindow(afb_req_t request)
328 {
329     HMI_NOTICE("homescreen-service","called.");
330     int ret = 0;
331     const char* value = afb_req_value(request, _application_id);
332     if (value) {
333         ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
334     }
335     else {
336         ret = AFB_EVENT_BAD_REQUEST;
337     }
338
339     if (ret) {
340         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
341     }
342     else {
343         struct json_object *res = json_object_new_object();
344         hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
345           _error,  ret);
346         afb_req_success(request, res, "afb_event_push event [replyShowWindow]");
347     }
348 }
349
350 /**
351  * showNotification event
352  *
353  * the contents to homescreen which display at top area.
354  *
355  * #### Parameters
356  *  - request : the request
357  *
358  * #### Return
359  * None
360  *
361  */
362 static void showNotification(afb_req_t request)
363 {
364     HMI_NOTICE("homescreen-service","called.");
365     int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, "homescreen");
366     if (ret) {
367         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
368     }
369     else {
370         struct json_object *res = json_object_new_object();
371         hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
372           _error,  ret);
373         afb_req_success(request, res, "afb_event_push event [showNotification]");
374     }
375 }
376
377 /**
378  * showInformation event
379  *
380  * the contents to homescreen which display at bottom area.
381  *
382  * #### Parameters
383  *  - request : the request
384  *
385  * #### Return
386  * None
387  *
388  */
389 static void showInformation(afb_req_t request)
390 {
391     HMI_NOTICE("homescreen-service","called.");
392     int ret = g_hs_instance->client_manager->handleRequest(request,  __FUNCTION__, "homescreen");
393     if (ret) {
394         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
395     }
396     else {
397         struct json_object *res = json_object_new_object();
398         hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
399           _error,  ret);
400         afb_req_success(request, res, "afb_event_push event [showInformation]");
401     }
402 }
403
404 /**
405  * get runnables list
406  *
407  * #### Parameters
408  *  - request : the request
409  *
410  * #### Return
411  * None
412  *
413  */
414 static void getRunnables(afb_req_t request)
415 {
416     HMI_NOTICE("homescreen-service","called.");
417     struct json_object* j_runnable = json_object_new_array();
418     g_hs_instance->app_info->getRunnables(&j_runnable);
419
420     /*create response json object*/
421     struct json_object *res = json_object_new_object();
422     hs_add_object_to_json_object_func(res, __FUNCTION__, 2, _error, 0);
423     json_object_object_add(res, _keyData, j_runnable);
424     afb_req_success_f(request, res, "homescreen binder unsubscribe success.");
425 }
426
427 /*
428  * array of the verbs exported to afb-daemon
429  */
430 static const afb_verb_t verbs[]= {
431     /* VERB'S NAME                 FUNCTION TO CALL                  */
432     { .verb="ping",              .callback=pingSample             },
433     { .verb="tap_shortcut",      .callback=tap_shortcut           },
434     { .verb="showWindow",        .callback=showWindow             },
435     { .verb="hideWindow",        .callback=hideWindow             },
436     { .verb="replyShowWindow",   .callback=replyShowWindow        },
437     { .verb="on_screen_message", .callback=on_screen_message      },
438     { .verb="on_screen_reply",   .callback=on_screen_reply        },
439     { .verb="subscribe",         .callback=subscribe              },
440     { .verb="unsubscribe",       .callback=unsubscribe            },
441     { .verb="showNotification",  .callback=showNotification       },
442     { .verb="showInformation",   .callback=showInformation        },
443     { .verb="getRunnables",      .callback=getRunnables           },
444     {NULL } /* marker for end of the array */
445 };
446
447 /**
448  * homescreen binding preinit function
449  *
450  * #### Parameters
451  *  - api : the api serving the request
452  *
453  * #### Return
454  * None
455  *
456  */
457 static int preinit(afb_api_t api)
458 {
459    HMI_NOTICE("homescreen-service","binding preinit (was register)");
460    return 0;
461 }
462
463 /**
464  * homescreen binding init function
465  *
466  * #### Parameters
467  *  - api : the api serving the request
468  *
469  * #### Return
470  * None
471  *
472  */
473 static int init(afb_api_t api)
474 {
475     HMI_NOTICE("homescreen-service","binding init");
476
477     if(g_hs_instance != nullptr) {
478         HMI_WARNING("homescreen-service", "g_hs_instance isn't null.");
479         delete g_hs_instance->client_manager;
480         delete g_hs_instance->app_info;
481         delete g_hs_instance;
482         g_hs_instance = nullptr;
483     }
484     g_hs_instance = new hs_instance();
485     if(g_hs_instance == nullptr) {
486         HMI_ERROR("homescreen-service", "Fatal Error: new g_hs_instance failed.");
487         return -1;
488     }
489
490     return g_hs_instance->init(api);
491 }
492
493 /**
494  * homescreen binding event function
495  *
496  * #### Parameters
497  *  - api : the api serving the request
498  *  - event  : event name
499  *  - object : event json object
500  *
501  * #### Return
502  * None
503  *
504  */
505 static void onevent(afb_api_t api, const char *event, struct json_object *object)
506 {
507     HMI_NOTICE("homescreen-service","on_event %s", event);
508     g_hs_instance->app_info->onEvent(api, event, object);
509 }
510
511 const afb_binding_t afbBindingExport = {
512     .api = "homescreen",
513     .specification = NULL,
514     .info = NULL,
515     .verbs = verbs,
516     .preinit = preinit,
517     .init = init,
518     .onevent = onevent
519 };