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