From: wang_zhiqiang Date: Fri, 19 Apr 2019 08:27:49 +0000 (+0800) Subject: recover application X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?p=apps%2Fagl-service-homescreen.git;a=commitdiff_plain;h=f16e0728c0c9806d9a7c3766028428ed73b5a8cf recover application Change-Id: I02330f9c9336609ce585ab172211acada68fba9c --- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7085bac..6baa3b3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/homescreen.cpp b/src/homescreen.cpp index 3e4ff8f..cb8a633 100644 --- a/src/homescreen.cpp +++ b/src/homescreen.cpp @@ -17,6 +17,7 @@ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif +#include #include #include #include @@ -25,7 +26,8 @@ #include "hs-clientmanager.h" #include "hs-appinfo.h" #include "hs-config.h" -#include +#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> 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 index 0000000..8e5545c --- /dev/null +++ b/src/hs-apprecover.cpp @@ -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 index 0000000..52ba38b --- /dev/null +++ b/src/hs-apprecover.h @@ -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 +#include +#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 m_recover_apps_list; + std::set m_recovering_set; +}; + +#endif // HOMESCREEN_APPRECOVER_H \ No newline at end of file diff --git a/src/hs-clientmanager.cpp b/src/hs-clientmanager.cpp index 1f8bc81..4a17b72 100644 --- a/src/hs-clientmanager.cpp +++ b/src/hs-clientmanager.cpp @@ -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 diff --git a/src/hs-clientmanager.h b/src/hs-clientmanager.h index efc36de..af5b4c8 100644 --- a/src/hs-clientmanager.h +++ b/src/hs-clientmanager.h @@ -23,6 +23,7 @@ #include #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 client_list; std::unordered_map appid2ctxt; std::mutex mtx; + HS_AppRecover *app_recover; }; #endif // HOMESCREEN_CLIENTMANAGER_H \ No newline at end of file diff --git a/src/hs-config.cpp b/src/hs-config.cpp index dad3a7e..17b086a 100644 --- a/src/hs-config.cpp +++ b/src/hs-config.cpp @@ -17,6 +17,11 @@ #include "hs-config.h" +const std::array HS_Config::keys_recover_type = { // based on hs-conf.json + "hs-apps", + "default-lastmode", + "normal-apps" +}; /** * read configuration file to memory diff --git a/src/hs-config.h b/src/hs-config.h index a81a660..849dc4f 100644 --- a/src/hs-config.h +++ b/src/hs-config.h @@ -21,6 +21,8 @@ #include #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 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 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; diff --git a/src/hs-proxy.cpp b/src/hs-proxy.cpp index 1a237d7..718f6ff 100644 --- a/src/hs-proxy.cpp +++ b/src/hs-proxy.cpp @@ -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------------------------------------------ */ diff --git a/src/hs-proxy.h b/src/hs-proxy.h index 1c9a67d..a0acf10 100644 --- a/src/hs-proxy.h +++ b/src/hs-proxy.h @@ -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 {