recover application
authorwang_zhiqiang <wang_zhiqiang@dl.cn.nexty-ele.com>
Fri, 19 Apr 2019 08:27:49 +0000 (16:27 +0800)
committerwang_zhiqiang <wang_zhiqiang@dl.cn.nexty-ele.com>
Fri, 19 Apr 2019 08:27:49 +0000 (16:27 +0800)
Change-Id: I02330f9c9336609ce585ab172211acada68fba9c

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

index 7085bac..6baa3b3 100644 (file)
@@ -29,7 +29,8 @@ set(binding_hs_sources
   hs-client.cpp
   hs-proxy.cpp
   hs-appinfo.cpp
-  hs-config.cpp)
+  hs-config.cpp
+  hs-apprecover.cpp)
 
 link_libraries(-Wl,--as-needed -Wl,--gc-sections -Wl,--no-undefined)
 include_directories(${PROJECT_SOURCE_DIR}/include)
index 3e4ff8f..cb8a633 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #endif
+#include <unistd.h>
 #include <memory>
 #include <algorithm>
 #include <unordered_map>
@@ -25,7 +26,8 @@
 #include "hs-clientmanager.h"
 #include "hs-appinfo.h"
 #include "hs-config.h"
-#include <unistd.h>
+#include "hs-apprecover.h"
+
 
 
 const char _error[] = "error";
