diff options
-rw-r--r-- | conf/hs-conf.json | 12 | ||||
-rw-r--r-- | package/root/config.xml | 2 | ||||
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/homescreen.cpp | 34 | ||||
-rw-r--r-- | src/hs-appinfo.cpp | 3 | ||||
-rw-r--r-- | src/hs-apprecover.cpp | 26 | ||||
-rw-r--r-- | src/hs-apprecover.h | 7 | ||||
-rw-r--r-- | src/hs-client.cpp | 13 | ||||
-rw-r--r-- | src/hs-clientmanager.cpp | 133 | ||||
-rw-r--r-- | src/hs-clientmanager.h | 30 | ||||
-rw-r--r-- | src/hs-helper.cpp | 4 | ||||
-rw-r--r-- | src/hs-proxy.cpp | 39 | ||||
-rw-r--r-- | src/hs-proxy.h | 9 | ||||
-rw-r--r-- | src/hs-vuiadapter.cpp | 308 | ||||
-rw-r--r-- | src/hs-vuiadapter.h | 77 |
15 files changed, 628 insertions, 72 deletions
diff --git a/conf/hs-conf.json b/conf/hs-conf.json index 6defefd..ec0835e 100644 --- a/conf/hs-conf.json +++ b/conf/hs-conf.json @@ -13,23 +13,11 @@ "appid": "launcher", "visibility": "visible", "after": "homescreen" - }, - { - "appid": "restriction", - "visibility": "invisible" } ], "default-lastmode": [ ], "normal-apps": [ - { - "appid": "navigation", - "visibility": "invisible" - }, - { - "appid": "tbtnavi", - "visibility": "invisible" - } ] } } diff --git a/package/root/config.xml b/package/root/config.xml index 38c1258..3501b7c 100644 --- a/package/root/config.xml +++ b/package/root/config.xml @@ -13,6 +13,7 @@ <param name="urn:AGL:permission:afm:system:widget" value="required" /> <param name="urn:AGL:permission:afm:system:runner" value="required" /> <param name="urn:AGL:permission:afm:system:widget:start" value="required" /> + <param name="urn:AGL:permission:vshl-capabilities:navigation:public" value="required" /> </feature> <feature name="urn:AGL:widget:provided-api"> <param name="homescreen" value="ws" /> @@ -20,6 +21,7 @@ <feature name="urn:AGL:widget:required-api"> <param name="afm-main" value="ws" /> <param name="windowmanager" value="ws" /> + <param name="vshl-capabilities" value="ws" /> </feature> <feature name="urn:AGL:widget:required-binding"> <param name="lib/homescreen-service.so" value="local" /> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 21cbf49..b8e558d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,7 +30,8 @@ set(binding_hs_sources hs-proxy.cpp hs-appinfo.cpp hs-config.cpp - hs-apprecover.cpp) + hs-apprecover.cpp + hs-vuiadapter.cpp) link_libraries(-Wl,--as-needed -Wl,--gc-sections -Wl,--no-undefined) include_directories(${PROJECT_SOURCE_DIR}/include) diff --git a/src/homescreen.cpp b/src/homescreen.cpp index cff2810..d9fef91 100644 --- a/src/homescreen.cpp +++ b/src/homescreen.cpp @@ -28,7 +28,7 @@ #include "hs-appinfo.h" #include "hs-config.h" #include "hs-apprecover.h" - +#include "hs-vuiadapter.h" const char _error[] = "error"; @@ -163,9 +163,10 @@ void hs_handshake::handshake_loop(afb_api_t api, int times, int sleeps) struct hs_instance { HS_ClientManager *client_manager; // the connection session manager HS_AppInfo *app_info; // application info - HS_AppRecover *app_recover; + HS_AppRecover *app_recover; // application recover + HS_VuiAdapter * vui_adapter; // vui function adapter - hs_instance() : client_manager(HS_ClientManager::instance()), app_info(HS_AppInfo::instance()), app_recover(HS_AppRecover::instance()) {} + hs_instance() : client_manager(HS_ClientManager::instance()), app_info(HS_AppInfo::instance()), app_recover(HS_AppRecover::instance()), vui_adapter(HS_VuiAdapter::instance()) {} int init(afb_api_t api); void setEventHook(const char *event, const event_hook_func f); void onEvent(afb_api_t api, const char *event, struct json_object *object); @@ -220,6 +221,11 @@ int hs_instance::init(afb_api_t api) return -1; } + if(vui_adapter == nullptr) { + AFB_ERROR("vui_adapter is nullptr."); + } + vui_adapter->init(api); + return 0; } @@ -235,6 +241,7 @@ int hs_instance::init(afb_api_t api) */ void hs_instance::setEventHook(const char *event, const event_hook_func f) { + AFB_INFO("hook event %s", event); if(event == nullptr || f == nullptr) { AFB_WARNING("argument is null."); return; @@ -273,6 +280,9 @@ void hs_instance::onEvent(afb_api_t api, const char *event, struct json_object * break; } } + else { + AFB_INFO("don't find hook event %s", event); + } } /** @@ -321,7 +331,6 @@ static void pingSample(afb_req_t request) */ static void tap_shortcut (afb_req_t request) { - AFB_DEBUG("called."); int ret = 0; const char* value = afb_req_value(request, _application_id); if (value) { @@ -363,7 +372,6 @@ static void tap_shortcut (afb_req_t request) */ static void on_screen_message (afb_req_t request) { - AFB_DEBUG("called."); int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__); if (ret) { afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__); @@ -389,7 +397,6 @@ static void on_screen_message (afb_req_t request) */ static void on_screen_reply (afb_req_t request) { - AFB_DEBUG("called."); int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__); if (ret) { afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__); @@ -414,7 +421,6 @@ static void on_screen_reply (afb_req_t request) */ static void subscribe(afb_req_t request) { - AFB_DEBUG("called."); int ret = 0; std::string req_appid = std::move(get_application_id(request)); if(!req_appid.empty()) { @@ -447,7 +453,6 @@ static void subscribe(afb_req_t request) */ static void unsubscribe(afb_req_t request) { - AFB_DEBUG("called."); int ret = 0; std::string req_appid = std::move(get_application_id(request)); if(!req_appid.empty()) { @@ -480,7 +485,6 @@ static void unsubscribe(afb_req_t request) */ static void showWindow(afb_req_t request) { - AFB_DEBUG("called."); int ret = 0; const char* value = afb_req_value(request, _application_id); if (value) { @@ -520,7 +524,6 @@ static void showWindow(afb_req_t request) */ static void hideWindow(afb_req_t request) { - AFB_DEBUG("called."); int ret = 0; const char* value = afb_req_value(request, _application_id); if (value) { @@ -553,7 +556,6 @@ static void hideWindow(afb_req_t request) */ static void replyShowWindow(afb_req_t request) { - AFB_DEBUG("called."); int ret = 0; const char* value = afb_req_value(request, _application_id); if (value) { @@ -588,7 +590,6 @@ static void replyShowWindow(afb_req_t request) */ static void showNotification(afb_req_t request) { - AFB_DEBUG("called."); int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, "homescreen"); if (ret) { afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__); @@ -615,7 +616,6 @@ static void showNotification(afb_req_t request) */ static void showInformation(afb_req_t request) { - AFB_DEBUG("called."); int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, "homescreen"); if (ret) { afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__); @@ -640,7 +640,6 @@ static void showInformation(afb_req_t request) */ static void getRunnables(afb_req_t request) { - AFB_DEBUG("called."); struct json_object* j_runnable = json_object_new_array(); g_hs_instance->app_info->getRunnables(&j_runnable); @@ -733,8 +732,8 @@ static const afb_verb_t verbs[]= { { .verb="unsubscribe", .callback=unsubscribe }, { .verb="showNotification", .callback=showNotification }, { .verb="showInformation", .callback=showInformation }, - { .verb="registerShortcut", .callback=registerShortcut }, { .verb="getRunnables", .callback=getRunnables }, + { .verb="registerShortcut", .callback=registerShortcut }, { .verb="updateShortcut", .callback=updateShortcut }, {NULL } /* marker for end of the array */ }; @@ -774,12 +773,13 @@ static int init(afb_api_t api) delete g_hs_instance->client_manager; delete g_hs_instance->app_info; delete g_hs_instance->app_recover; + delete g_hs_instance->vui_adapter; delete g_hs_instance; g_hs_instance = nullptr; } g_hs_instance = new hs_instance(); if(g_hs_instance == nullptr) { - AFB_ERROR( "Fatal Error: new g_hs_instance failed."); + AFB_ERROR( "new g_hs_instance failed."); return -1; } @@ -800,7 +800,7 @@ static int init(afb_api_t api) */ static void onevent(afb_api_t api, const char *event, struct json_object *object) { - AFB_INFO("on_event %s", event); + AFB_INFO("on_event %s, object %s", event, json_object_to_json_string(object)); g_hs_instance->onEvent(api, event, object); } diff --git a/src/hs-appinfo.cpp b/src/hs-appinfo.cpp index 6274670..6b22265 100644 --- a/src/hs-appinfo.cpp +++ b/src/hs-appinfo.cpp @@ -125,7 +125,7 @@ int HS_AppInfo::init(afb_api_t api) { afmmain = new HS_AfmMainProxy(); if(afmmain == nullptr) { - AFB_ERROR("Fatal Error:new HS_AfmMainProxy failed"); + AFB_ERROR("new HS_AfmMainProxy failed"); return -1; } @@ -362,7 +362,6 @@ void HS_AppInfo::removeAppDetail(std::string appid) */ void HS_AppInfo::pushAppListChangedEvent(const char *oper, struct json_object *object) { - AFB_DEBUG("called."); struct json_object *push_obj = json_object_new_object(); json_object_object_add(push_obj, _keyOperation, json_object_new_string(oper)); json_object_object_add(push_obj, _keyData, object); diff --git a/src/hs-apprecover.cpp b/src/hs-apprecover.cpp index fa8d824..adc8a3a 100644 --- a/src/hs-apprecover.cpp +++ b/src/hs-apprecover.cpp @@ -90,6 +90,9 @@ int HS_AppRecover::init(afb_api_t api) */ void HS_AppRecover::startRecovery(afb_api_t api) { + this->addListenAppId(_listen_all); + HS_ClientManager::instance()->addListener(this); + for(auto &key : HS_Config::keys_recover_type) { for(auto &m : recover_app_map[key]){ struct app_recover_info recover_info = { @@ -124,23 +127,18 @@ void HS_AppRecover::startRecovery(afb_api_t api) } /** - * register started applications + * notify * * #### Parameters - * - appid : application id liked "dashboard" + * - api : the api + * - appid : application id * * #### Return - * false : not recover app - * true : recover app - * + * None + * */ -bool HS_AppRecover::registerRecoveredApp(afb_api_t api, const std::string &appid) +void HS_AppRecover::notify(afb_api_t api, std::string appid) { - bool ret = false; - if(m_recovering_set.empty()) { - return ret; - } - AFB_INFO("recover appid=[%s].", appid.c_str()); auto it = m_recovering_set.find(appid); if(it != m_recovering_set.end()) { @@ -150,7 +148,6 @@ bool HS_AppRecover::registerRecoveredApp(afb_api_t api, const std::string &appid && ip->second.visibility) { HS_ClientManager::instance()->pushEvent("showWindow", nullptr, appid); } - ret = true; } // check wait recover application @@ -161,7 +158,10 @@ bool HS_AppRecover::registerRecoveredApp(afb_api_t api, const std::string &appid } m_wait_recover_set.erase(appid); } - return ret; + + if(m_recovering_set.empty()) { + HS_ClientManager::instance()->removeListener(this); + } } /** diff --git a/src/hs-apprecover.h b/src/hs-apprecover.h index 28b0ce6..48138b5 100644 --- a/src/hs-apprecover.h +++ b/src/hs-apprecover.h @@ -20,6 +20,7 @@ #include <set> #include "hs-helper.h" #include "hs-config.h" +#include "hs-clientmanager.h" struct app_recover_info { std::string recover_type; @@ -27,9 +28,9 @@ struct app_recover_info { std::string after; }; -class HS_AppRecover { +class HS_AppRecover : public listener_interface { public: - HS_AppRecover() = default; + HS_AppRecover() : listener_interface(std::string("hs_apprecover")) {} ~HS_AppRecover() = default; HS_AppRecover(HS_AppRecover const &) = delete; HS_AppRecover &operator=(HS_AppRecover const &) = delete; @@ -40,8 +41,8 @@ public: int init(afb_api_t api); void setRecoverMap(recover_map &map) {recover_app_map.swap(map);} void startRecovery(afb_api_t api); - bool registerRecoveredApp(afb_api_t api, const std::string &appid); void screenUpdated(struct json_object *obj); + void notify(afb_api_t api, std::string appid = ""); private: void startApplication(afb_api_t api, const std::string &appid); diff --git a/src/hs-client.cpp b/src/hs-client.cpp index e8f0f7b..5da52bb 100644 --- a/src/hs-client.cpp +++ b/src/hs-client.cpp @@ -60,7 +60,6 @@ std::list<std::pair<std::string, std::string>> HS_Client::shortcut_list; */ HS_Client::HS_Client(afb_req_t request, std::string id) : my_id(id) { - AFB_DEBUG("called."); my_event = afb_api_make_event(request->api, id.c_str()); } @@ -76,7 +75,6 @@ HS_Client::HS_Client(afb_req_t request, std::string id) : my_id(id) */ HS_Client::~HS_Client() { - AFB_DEBUG("called."); afb_event_unref(my_event); } @@ -172,7 +170,6 @@ int HS_Client::on_screen_reply(afb_req_t request) */ int HS_Client::subscribe(afb_req_t request) { - AFB_DEBUG(" called."); int ret = 0; const char *value = afb_req_value(request, _event); if(value) { @@ -189,9 +186,6 @@ int HS_Client::subscribe(afb_req_t request) subscription = true; } } - if (!strcasecmp("updateShortcut", value)) { - pushUpdateShortcutEvent(); - } } } else { @@ -214,7 +208,6 @@ int HS_Client::subscribe(afb_req_t request) */ int HS_Client::unsubscribe(afb_req_t request) { - AFB_DEBUG(" called."); int ret = 0; const char *value = afb_req_value(request, _event); if(value) { @@ -281,7 +274,6 @@ int HS_Client::showWindow(afb_req_t request) */ int HS_Client::hideWindow(afb_req_t request) { - AFB_DEBUG(" called."); std::string req_appid = std::move(get_application_id(request)); if(req_appid.empty()) { AFB_WARNING("can't get application identifier"); @@ -340,7 +332,6 @@ int HS_Client::replyShowWindow(afb_req_t request) */ int HS_Client::showNotification(afb_req_t request) { - AFB_DEBUG(" called."); int ret = 0; const char *value = afb_req_value(request, _text); if(value) { @@ -388,7 +379,6 @@ int HS_Client::showNotification(afb_req_t request) */ int HS_Client::showInformation(afb_req_t request) { - AFB_DEBUG(" called."); int ret = 0; const char *value = afb_req_value(request, _info); if(value) { @@ -547,7 +537,6 @@ bool HS_Client::isSupportEvent(const char* event) */ int HS_Client::handleRequest(afb_req_t request, const char *verb) { - AFB_DEBUG("called."); if((strcasecmp(verb, "subscribe") && strcasecmp(verb, "unsubscribe")) && !checkEvent(verb)) return 0; @@ -577,7 +566,7 @@ int HS_Client::pushEvent(const char *event, struct json_object *param) if(!checkEvent(event)) return 0; - AFB_INFO("called, event=%s.",event); + AFB_INFO("called, event=%s.", event); struct json_object* push_obj = json_object_new_object(); hs_add_object_to_json_object_str( push_obj, 4, _application_id, my_id.c_str(), _type, event); if(param != nullptr) diff --git a/src/hs-clientmanager.cpp b/src/hs-clientmanager.cpp index 3585bea..d84d07b 100644 --- a/src/hs-clientmanager.cpp +++ b/src/hs-clientmanager.cpp @@ -20,6 +20,7 @@ #include "hs-apprecover.h" static const char _homescreen[] = "homescreen"; +const std::string _listen_all("all"); HS_ClientManager* HS_ClientManager::me = nullptr; @@ -72,7 +73,9 @@ HS_ClientManager* HS_ClientManager::instance(void) */ int HS_ClientManager::init(void) { - AFB_NOTICE("called."); + listener_list.clear(); + std::list<listener_interface*> interface_list; + listener_list[_listen_all] = std::move(interface_list); } /** @@ -199,7 +202,7 @@ int HS_ClientManager::handleRequest(afb_req_t request, const char *verb, const c } } if(isRegisterApp) { - checkRegisterApp(request->api, std::string(appid)); + notifyListener(request->api, std::string(appid)); } return ret; } @@ -249,18 +252,132 @@ int HS_ClientManager::pushEvent(const char *event, struct json_object *param, st * - appid : register application's id * * #### Return + * true : checked + * false : not checked + * + */ +bool HS_ClientManager::checkRegisterApp(afb_api_t api, const std::string &appid) +{ + bool ret = true; + auto &ip = listener_list[_listen_all]; + if(!ip.empty()) { + for(auto &it : ip) { + it->notify(api, appid); + } + } + else if(startup_appid == appid) { + startup_appid.clear(); + pushEvent("showWindow", nullptr, appid); + } + else { + ret = false; + } + return ret; +} + +/** + * check whether application was started + * + * #### Parameters + * - appid : application's id + * + * #### Return + * true : started + * false : not start + * + */ +bool HS_ClientManager::isAppStarted(const std::string &appid) +{ + auto it = client_list.find(appid); + return it != client_list.end() ? true : false; +} + +/** + * add app register listener + * + * #### Parameters + * - listener_interface : listener interface + * + * #### Return + * None + * + */ +void HS_ClientManager::addListener(listener_interface* listener) +{ + for (auto &it : listener->listenAppSet()) { + auto ip = listener_list.find(it); + if(ip != listener_list.end()) { + ip->second.push_back(listener); + } + else { + std::list<listener_interface*> lst; + lst.push_back(listener); + listener_list[it] = std::move(lst); + } + } +} + +/** + * remove app register listener + * + * #### Parameters + * - listener_interface : listener interface + * + * #### Return + * None + * + */ +void HS_ClientManager::removeListener(listener_interface* listener) +{ + for (auto &iter : listener->listenAppSet()) { + auto it = listener_list.find(iter); + if(it != listener_list.end()) { + auto ip = it->second.begin(); + for(; ip != it->second.end(); ++ip) { + if(listener->myUid() == (*ip)->myUid()) { + break; + } + } + it->second.erase(ip); + if(it->second.empty()) { + listener_list.erase(it->first); + } + } + } +} + +/** + * notify listener + * + * #### Parameters + * - api : the api + * - appid : register application's id + * + * #### Return * None * */ -void HS_ClientManager::checkRegisterApp(afb_api_t api, const std::string &appid) +void HS_ClientManager::notifyListener(afb_api_t api, const std::string &appid) { - if(HS_AppRecover::instance()->registerRecoveredApp(api, appid)) { - AFB_INFO("register recover application %s.", appid.c_str()); + if (checkRegisterApp(api, appid)) { return; } - if(startup_appid == appid) { - startup_appid.clear(); - pushEvent("showWindow", nullptr, appid); + AFB_INFO("listen %s, notified", appid.c_str()); + std::list<listener_interface*> interface_list; + auto ip = listener_list.find(appid); + if(ip != listener_list.end()) { + if(!ip->second.empty()) { + interface_list = ip->second; + } + else { + AFB_WARNING("listener is null."); + return; + } + } + + for(auto &it : interface_list) { + it->notify(api, appid); } + }
\ No newline at end of file diff --git a/src/hs-clientmanager.h b/src/hs-clientmanager.h index 366f256..c8bc48e 100644 --- a/src/hs-clientmanager.h +++ b/src/hs-clientmanager.h @@ -21,9 +21,32 @@ #include <mutex> #include <memory> #include <unordered_map> +#include <list> +#include <set> #include "hs-helper.h" #include "hs-client.h" +extern const std::string _listen_all; + +class listener_interface { +public: + listener_interface(std::string uid, std::set<std::string> listen_appid = std::set<std::string>()) : m_uid(uid), m_listen_appid(listen_appid) {} + virtual ~listener_interface() {} + virtual void notify(afb_api_t api, std::string appid = "") = 0; + std::string myUid(void) {return m_uid;} + std::set<std::string> listenAppSet(void) {return m_listen_appid;} + void addListenAppId(std::string appid) {m_listen_appid.insert(appid);} + bool isListenAppId(std::string &appid) { + auto it = m_listen_appid.find(appid); + return it != m_listen_appid.end() ? true : false; + } + bool listenAppEmpty(void) {return m_listen_appid.empty();} + void clearListenAppSet(void) {m_listen_appid.clear();} +private: + std::string m_uid; + std::set<std::string> m_listen_appid; +}; + typedef struct HS_ClientCtxt { std::string id; @@ -49,15 +72,20 @@ public: int pushEvent(const char *event, struct json_object *param, std::string appid = ""); void removeClientCtxt(void *data); // don't use, internal only void setStartupAppid(const std::string &appid) {startup_appid = appid;} + bool isAppStarted(const std::string &appid); + void addListener(listener_interface* listener); + void removeListener(listener_interface* listener); private: HS_ClientCtxt* createClientCtxt(afb_req_t req, std::string appid); HS_Client* addClient(afb_req_t req, std::string appid); void removeClient(std::string appid); - void checkRegisterApp(afb_api_t api, const std::string &appid); + bool checkRegisterApp(afb_api_t api, const std::string &appid); + void notifyListener(afb_api_t api, const std::string &appid); private: static HS_ClientManager* me; + std::unordered_map<std::string, std::list<listener_interface*>> listener_list; std::unordered_map<std::string, HS_Client*> client_list; std::unordered_map<std::string, HS_ClientCtxt*> appid2ctxt; std::mutex mtx; diff --git a/src/hs-helper.cpp b/src/hs-helper.cpp index 780b7d4..e5e1d92 100644 --- a/src/hs-helper.cpp +++ b/src/hs-helper.cpp @@ -32,6 +32,10 @@ const char* evlist[] = { "application-list-changed", "registerShortcut", "updateShortcut", + "setDestination", + "cancelDestination", + "startNavigation", + "stopNavigation", "reserved" }; diff --git a/src/hs-proxy.cpp b/src/hs-proxy.cpp index 718f6ff..7baca30 100644 --- a/src/hs-proxy.cpp +++ b/src/hs-proxy.cpp @@ -16,9 +16,11 @@ #include "hs-proxy.h" -static const char _afm_main[] = "afm-main"; -static const char _windowmanager[] = "windowmanager"; -static const char _event[] = "event"; +const char _afm_main[] = "afm-main"; +const char _windowmanager[] = "windowmanager"; +const char _event[] = "event"; +const char _vshl_capabilities[] = "vshl-capabilities"; +const char _actions[] = "actions"; /** * the callback function @@ -159,3 +161,34 @@ void HS_WmProxy::subscribe(afb_api_t api, EventType event, api_cb_func f) json_object_object_add(push_obj, _event, json_object_new_int(event)); api_call(api, _windowmanager, "wm_subscribe", push_obj, f); } + +/* -------------------------------------HS_VshlCapabilitiesProxy------------------------------------------ */ + +/** + * subscribe event + * + * #### Parameters + * - api : the api + * - module : module name + * - ev_list : event list + * + * #### Return + * None + * + */ +void HS_VshlCapabilitiesProxy::subscribe(afb_api_t api, const std::string &module, const std::list<std::string> &ev_list) +{ + if(ev_list.empty()) { + return; + } + + struct json_object *arr_obj = json_object_new_array(); + for(auto &it : ev_list) { + json_object_array_add(arr_obj, json_object_new_string(it.c_str())); + } + struct json_object *args = json_object_new_object(); + json_object_object_add(args, _actions, arr_obj); + + std::string verb = module + '/' + __FUNCTION__; + api_call(api, _vshl_capabilities, verb.c_str(), args); +}
\ No newline at end of file diff --git a/src/hs-proxy.h b/src/hs-proxy.h index 45bf9f4..6793b39 100644 --- a/src/hs-proxy.h +++ b/src/hs-proxy.h @@ -20,8 +20,12 @@ #include <string> #include <json-c/json.h> #include <functional> +#include <list> #include "hs-helper.h" +extern const char _afm_main[]; +extern const char _vshl_capabilities[]; + typedef void (*api_cb_func)(struct json_object *obj, const char *error, const char *info); class HS_AfmMainProxy { @@ -75,4 +79,9 @@ public: void subscribe(afb_api_t api, EventType event, api_cb_func f = nullptr); }; +struct HS_VshlCapabilitiesProxy { + // asynchronous call, reply in callback function + void subscribe(afb_api_t api, const std::string &module, const std::list<std::string> &ev_list); +}; + #endif // HOMESCREEN_PROXY_H
\ No newline at end of file diff --git a/src/hs-vuiadapter.cpp b/src/hs-vuiadapter.cpp new file mode 100644 index 0000000..6cb4f46 --- /dev/null +++ b/src/hs-vuiadapter.cpp @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2019 TOYOTA MOTOR CORPORATION + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "hs-vuiadapter.h" +#include "hs-clientmanager.h" +#include "hs-proxy.h" +#include "hs-appinfo.h" +#include "unistd.h" + +/** + * event handler + * + * #### Parameters + * - api : the api + * - event : received event name + * - object : received json object + * + * #### Return + * 0 : event can transfer to others + * 1 : event not transfer to others + */ +int event_handler(afb_api_t api, const char *event, struct json_object *object) +{ + return HS_VuiAdapter::instance()->onEvent(api, event, object); +} + +/* -------------------------------------Vui_Navigation------------------------------------------ */ + +const std::map<std::string, Vui_Navigation::func_handler> Vui_Navigation::func_list = { + {"set_destination", &Vui_Navigation::set_destination}, + {"cancel_navigation", &Vui_Navigation::cancel_navigation} +}; +const char _vui_prefixe[] = "vui"; +const char _poi[] = "poi"; +const char _navigation[] = "navigation"; +const char _destination[] = "destination"; +const char _coordinate[] = "coordinate"; +const char _latitudeInDegrees[] = "latitudeInDegrees"; +const char _longitudeInDegrees[] = "longitudeInDegrees"; +const char _setDestination[] = "setDestination"; +const char _cancelDestination[] = "cancelDestination"; +const char _startNavigation[] = "startNavigation"; +const char _stopNavigation[] = "stopNavigation"; + +/** + * init + * + * #### Parameters + * - api : the api + * + * #### Return + * None + * + */ +void Vui_Navigation::init(afb_api_t api) +{ + std::list<std::string> ev_list; + for(auto &it : func_list) { + ev_list.push_back(it.first); + std::string ev_name = std::string(_vshl_capabilities) + '/' + it.first; + AFB_INFO("setEventHook event %s", ev_name.c_str()); + setEventHook(ev_name.c_str(), event_handler); + } + HS_VshlCapabilitiesProxy proxy; + proxy.subscribe(api, _navigation, ev_list); +} + +/** + * handle event + * + * #### Parameters + * - api : the api serving the request + * - event : event name + * - object : event json object + * + * #### Return + * 0 : continue transfer + * 1 : blocked + * + */ +int Vui_Navigation::onEvent(afb_api_t api, const char *event, struct json_object *object) +{ + std::string ev(event); + auto pos = ev.find('/'); + auto ip = func_list.find(ev.substr(pos + 1)); + int ret = 0; + if(ip != func_list.end()) { + (this->*(ip->second))(api, object); + ret = 1; + } + return ret; +} + +/** + * set_destination event handler + * + * #### Parameters + * - api : the api serving the reques + * - object : event json object + * + * #### Return + * None + * + */ +void Vui_Navigation::set_destination(afb_api_t api, struct json_object *object) +{ + AFB_INFO("set dest: %s", json_object_to_json_string(object)); + struct json_object *j_dest, *j_coord, *j_latitude, *j_longitude; + struct json_object *j_obj = json_tokener_parse(json_object_get_string(object)); + if(json_object_object_get_ex(j_obj, _destination, &j_dest) + && json_object_object_get_ex(j_dest, _coordinate, &j_coord) + && json_object_object_get_ex(j_coord, _latitudeInDegrees, &j_latitude) + && json_object_object_get_ex(j_coord, _longitudeInDegrees, &j_longitude)) { + m_dest = std::make_pair(json_object_get_double(j_latitude), json_object_get_double(j_longitude)); + } + else { + AFB_WARNING("input data error."); + return; + } + + auto b_pair = std::make_pair<bool, bool>(false, false); + if(HS_ClientManager::instance()->isAppStarted(std::string(_poi))) { + b_pair.first = true; + set_destination2poi(api); + } + else { + this->addListenAppId(_poi); + std::string id = HS_AppInfo::instance()->getAppProperty(_poi, _keyId); + HS_AfmMainProxy afm_proxy; + afm_proxy.start(api, id); + } + + if(HS_ClientManager::instance()->isAppStarted(std::string(_navigation))) { + b_pair.second = true; + start_navigation(api); + } + else { + this->addListenAppId(_navigation); + std::string id = HS_AppInfo::instance()->getAppProperty(_navigation, _keyId); + HS_AfmMainProxy afm_proxy; + afm_proxy.start(api, id); + } + m_start_flg.swap(b_pair); + if (!listenAppEmpty()) { + HS_ClientManager::instance()->addListener(this); + } +} + +/** + * cancel_navigation event handler + * + * #### Parameters + * - api : the api serving the reques + * - object : event json object + * + * #### Return + * None + * + */ +void Vui_Navigation::cancel_navigation(afb_api_t api, struct json_object *object) +{ + HS_ClientManager::instance()->pushEvent(_stopNavigation, nullptr); +} + +/** + * notify + * + * #### Parameters + * - api : the api + * - appid : application id + * + * #### Return + * None + * + */ +void Vui_Navigation::notify(afb_api_t api, std::string appid) +{ + if(isListenAppId(appid)) { + if (appid == _poi) { + m_start_flg.first = true; + sleep(1); + set_destination2poi(api); + } + else if(appid == _navigation) { + m_start_flg.second = true; + start_navigation(api); + } + else { + AFB_WARNING("%s isn't interest app.", appid.c_str()); + return; + } + } + if(m_start_flg.first && m_start_flg.second) { + HS_ClientManager::instance()->removeListener(this); + clearListenAppSet(); + } +} + +/** + * set destination to poiapp + * + * #### Parameters + * - api : the api + * + * #### Return + * None + * + */ +void Vui_Navigation::set_destination2poi(afb_api_t api) +{ + struct json_object *param = json_object_new_object(); + json_object_object_add(param, _latitudeInDegrees, json_object_new_double(m_dest.first)); + json_object_object_add(param, _longitudeInDegrees, json_object_new_double(m_dest.second)); + HS_ClientManager::instance()->pushEvent(_setDestination, param); +} + +/** + * set destination and start navigation + * + * #### Parameters + * - api : the ap + * + * #### Return + * None + * + */ +void Vui_Navigation::start_navigation(afb_api_t api) +{ + HS_ClientManager::instance()->pushEvent(_startNavigation, nullptr); + HS_ClientManager::instance()->pushEvent("showWindow", nullptr, _navigation); +} + +/* -------------------------------------HS_VuiAdapter------------------------------------------ */ + +HS_VuiAdapter* HS_VuiAdapter::me = nullptr; + +/** + * get instance + * + * #### Parameters + * - Nothing + * + * #### Return + * HS_VuiAdapter instance pointer + * + */ +HS_VuiAdapter* HS_VuiAdapter::instance(void) +{ + if(me == nullptr) + me = new HS_VuiAdapter(); + + return me; +} + +/** + * init + * + * #### Parameters + * - api : the api + * + * #### Return + * None + * + */ +void HS_VuiAdapter::init(afb_api_t api) +{ + std::string uid = std::string(_vui_prefixe) + std::string("-") + _navigation; + module_list[uid] = new Vui_Navigation(uid); + + for(auto &it : module_list) { + it.second->init(api); + } +} + +/** + * handle event + * + * #### Parameters + * - api : the api serving the request + * - event : event name + * - object : event json object + * + * #### Return + * 0 : continue transfer + * 1 : blocked + * + */ +int HS_VuiAdapter::onEvent(afb_api_t api, const char *event, struct json_object *object) +{ + for(auto &it : module_list) { + if(it.second->onEvent(api, event, object)) + return 1; + } + return 0; +} diff --git a/src/hs-vuiadapter.h b/src/hs-vuiadapter.h new file mode 100644 index 0000000..6bf47b0 --- /dev/null +++ b/src/hs-vuiadapter.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2019 TOYOTA MOTOR CORPORATION + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef HOMESCREEN_VUIADAPTER_H +#define HOMESCREEN_VUIADAPTER_H + +#include <map> +#include <memory> +#include <utility> +#include "hs-helper.h" +#include "hs-clientmanager.h" + +class Vui_ModuleBase { +public: + explicit Vui_ModuleBase(std::string uid) : m_uid(uid) {} + virtual ~Vui_ModuleBase() {} + virtual void init(afb_api_t api) = 0; + virtual int onEvent(afb_api_t api, const char *event, struct json_object *object) = 0; + std::string mouduleId(void) {return m_uid;} + +private: + std::string m_uid; +}; + +class Vui_Navigation : public Vui_ModuleBase, public listener_interface { +public: + explicit Vui_Navigation(std::string uid) : Vui_ModuleBase(uid), listener_interface(uid) {} + ~Vui_Navigation() = default; + + virtual void init(afb_api_t api); + virtual int onEvent(afb_api_t api, const char *event, struct json_object *object); + virtual void notify(afb_api_t api, std::string appid = ""); + +private: + void set_destination(afb_api_t api, struct json_object *object); + void cancel_navigation(afb_api_t api, struct json_object *object); + void set_destination2poi(afb_api_t api); + void start_navigation(afb_api_t api); + + typedef void (Vui_Navigation::*func_handler)(afb_api_t, struct json_object *object); + static const std::map<std::string, func_handler> func_list; + std::pair<double, double> m_dest; + std::pair<bool, bool> m_start_flg; +}; + +class HS_VuiAdapter { +public: + HS_VuiAdapter() = default; + ~HS_VuiAdapter() = default; + HS_VuiAdapter(HS_VuiAdapter const &) = delete; + HS_VuiAdapter &operator=(HS_VuiAdapter const &) = delete; + HS_VuiAdapter(HS_VuiAdapter &&) = delete; + HS_VuiAdapter &operator=(HS_VuiAdapter &&) = delete; + + static HS_VuiAdapter* instance(void); + void init(afb_api_t api); + int onEvent(afb_api_t api, const char *event, struct json_object *object); + +private: + static HS_VuiAdapter* me; + std::map<std::string, Vui_ModuleBase*> module_list; +}; + +#endif // HOMESCREEN_VUIADAPTER_H
\ No newline at end of file |