merge improvement
authorwang_zhiqiang <wang_zhiqiang@dl.cn.nexty-ele.com>
Mon, 14 Jan 2019 05:50:55 +0000 (13:50 +0800)
committerwang_zhiqiang <wang_zhiqiang@dl.cn.nexty-ele.com>
Mon, 14 Jan 2019 05:50:55 +0000 (13:50 +0800)
Change-Id: I555f0e48ff96564695af60e8d2dbbc1379a8bc95

src/CMakeLists.txt
src/homescreen.cpp
src/hs-client.cpp
src/hs-client.h
src/hs-clientmanager.cpp
src/hs-clientmanager.h
src/hs-periphery.cpp [new file with mode: 0644]
src/hs-periphery.h [new file with mode: 0644]
src/hs-proxy.cpp [new file with mode: 0644]
src/hs-proxy.h [new file with mode: 0644]

index 3687345..c6dc972 100644 (file)
@@ -26,7 +26,9 @@ set(binding_hs_sources
   homescreen.cpp
   hs-helper.cpp
   hs-clientmanager.cpp
-  hs-client.cpp)
+  hs-client.cpp
+  hs-proxy.cpp
+  hs-periphery.cpp)
 
 link_libraries(-Wl,--as-needed -Wl,--gc-sections -Wl,--no-undefined)
 include_directories(${PROJECT_SOURCE_DIR}/include)
index e921feb..a6eee8f 100644 (file)
@@ -22,6 +22,7 @@
 #include "hs-helper.h"
 #include "hmi-debug.h"
 #include "hs-clientmanager.h"
+#include "hs-periphery.h"
 
 
 const char _error[] = "error";
@@ -29,7 +30,44 @@ const char _application_id[] = "application_id";
 const char _display_message[] = "display_message";
 const char _reply_message[] = "reply_message";
 