@@ -37,7 +39,7 @@ const char _keyId[] = "id";
 
 struct hs_handshake {
     hs_handshake(int times, int sleep) : m_times(times), m_sleep(sleep) {}
-    void start(afb_api_t api) const;
+    int start(afb_api_t api) const;
 
     enum HandshakeStatus {
         Handshake_Idle = 0,
@@ -56,6 +58,18 @@ private:
 
 int hs_handshake::hs_sts = hs_handshake::Handshake_Idle;
 
+/**
+ * handshake callback function
+ *
+ * #### Parameters
+ * - obj : reply json object
+ * - error : api_call error
+ * - info : api_call information
+ *
+ * #### Return
+ * None
+ *
+ */
 void handshake_subscribe_callback(struct json_object *obj, const char *error, const char *info)
 {
     if(error == nullptr) {
@@ -66,14 +80,39 @@ void handshake_subscribe_callback(struct json_object *obj, const char *error, co
     }
 }
 
+/**
+ * handshake event function
+ *
+ * #### 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 on_handshake_event(afb_api_t api, const char *event, struct json_object *object)
 {
     hs_handshake::hs_sts =  hs_handshake::Handshake_Over;
     return 1;
 }
 
-void hs_handshake::start(afb_api_t api) const
+/**
+ * start handshake function
+ *
+ * #### Parameters
+ * - api : the api
+ *
+ * #### Return
+ * None
+ * 0 : handshake success
+ * -1 : handshake fail
+ * 
+ */
+int hs_handshake::start(afb_api_t api) const
 {
+    int ret = -1;
     setEventHook(sub_event.c_str(), on_handshake_event);
     int count = 0;
     do {
@@ -81,19 +120,21 @@ void hs_handshake::start(afb_api_t api) const
         if(hs_handshake::hs_sts == hs_handshake::Handshake_Idle
         || hs_handshake::hs_sts == hs_handshake::Handshake_Subscribe_Fail) {
             hs_handshake::hs_sts = Handshake_Subscribing;
-            HS_WmProxy *wm_proxy = new HS_WmProxy();
-            wm_proxy->subscribe(api, HS_WmProxy::Event_Handshake, handshake_subscribe_callback);
+            HS_WmProxy wm_proxy;
+            wm_proxy.subscribe(api, HS_WmProxy::Event_Handshake, handshake_subscribe_callback);
         }
 
         // wait handshake event
         if(hs_handshake::hs_sts == hs_handshake::Handshake_Over) {
+            ret = 0;
             break;
         }
 
         ++count;
         usleep(m_sleep*1000);
     } while(count < m_times);
-    AFB_WARNING("wait count is %d.", count);
+
+    return ret;
 }
 
 struct hs_instance {
@@ -108,6 +149,8 @@ private:
     std::unordered_map<std::string, std::list<event_hook_func>> event_hook_list;
 };
 
+static struct hs_instance *g_hs_instance;
+
 /**
  * init function
  *
@@ -139,12 +182,20 @@ int hs_instance::init(afb_api_t api)
         return -1;
     }
 
-    // const struct handshake_info *h = hs_config.getHandshakeInfo();
-    // struct hs_handshake handshake(h->times, h->sleep);
-    // handshake.start(api);
-
-    // recover application
+    const struct handshake_info *h = hs_config.getHandshakeInfo();
+    struct hs_handshake handshake(h->times, h->sleep);
+    if(handshake.start(api) < 0) {
+        AFB_ERROR("handshake with windowmanager failed.");
+        return -1;
+    }
 
+    HS_AppRecover *app_recover = new HS_AppRecover();
+    if(app_recover == nullptr) {
+        AFB_ERROR("app_recover is nullptr.");
+        return -1;
+    }
+    app_recover->startRecovery(api, hs_config.getRecoverMap());
+    client_manager->setAppRecover(app_recover);
 
     return 0;
 }
@@ -201,8 +252,6 @@ void hs_instance::onEvent(afb_api_t api, const char *event, struct json_object *
     }
 }
 
-static struct hs_instance *g_hs_instance;
-
 /**
  * set event hook
  *
@@ -258,7 +307,7 @@ static void tap_shortcut (afb_req_t request)
         if(ret == AFB_REQ_NOT_STARTED_APPLICATION) {
             std::string id = g_hs_instance->app_info->getAppProperty(value, _keyId);
             HS_AfmMainProxy afm_proxy;
-            afm_proxy.start(request, id);
+            afm_proxy.start(request->api, id);
             ret = 0;
         }
     }
@@ -415,7 +464,7 @@ static void showWindow(afb_req_t request)
         if(ret == AFB_REQ_NOT_STARTED_APPLICATION) {
             std::string id = g_hs_instance->app_info->getAppProperty(value, _keyId);
             HS_AfmMainProxy afm_proxy;
-            afm_proxy.start(request, id);
+            afm_proxy.start(request->api, id);
             ret = 0;
         }
     }
diff --git a/src/hs-apprecover.cpp b/src/hs-apprecover.cpp
new file mode 100644 (file)
index 0000000..8e5545c
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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-apprecover.h"
+#include "hs-appinfo.h"
+#include "hs-proxy.h"
+#include "hs-clientmanager.h"
+
+const char _keyArea[] = "area";
+
+/**
+ * starting recover applications
+ *
+ * #### Parameters
+ *  - api : the api
+ *  - map : recover app map
+ *
+ * #### Return
+ * None
+ *
+ */
+void HS_AppRecover::startRecovery(afb_api_t api, recover_map &map)
+{
+    HS_AfmMainProxy afm_proxy;
+    for(auto &key : HS_Config::keys_recover_type) {
+        for(auto &m : map[key]){
+            struct app_recover_info recover_info;
+            recover_info.recover_type = key;
+            recover_info.area = m.area;
+            recover_info.visibility = m.visibility;
+            m_recover_apps_list[m.appid] = std::move(recover_info);
+
+            // recover application
+            m_recovering_set.insert(m.appid);
+            afm_proxy.start(api,  HS_AppInfo::instance()->getAppProperty(m.appid, _keyId));
+        }
+    }
+}
+
+/**
+ * register started applications
+ *
+ * #### Parameters
+ *  - appid : application id liked "dashboard"
+ *
+ * #### Return
+ * false : not all application recovered
+ * true : all applications recovered
+ */
+bool HS_AppRecover::registerRecoveredApp(std::string &appid)
+{
+    auto it = m_recovering_set.find(appid);
+    if(it != m_recovering_set.end()) {
+        m_recovering_set.erase(appid);
+        auto ip = m_recover_apps_list.find(appid);
+        if(ip != m_recover_apps_list.end()
+        && ip->second.visibility) {
+            // TBD, call setWindowResource
+            struct json_object *push_obj = json_object_new_object();
+            json_object_object_add(push_obj, _keyArea, json_object_new_string(ip->second.area.c_str()));
+            HS_ClientManager::instance()->pushEvent("showWindow", push_obj, appid);
+        }
+    }
+
+    return m_recovering_set.empty() ? true : false;
+}
\ No newline at end of file
diff --git a/src/hs-apprecover.h b/src/hs-apprecover.h
new file mode 100644 (file)
index 0000000..52ba38b
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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_APPRECOVER_H
+#define HOMESCREEN_APPRECOVER_H
+
+#include <map>
+#include <set>
+#include "hs-helper.h"
+#include "hs-config.h"
+
+struct app_recover_info {
+    std::string recover_type;
+    std::string area;
+    bool visibility;
+};
+
+class HS_AppRecover {
+public:
+    HS_AppRecover() = default;
+    ~HS_AppRecover() = default;
+    HS_AppRecover(HS_AppRecover const &) = delete;
+    HS_AppRecover &operator=(HS_AppRecover const &) = delete;
+    HS_AppRecover(HS_AppRecover &&) = delete;
+    HS_AppRecover &operator=(HS_AppRecover &&) = delete;
+
+    void startRecovery(afb_api_t api, recover_map &map);
+    bool registerRecoveredApp(std::string &appid);
+
+private:
+
+    std::map<std::string, struct app_recover_info> m_recover_apps_list;
+    std::set<std::string> m_recovering_set;
+};
+
+#endif // HOMESCREEN_APPRECOVER_H
\ No newline at end of file
index 1f8bc81..4a17b72 100644 (file)
@@ -37,7 +37,7 @@ static void cbRemoveClientCtxt(void *data)
  * None
  *
  */
-HS_ClientManager::HS_ClientManager()
+HS_ClientManager::HS_ClientManager() : app_recover(nullptr)
 {
 }
 
@@ -187,6 +187,7 @@ int HS_ClientManager::handleRequest(afb_req_t request, const char *verb, const c
                 appid2ctxt[appid] = createClientCtxt(request, appid);
                 HS_Client* client = addClient(request, appid);
                 ret = client->handleRequest(request, "subscribe");
+                registerApplication(appid);
             }
             else {
                 AFB_NOTICE("not exist session");
@@ -231,4 +232,22 @@ int HS_ClientManager::pushEvent(const char *event, struct json_object *param, st
     }
 
     return 0;
+}
+
+/**
+ * register recovered application
+ *
+ * #### Parameters
+ *  - appid : application id
+ *
+ * #### Return
+ * None
+ *
+ */
+void HS_ClientManager::registerApplication(std::string appid)
+{
+    if(app_recover != nullptr && app_recover->registerRecoveredApp(appid)) {
+        delete app_recover;
+        app_recover = nullptr;
+    }
 }
\ No newline at end of file
index efc36de..af5b4c8 100644 (file)
@@ -23,6 +23,7 @@
 #include <unordered_map>
 #include "hs-helper.h"
 #include "hs-client.h"
+#include "hs-apprecover.h"
 
 typedef struct HS_ClientCtxt
 {
@@ -48,17 +49,20 @@ public:
     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
+    void setAppRecover(HS_AppRecover *recover) {app_recover = recover;}
 
 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 registerApplication(std::string appid);
 
 private:
     static HS_ClientManager* me;
     std::unordered_map<std::string, HS_Client*> client_list;
     std::unordered_map<std::string, HS_ClientCtxt*> appid2ctxt;
     std::mutex mtx;
+    HS_AppRecover *app_recover;
 };
 
 #endif // HOMESCREEN_CLIENTMANAGER_H
\ No newline at end of file
index dad3a7e..17b086a 100644 (file)
 
 #include "hs-config.h"
 
+const std::array<std::string, 3> HS_Config::keys_recover_type = {   // based on hs-conf.json
+    "hs-apps",
+    "default-lastmode",
+    "normal-apps"
+};
 
 /**
  * read configuration file to memory
index a81a660..849dc4f 100644 (file)
@@ -21,6 +21,8 @@
 #include <unordered_map>
 #include "hs-helper.h"
 
+#define RECOVER_MAX 3
+
 struct handshake_info {
     int times;    // sleep times
     int sleep;    // sleep x ms
@@ -45,7 +47,8 @@ public:
 
     int readConfig(void);
     const struct handshake_info* getHandshakeInfo(void) const {return &m_handshake_info;}
-    const recover_map* getRecoverMap(void) const {return &m_recover_map;}
+    recover_map& getRecoverMap(void) {return m_recover_map;}
+    static const std::array<std::string, RECOVER_MAX> keys_recover_type;   // based on hs-conf.json
 
 private:
     int parseConfig(void);
@@ -60,11 +63,6 @@ private:
     const std::string key_appid = "appid";
     const std::string key_visibility = "visibility";
     const std::string key_area = "area";
-    const std::array<std::string, 3> keys_recover_type = {   // based on hs-conf.json
-        "hs-apps",
-        "default-lastmode",
-        "normal-apps"
-    };
 
     struct json_object *m_hs_conf;
     struct json_object *m_lastmode;
index 1a237d7..718f6ff 100644 (file)
@@ -126,17 +126,17 @@ int HS_AfmMainProxy::detail(afb_api_t api, const std::string &id, struct json_ob
  * start application
  *
  * #### Parameters
- *  - request : the request
+ *  - api : the api
  *  - id : the application id liked "dashboard@0.1"
  *
  * #### Return
  *  None
  *
  */
-void HS_AfmMainProxy::start(afb_req_t request, const std::string &id)
+void HS_AfmMainProxy::start(afb_api_t api, const std::string &id)
 {
     struct json_object *args = json_object_new_string(id.c_str());
-    api_call(request->api, _afm_main, __FUNCTION__, args);
+    api_call(api, _afm_main, __FUNCTION__, args);
 }
 
 /* -------------------------------------HS_WmProxy------------------------------------------ */
index 1c9a67d..a0acf10 100644 (file)
@@ -31,7 +31,7 @@ public:
     int detail(afb_api_t api, const std::string &id, struct json_object **object);
 
     // asynchronous call, reply in callback function
-    void start(afb_req_t request, const std::string &id);
+    void start(afb_api_t api, const std::string &id);
 };
 
 class HS_WmProxy {