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.
22 #include <unordered_map>
24 #include "hs-helper.h"
25 #include "hs-clientmanager.h"
26 #include "hs-appinfo.h"
29 const char _error[] = "error";
30 const char _application_id[] = "application_id";
31 const char _display_message[] = "display_message";
32 const char _reply_message[] = "reply_message";
33 const char _keyData[] = "data";
34 const char _keyId[] = "id";
35 const char _HS_CONF_JSON[] = "hs-conf.json";
36 const char _LASTMODE_JSON[] = "lastmode.json";
39 struct json_object *hs_conf;
40 struct json_object *lastmode;
42 static struct hs_config g_hs_config;
45 HS_ClientManager *client_manager; // the connection session manager
46 HS_AppInfo *app_info; // application info
48 hs_instance() : client_manager(HS_ClientManager::instance()), app_info(HS_AppInfo::instance()) {}
49 int init(afb_api_t api);
50 void setEventHook(const char *event, const event_hook_func f);
51 void onEvent(afb_api_t api, const char *event, struct json_object *object);
53 std::unordered_map<std::string, std::list<event_hook_func>> event_hook_list;
60 * - api : the api serving the request
67 int hs_instance::init(afb_api_t api)
69 if(client_manager == nullptr) {
70 AFB_ERROR("FATAL ERROR: client_manager is nullptr.");
73 client_manager->init();
75 if(app_info == nullptr) {
76 AFB_ERROR("FATAL ERROR: app_info is nullptr.");
88 * - event : event name
94 void hs_instance::setEventHook(const char *event, const event_hook_func f)
96 if(event == nullptr || f == nullptr) {
97 AFB_WARNING("argument is null.");
101 std::string ev(event);
102 auto it = event_hook_list.find(ev);
103 if(it != event_hook_list.end()) {
104 it->second.push_back(f);
107 std::list<event_hook_func> l;
109 event_hook_list[ev] = std::move(l);
117 * - api : the api serving the request
118 * - event : event name
119 * - object : event json object
124 void hs_instance::onEvent(afb_api_t api, const char *event, struct json_object *object)
126 std::string ev(event);
127 auto it = event_hook_list.find(ev);
128 if(it != event_hook_list.end()) {
129 for(auto &ref : it->second) {
130 if(ref(api, event, object))
136 static struct hs_instance *g_hs_instance;
142 * - event : event name
143 * - f : hook function pointer
148 void setEventHook(const char *event, const event_hook_func f)
150 if(g_hs_instance == nullptr) {
151 AFB_ERROR("g_hs_instance is null.");
155 g_hs_instance->setEventHook(event, f);
159 ********** Method of HomeScreen Service (API) **********
162 static void pingSample(afb_req_t request)
164 static int pingcount = 0;
165 afb_req_success_f(request, json_object_new_int(pingcount), "Ping count = %d", pingcount);
166 AFB_DEBUG("Verbosity macro at level notice invoked at ping invocation count = %d", pingcount);
171 * tap_shortcut notify for homescreen
172 * When Shortcut area is tapped, notify these applciations
176 * - application_id : application id
182 static void tap_shortcut (afb_req_t request)
184 AFB_DEBUG("called.");
186 const char* value = afb_req_value(request, _application_id);
188 AFB_INFO("request appid = %s.", value);
189 ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
190 if(ret == AFB_REQ_NOT_STARTED_APPLICATION) {
191 std::string id = g_hs_instance->app_info->getAppProperty(value, _keyId);
192 HS_AfmMainProxy afm_proxy;
193 afm_proxy.start(request, id);
198 ret = AFB_EVENT_BAD_REQUEST;
202 afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
205 struct json_object *res = json_object_new_object();
206 hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
208 afb_req_success(request, res, "afb_event_push event [tap_shortcut]");
213 * HomeScreen OnScreen message
217 * - display_message : message for display
223 static void on_screen_message (afb_req_t request)
225 AFB_DEBUG("called.");
226 int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__);
228 afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
231 struct json_object *res = json_object_new_object();
232 hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
234 afb_req_success(request, res, "afb_event_push event [on_screen_message]");
239 * HomeScreen OnScreen Reply
243 * - reply_message : message for reply
249 static void on_screen_reply (afb_req_t request)
251 AFB_DEBUG("called.");
252 int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__);
254 afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
257 struct json_object *res = json_object_new_object();
258 hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
260 afb_req_success(request, res, "afb_event_push event [on_screen_reply]");
268 * - event : Event name. Event list is written in libhomescreen.cpp
274 static void subscribe(afb_req_t request)
276 AFB_DEBUG("called.");
278 std::string req_appid = std::move(get_application_id(request));
279 if(!req_appid.empty()) {
280 ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, req_appid.c_str());
283 ret = AFB_EVENT_BAD_REQUEST;
287 afb_req_fail_f(request, "afb_req_subscribe failed", "called %s.", __FUNCTION__);
290 struct json_object *res = json_object_new_object();
291 hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
293 afb_req_success_f(request, res, "homescreen binder subscribe.");
301 * - event : Event name. Event list is written in libhomescreen.cpp
307 static void unsubscribe(afb_req_t request)
309 AFB_DEBUG("called.");
311 std::string req_appid = std::move(get_application_id(request));
312 if(!req_appid.empty()) {
313 ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, req_appid.c_str());
316 ret = AFB_EVENT_BAD_REQUEST;
320 afb_req_fail_f(request, "afb_req_unsubscribe failed", "called %s.", __FUNCTION__);
323 struct json_object *res = json_object_new_object();
324 hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
326 afb_req_success_f(request, res, "homescreen binder unsubscribe success.");
334 * - request : the request
340 static void showWindow(afb_req_t request)
342 AFB_DEBUG("called.");
344 const char* value = afb_req_value(request, _application_id);
346 ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
347 if(ret == AFB_REQ_NOT_STARTED_APPLICATION) {
348 std::string id = g_hs_instance->app_info->getAppProperty(value, _keyId);
349 HS_AfmMainProxy afm_proxy;
350 afm_proxy.start(request, id);
355 ret = AFB_EVENT_BAD_REQUEST;
359 afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
362 struct json_object *res = json_object_new_object();
363 hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
365 afb_req_success(request, res, "afb_event_push event [showWindow]");
373 * - request : the request
379 static void hideWindow(afb_req_t request)
381 AFB_DEBUG("called.");
383 const char* value = afb_req_value(request, _application_id);
385 ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
388 ret = AFB_EVENT_BAD_REQUEST;
392 afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
395 struct json_object *res = json_object_new_object();
396 hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
398 afb_req_success(request, res, "afb_event_push event [hideWindow]");
403 * replyShowWindow event
406 * - request : the request
412 static void replyShowWindow(afb_req_t request)
414 AFB_DEBUG("called.");
416 const char* value = afb_req_value(request, _application_id);
418 ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
421 ret = AFB_EVENT_BAD_REQUEST;
425 afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
428 struct json_object *res = json_object_new_object();
429 hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
431 afb_req_success(request, res, "afb_event_push event [replyShowWindow]");
436 * showNotification event
438 * the contents to homescreen which display at top area.
441 * - request : the request
447 static void showNotification(afb_req_t request)
449 AFB_DEBUG("called.");
450 int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, "homescreen");
452 afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
455 struct json_object *res = json_object_new_object();
456 hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
458 afb_req_success(request, res, "afb_event_push event [showNotification]");
463 * showInformation event
465 * the contents to homescreen which display at bottom area.
468 * - request : the request
474 static void showInformation(afb_req_t request)
476 AFB_DEBUG("called.");
477 int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, "homescreen");
479 afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
482 struct json_object *res = json_object_new_object();
483 hs_add_object_to_json_object_func(res, __FUNCTION__, 2,
485 afb_req_success(request, res, "afb_event_push event [showInformation]");
493 * - request : the request
499 static void getRunnables(afb_req_t request)
501 AFB_DEBUG("called.");
502 struct json_object* j_runnable = json_object_new_array();
503 g_hs_instance->app_info->getRunnables(&j_runnable);
505 /*create response json object*/
506 struct json_object *res = json_object_new_object();
507 hs_add_object_to_json_object_func(res, __FUNCTION__, 2, _error, 0);
508 json_object_object_add(res, _keyData, j_runnable);
509 afb_req_success_f(request, res, "homescreen binder unsubscribe success.");
513 * array of the verbs exported to afb-daemon
515 static const afb_verb_t verbs[]= {
516 /* VERB'S NAME FUNCTION TO CALL */
517 { .verb="ping", .callback=pingSample },
518 { .verb="tap_shortcut", .callback=tap_shortcut },
519 { .verb="showWindow", .callback=showWindow },
520 { .verb="hideWindow", .callback=hideWindow },
521 { .verb="replyShowWindow", .callback=replyShowWindow },
522 { .verb="on_screen_message", .callback=on_screen_message },
523 { .verb="on_screen_reply", .callback=on_screen_reply },
524 { .verb="subscribe", .callback=subscribe },
525 { .verb="unsubscribe", .callback=unsubscribe },
526 { .verb="showNotification", .callback=showNotification },
527 { .verb="showInformation", .callback=showInformation },
528 { .verb="getRunnables", .callback=getRunnables },
529 {NULL } /* marker for end of the array */
533 * homescreen binding preinit function
536 * - api : the api serving the request
542 static int preinit(afb_api_t api)
544 AFB_DEBUG("binding preinit (was register)");
545 auto rootdir = std::string(getenv("AFM_APP_INSTALL_DIR"));
546 auto path = rootdir + "/etc/" + _HS_CONF_JSON;
547 if(readJsonFile(path.c_str(), &g_hs_config.hs_conf) < 0) {
548 AFB_ERROR("read %s failed.", _HS_CONF_JSON);
552 path = rootdir + "/etc/" + _LASTMODE_JSON;
553 if(readJsonFile(path.c_str(), &g_hs_config.lastmode) < 0) {
554 AFB_ERROR("read %s failed.", _LASTMODE_JSON);
561 * homescreen binding init function
564 * - api : the api serving the request
570 static int init(afb_api_t api)
572 AFB_DEBUG("binding init");
574 if(g_hs_instance != nullptr) {
575 AFB_WARNING( "g_hs_instance isn't null.");
576 delete g_hs_instance->client_manager;
577 delete g_hs_instance->app_info;
578 delete g_hs_instance;
579 g_hs_instance = nullptr;
581 g_hs_instance = new hs_instance();
582 if(g_hs_instance == nullptr) {
583 AFB_ERROR( "Fatal Error: new g_hs_instance failed.");
587 return g_hs_instance->init(api);
591 * homescreen binding event function
594 * - api : the api serving the request
595 * - event : event name
596 * - object : event json object
602 static void onevent(afb_api_t api, const char *event, struct json_object *object)
604 AFB_INFO("on_event %s", event);
605 g_hs_instance->onEvent(api, event, object);
608 const afb_binding_t afbBindingExport = {
610 .specification = NULL,