aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--conf/hs-conf.json12
-rw-r--r--package/root/config.xml2
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/homescreen.cpp34
-rw-r--r--src/hs-appinfo.cpp3
-rw-r--r--src/hs-apprecover.cpp26
-rw-r--r--src/hs-apprecover.h7
-rw-r--r--src/hs-client.cpp13
-rw-r--r--src/hs-clientmanager.cpp133
-rw-r--r--src/hs-clientmanager.h30
-rw-r--r--src/hs-helper.cpp4
-rw-r--r--src/hs-proxy.cpp39
-rw-r--r--src/hs-proxy.h9
-rw-r--r--src/hs-vuiadapter.cpp308
-rw-r--r--src/hs-vuiadapter.h77
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