merge vui
authorwang_zhiqiang <wang_zhiqiang@dl.cn.nexty-ele.com>
Mon, 3 Jun 2019 06:47:27 +0000 (14:47 +0800)
committerwang_zhiqiang <wang_zhiqiang@dl.cn.nexty-ele.com>
Mon, 3 Jun 2019 09:41:21 +0000 (17:41 +0800)
Change-Id: I64a1bb68ea3e2b772a40eb78d316c54f8ed25de8

14 files changed:
package/root/config.xml
src/CMakeLists.txt
src/homescreen.cpp
src/hs-appinfo.cpp
src/hs-apprecover.cpp
src/hs-apprecover.h
src/hs-client.cpp
src/hs-clientmanager.cpp
src/hs-clientmanager.h
src/hs-helper.cpp
src/hs-proxy.cpp
src/hs-proxy.h
src/hs-vuiadapter.cpp [new file with mode: 0644]
src/hs-vuiadapter.h [new file with mode: 0644]

index 38c1258..3501b7c 100644 (file)
@@ -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" />
index 21cbf49..b8e558d 100644 (file)
@@ -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)
index cff2810..d9fef91 100644 (file)
@@ -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);
 }
 
index 6274670..6b22265 100644 (file)
@@ -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);
index fa8d824..adc8a3a 100644 (file)
@@ -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);
+    }
 }
 
 /**
index 28b0ce6..48138b5 100644 (file)
@@ -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);
index e8f0f7b..bff9141 100644 (file)
@@ -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) {
@@ -214,7 +211,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 +277,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 +335,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 +382,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 +540,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 +569,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)
index 3585bea..d84d07b 100644 (file)
@@ -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
index 366f256..c8bc48e 100644 (file)
 #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;
index 780b7d4..e5e1d92 100644 (file)
@@ -32,6 +32,10 @@ const char* evlist[] = {
     "application-list-changed",
     "registerShortcut",
     "updateShortcut",
+    "setDestination",
+    "cancelDestination",
+    "startNavigation",
+    "stopNavigation",
     "reserved"
   };
 
index 718f6ff..7baca30 100644 (file)
 
 #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
index 45bf9f4..6793b39 100644 (file)
 #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 (file)
index 0000000..f71e6fd
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * 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"
+
+/**
+ * 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;
+            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_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;
+}
\ No newline at end of file
diff --git a/src/hs-vuiadapter.h b/src/hs-vuiadapter.h
new file mode 100644 (file)
index 0000000..6bf47b0
--- /dev/null
@@ -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