-static HS_ClientManager* g_client_manager = HS_ClientManager::instance();
+struct hs_instance {
+  HS_ClientManager *client_manager;   // the connection session manager
+  HS_PeripheryManager *periphery_manager; // the periphery application manager
+
+  hs_instance() : client_manager(HS_ClientManager::instance()), periphery_manager(HS_PeripheryManager::instance()) {}
+  int init(afb_api_t api);
+};
+
+/**
+ * init function
+ *
+ * #### Parameters
+ * - api : the api serving the request
+ *
+ * #### Return
+ * 0 : init success
+ * 1 : init fail
+ *
+ */
+int hs_instance::init(afb_api_t api)
+{
+    if(client_manager == nullptr) {
+        HMI_ERROR("homescreen-service","FATAL ERROR: client_manager is nullptr.");
+        return -1;
+    }
+    client_manager->init();
+
+    if(periphery_manager == nullptr) {
+        HMI_ERROR("homescreen-service","FATAL ERROR: periphery_manager is nullptr.");
+        return -1;
+    }
+    periphery_manager->init(api);
+
+    return 0;
+}
+
+static struct hs_instance *g_hs_instance;
+// static HS_ClientManager* g_client_manager = HS_ClientManager::instance();
 
 /*
 ********** Method of HomeScreen Service (API) **********
@@ -62,7 +100,7 @@ static void tap_shortcut (afb_req_t request)
     const char* value = afb_req_value(request, _application_id);
     if (value) {
         HMI_NOTICE("homescreen-service","request appid = %s.", value);
-        ret = g_client_manager->handleRequest(request, __FUNCTION__, value);
+        ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
     }
     else {
         ret = AFB_EVENT_BAD_REQUEST;
@@ -93,7 +131,7 @@ static void tap_shortcut (afb_req_t request)
 static void on_screen_message (afb_req_t request)
 {
     HMI_NOTICE("homescreen-service","called.");
-    int ret = g_client_manager->handleRequest(request, __FUNCTION__);
+    int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__);
     if (ret) {
         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
     }
@@ -119,7 +157,7 @@ static void on_screen_message (afb_req_t request)
 static void on_screen_reply (afb_req_t request)
 {
     HMI_NOTICE("homescreen-service","called.");
-    int ret = g_client_manager->handleRequest(request, __FUNCTION__);
+    int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__);
     if (ret) {
         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
     }
@@ -147,7 +185,7 @@ static void subscribe(afb_req_t request)
     int ret = 0;
     std::string req_appid = std::move(get_application_id(request));
     if(!req_appid.empty()) {
-        ret = g_client_manager->handleRequest(request, __FUNCTION__, req_appid.c_str());
+        ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, req_appid.c_str());
     }
     else {
         ret = AFB_EVENT_BAD_REQUEST;
@@ -180,7 +218,7 @@ static void unsubscribe(afb_req_t request)
     int ret = 0;
     std::string req_appid = std::move(get_application_id(request));
     if(!req_appid.empty()) {
-        ret = g_client_manager->handleRequest(request, __FUNCTION__, req_appid.c_str());
+        ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, req_appid.c_str());
     }
     else {
         ret = AFB_EVENT_BAD_REQUEST;
@@ -213,7 +251,7 @@ static void showWindow(afb_req_t request)
     int ret = 0;
     const char* value = afb_req_value(request, _application_id);
     if (value) {
-        ret = g_client_manager->handleRequest(request, __FUNCTION__, value);
+        ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
     }
     else {
         ret = AFB_EVENT_BAD_REQUEST;
@@ -246,7 +284,7 @@ static void hideWindow(afb_req_t request)
     int ret = 0;
     const char* value = afb_req_value(request, _application_id);
     if (value) {
-        ret = g_client_manager->handleRequest(request, __FUNCTION__, value);
+        ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
     }
     else {
         ret = AFB_EVENT_BAD_REQUEST;
@@ -279,7 +317,7 @@ static void replyShowWindow(afb_req_t request)
     int ret = 0;
     const char* value = afb_req_value(request, _application_id);
     if (value) {
-        ret = g_client_manager->handleRequest(request, __FUNCTION__, value);
+        ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, value);
     }
     else {
         ret = AFB_EVENT_BAD_REQUEST;
@@ -311,7 +349,7 @@ static void replyShowWindow(afb_req_t request)
 static void showNotification(afb_req_t request)
 {
     HMI_NOTICE("homescreen-service","called.");
-    int ret = g_client_manager->handleRequest(request, __FUNCTION__, "homescreen");
+    int ret = g_hs_instance->client_manager->handleRequest(request, __FUNCTION__, "homescreen");
     if (ret) {
         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
     }
@@ -338,7 +376,7 @@ static void showNotification(afb_req_t request)
 static void showInformation(afb_req_t request)
 {
     HMI_NOTICE("homescreen-service","called.");
-    int ret = g_client_manager->handleRequest(request,  __FUNCTION__, "homescreen");
+    int ret = g_hs_instance->client_manager->handleRequest(request,  __FUNCTION__, "homescreen");
     if (ret) {
         afb_req_fail_f(request, "failed", "called %s, Unknown parameter", __FUNCTION__);
     }
@@ -399,9 +437,21 @@ static int init(afb_api_t api)
 {
     HMI_NOTICE("homescreen-service","binding init");
 
-    g_client_manager->init();
+    // g_client_manager->init();
+    if(g_hs_instance != nullptr) {
+        HMI_WARNING("homescreen-service", "g_hs_instance isn't null.");
+        delete g_hs_instance->client_manager;
+        delete g_hs_instance->periphery_manager;
+        delete g_hs_instance;
+        g_hs_instance = nullptr;
+    }
+    g_hs_instance = new hs_instance();
+    if(g_hs_instance == nullptr) {
+        HMI_ERROR("homescreen-service", "Fatal Error: new g_hs_instance failed.");
+        return -1;
+    }
 
-    return 0;
+    return g_hs_instance->init(api);
 }
 
 /**
@@ -419,6 +469,7 @@ static int init(afb_api_t api)
 static void onevent(afb_api_t api, const char *event, struct json_object *object)
 {
    HMI_NOTICE("homescreen-service","on_event %s", event);
+   g_hs_instance->periphery_manager->onEvent(api, event, object);
 }
 
 const afb_binding_t afbBindingExport = {
index dd91e10..5ecc23b 100644 (file)
@@ -390,6 +390,30 @@ int HS_Client::showInformation(afb_req_t request)
     return ret;
 }
 
+/**
+ * push event
+ *
+ * #### Parameters
+ *  - event : the event want to push
+ *  - param : the parameter contents of event
+ *
+ * #### Return
+ * 0 : success
+ * others : fail
+ *
+ */
+int HS_Client::pushEvent(const char *event, struct json_object *param)
+{
+    if(!checkEvent(event))
+        return 0;
+
+    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)
+        json_object_object_add(push_obj, _parameter, param);
+    afb_event_push(my_event, push_obj);
+    return 0;
+}
 /**
  * check if client subscribe event
  *
index 5b384b1..791c4cd 100644 (file)
@@ -32,6 +32,7 @@ public:
     ~HS_Client();
 
     int handleRequest(afb_req_t request, const char *verb);
+    int pushEvent(const char *event, struct json_object *param);
 
 private:
     int tap_shortcut(afb_req_t request);
index 7d658e4..ce9ad6c 100644 (file)
@@ -194,4 +194,41 @@ int HS_ClientManager::handleRequest(afb_req_t request, const char *verb, const c
         }
     }
     return ret;
+}
+
+/**
+ * push event
+ *
+ * #### Parameters
+ *  - event : the event want to push
+ *  - param : the parameter contents of event
+ *  - appid : the destination application's id
+ *
+ * #### Return
+ * 0 : success
+ * others : fail
+ *
+ */
+int HS_ClientManager::pushEvent(const char *event, struct json_object *param, std::string appid)
+{
+    if(event == nullptr) {
+        HMI_ERROR("homescreen-service","event name is null.");
+        return -1;
+    }
+
+    if(appid.empty()) { // broadcast event to clients who subscribed this event
+        std::lock_guard<std::mutex> lock(this->mtx);
+        for(auto m : client_list) {
+            m.second->pushEvent(event, param);
+        }
+    }
+    else {  // push event to specific client
+        std::lock_guard<std::mutex> lock(this->mtx);
+        auto ip = client_list.find(appid);
+        if(ip != client_list.end()) {
+            ip->second->pushEvent(event, param);
+        }
+    }
+
+    return 0;
 }
\ No newline at end of file
index d485ea8..efc36de 100644 (file)
@@ -46,6 +46,7 @@ public:
     static HS_ClientManager* instance(void);
     int init(void);
     int handleRequest(afb_req_t request, const char *verb, const char *appid = nullptr);
+    int pushEvent(const char *event, struct json_object *param, std::string appid = "");
     void removeClientCtxt(void *data);  // don't use, internal only
 
 private:
diff --git a/src/hs-periphery.cpp b/src/hs-periphery.cpp
new file mode 100644 (file)
index 0000000..06e95ea
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * 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-periphery.h"
+#include "hs-proxy.h"
+#include "hmi-debug.h"
+#include "hs-clientmanager.h"
+
+static const char _restriction_on[] = "RestrictionOn";
+static const char _restriction_off[] = "RestrictionOff";
+
+/* -------------------------------------HS_PeripheryManager------------------------------------------ */
+
+HS_PeripheryManager* HS_PeripheryManager::me = nullptr;
+
+/**
+ * HS_PeripheryManager init function
+ *
+ * #### Parameters
+ *  - Nothing
+ *
+ * #### Return
+ * init result
+ *
+ */
+int HS_PeripheryManager::init(afb_api_t api)
+{
+    HS_Restriction* restriction = new HS_Restriction();
+    int ret = restriction->init(api);
+    if(ret) {
+        HMI_ERROR("homescreen-service","restriction init failed.");
+    }
+    else {
+        periphery_list[std::string("restriction")] = restriction;
+    }
+    return ret;
+}
+
+/**
+ * get instance
+ *
+ * #### Parameters
+ *  - Nothing
+ *
+ * #### Return
+ * HS_PeripheryManager instance pointer
+ *
+ */
+HS_PeripheryManager* HS_PeripheryManager::instance(void)
+{
+    if(me == nullptr)
+        me = new HS_PeripheryManager();
+    return me;
+}
+
+/**
+ * event function
+ *
+ * #### Parameters
+ *  - api : the api serving the request
+ *  - event  : event name
+ *  - object : event json object
+ *
+ * #### Return
+ * None
+ *
+ */
+void HS_PeripheryManager::onEvent(afb_api_t api, const char *event, struct json_object *object)
+{
+    for(auto m : periphery_list)
+        m.second->onEvent(api, event, object);
+}
+
+/* -------------------------------------HS_Restriction------------------------------------------ */
+
+/**
+ * HS_Restriction init function
+ *
+ * #### Parameters
+ *  - Nothing
+ *
+ * #### Return
+ * init result
+ *
+ */
+int HS_Restriction::init(afb_api_t api)
+{
+    HS_WmProxy wm_proxy;
+    // TBD
+    wm_proxy.subscribe(api, HS_WmProxy::Event_ScreenUpdated);
+    return 0;
+}
+
+/**
+ * event function
+ *
+ * #### Parameters
+ *  - api : the api serving the request
+ *  - event  : event name
+ *  - object : event json object
+ *
+ * #### Return
+ * None
+ *
+ */
+void HS_Restriction::onEvent(afb_api_t api, const char *event, struct json_object *object)
+{
+    if(!isConcernedEvent(event))
+        return;
+
+    std::string ev = event;
+    std::size_t pos = ev.find("/");
+    if(pos != std::string::npos) {
+        ev = ev.substr(pos + 1);
+    }
+    else {
+        HMI_ERROR("homescreen-service","received event is error.");
+        return;
+    }
+
+    if(ev == _restriction_on) {
+        restrictionOn(api, object);
+    }
+    else if(ev == _restriction_off) {
+        restrictionOff(api, object);
+    }
+    else {
+    }
+}
+
+/**
+ * restriction on function
+ *
+ * #### Parameters
+ *  - api : the api serving the request
+ *  - object : event json object
+ *
+ * #### Return
+ * None
+ *
+ */
+void HS_Restriction::restrictionOn(afb_api_t api, struct json_object *object)
+{
+
+}
+
+/**
+ * restriction off function
+ *
+ * #### Parameters
+ *  - api : the api serving the request
+ *  - object : event json object
+ *
+ * #### Return
+ * None
+ *
+ */
+void HS_Restriction::restrictionOff(afb_api_t api, struct json_object *object)
+{
+
+}
\ No newline at end of file
diff --git a/src/hs-periphery.h b/src/hs-periphery.h
new file mode 100644 (file)
index 0000000..d2da39e
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * 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_PERIPHERY_H
+#define HOMESCREEN_PERIPHERY_H
+
+#include <unordered_set>
+#include <unordered_map>
+#include "hs-helper.h"
+
+class HS_Periphery {
+public:
+    virtual int init(afb_api_t api) = 0;
+    virtual void onEvent(afb_api_t api, const char *event, struct json_object *object) = 0;
+};
+
+class HS_Restriction : public HS_Periphery {
+public:
+    HS_Restriction() = default;
+    ~HS_Restriction() = default;
+
+    int init(afb_api_t api);
+    void onEvent(afb_api_t api, const char *event, struct json_object *object);
+
+private:
+    const std::unordered_set<const char*> concerned_event_list {
+        "windowmanager/RestrictionOn",
+        "windowmanager/RestrictionOff"
+    };
+    inline bool isConcernedEvent(const char* event) const {
+        return (concerned_event_list.find(event) != concerned_event_list.end()) ? true : false;
+    }
+
+    void restrictionOn(afb_api_t api, struct json_object *object);
+    void restrictionOff(afb_api_t api, struct json_object *object);
+
+    std::string m_appid = "restriction";
+};
+
+class HS_PeripheryManager {
+public:
+    HS_PeripheryManager() = default;
+    ~HS_PeripheryManager() = default;
+
+    int init(afb_api_t api);
+    static HS_PeripheryManager* instance(void);
+    void onEvent(afb_api_t api, const char *event, struct json_object *object);
+
+    inline bool isPeripheryApp(const char* name) const {
+        return (periphery_app_list.find(name) != periphery_app_list.end()) ? true : false;
+    }
+
+private:
+    const std::unordered_set<const char*> periphery_app_list {
+        "launcher",
+        "homescreen",
+        "onscreenapp",
+        "restriction"
+    };
+
+    static HS_PeripheryManager* me;
+    std::unordered_map<std::string, HS_Periphery*> periphery_list;
+    // HS_Restriction m_restriction;
+};
+
+#endif // HOMESCREEN_PERIPHERY_H
\ No newline at end of file
diff --git a/src/hs-proxy.cpp b/src/hs-proxy.cpp
new file mode 100644 (file)
index 0000000..6ac4439
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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-proxy.h"
+#include "hmi-debug.h"
+
+static const char _windowmanager[] = "windowmanager";
+static const char _event[] = "event";
+
+
+/**
+ * the callback function
+ *
+ * #### Parameters
+ *  - closure : the user defined closure pointer 'closure'
+ *  - object : a JSON object returned (can be NULL)
+ *  - error : a string not NULL in case of error but NULL on success
+ *  - info : a string handling some info (can be NULL)
+ *  - api : the api
+ *
+ * #### Return
+ *  None
+ *
+ */
+static void api_callback(void *closure, struct json_object *object, const char *error, const char *info, afb_api_t api)
+{
+    HMI_NOTICE("homescreen-service","asynchronous call, error=%s, info=%s, object=%s.", error, info, json_object_get_string(object));
+    callback_func* f = (callback_func*)closure;
+    if(f != nullptr)
+        (*f)(api, object);
+}
+
+/**
+ * call api asynchronous
+ *
+ * #### Parameters
+ *  - api : the api serving the request
+ *  - service : the api name of service
+ *  - verb : the verb of service
+ *  - args : parameter
+ *
+ * #### Return
+ *  None
+ *
+ */
+static void api_call(afb_api_t api, const char *service, const char *verb, struct json_object *args, callback_func *f = nullptr)
+{
+    HMI_NOTICE("homescreen-service","service=%s verb=%s, args=%s.", service, verb, json_object_get_string(args));
+    afb_api_call(api, service, verb, args, api_callback, (void*)f);
+}
+
+/**
+ * call api synchronous
+ *
+ * #### Parameters
+ *  - api : the api serving the request
+ *  - service : the api name of service
+ *  - verb : the verb of afm-main
+ *  - args : parameter
+ *  - object : return the details of application
+ *
+ * #### Return
+ *  0 : success
+ *  1 : fail
+ *
+ */
+static int api_call_sync(afb_api_t api, const char *service, const char *verb, struct json_object *args, struct json_object **object)
+{
+    char *error = nullptr, *info = nullptr;
+    int ret = afb_api_call_sync(api, service, verb, args, object, &error, &info);
+    HMI_NOTICE("homescreen-service","synchronous call, error=%s, info=%s.", error, info);
+    return ret;
+}
+
+/**
+ * subscribe windowmanager event
+ *
+ * #### Parameters
+ *  - api : the api serving the request
+ *  - event : windowmanager event
+ *
+ * #### Return
+ *  None
+ *
+ */
+void HS_WmProxy::subscribe(afb_api_t api, EventType event)
+{
+    struct json_object* push_obj = json_object_new_object();
+    json_object_object_add(push_obj, _event, json_object_new_int(event));
+    api_call(api, _windowmanager, "wm_subscribe", push_obj);
+}
diff --git a/src/hs-proxy.h b/src/hs-proxy.h
new file mode 100644 (file)
index 0000000..eae80fc
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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_PROXY_H
+#define HOMESCREEN_PROXY_H
+
+#include <functional>
+#include "hs-helper.h"
+
+
+using callback_func = std::function<void(afb_api_t, json_object*)>;
+
+class HS_WmProxy {
+public:
+    HS_WmProxy() = default;
+    ~HS_WmProxy() = default;
+
+    enum EventType
+    {
+        Event_Val_Min = 0,
+
+        Event_Active = Event_Val_Min,
+        Event_Inactive,
+
+        Event_Visible,
+        Event_Invisible,
+
+        Event_SyncDraw,
+        Event_FlushDraw,
+
+        Event_ScreenUpdated,
+
+        Event_Error,
+
+        Event_Val_Max = Event_Error,
+    };
+
+    // asynchronous call, reply in callback function
+    void subscribe(afb_api_t api, EventType event);
+};
+
+#endif // HOMESCREEN_PROXY_H
\ No newline at end of file