X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fhs-apprecover.cpp;h=472a9fc8ebda0b6135822450a5372867c79e97d4;hb=de4ff7944811d8ad7ef0bd95c032df953034bab3;hp=9bd0cf285f48ac3907329efeaa608e7092a79bfc;hpb=f11aba0409610b3f6873006752579690225ca4be;p=apps%2Fagl-service-homescreen.git diff --git a/src/hs-apprecover.cpp b/src/hs-apprecover.cpp index 9bd0cf2..472a9fc 100644 --- a/src/hs-apprecover.cpp +++ b/src/hs-apprecover.cpp @@ -19,7 +19,63 @@ #include "hs-proxy.h" #include "hs-clientmanager.h" -const char _keyArea[] = "area"; + +HS_AppRecover* HS_AppRecover::me = nullptr; + +/** + * screen_update 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 on_screen_update_event(afb_api_t api, const char *event, struct json_object *object) +{ + HS_AppRecover::instance()->screenUpdated(object); + return 0; +} + +/** + * get instance + * + * #### Parameters + * - Nothing + * + * #### Return + * HS_AppRecover instance pointer + * + */ +HS_AppRecover* HS_AppRecover::instance(void) +{ + if(me == nullptr) + me = new HS_AppRecover(); + + return me; +} + +/** + * HS_AppRecover initialize function + * + * #### Parameters + * - api : the api serving the request + * + * #### Return + * 0 : init success + * 1 : init fail + * + */ +int HS_AppRecover::init(afb_api_t api) +{ + setEventHook("windowmanager/screenUpdated", on_screen_update_event); + HS_WmProxy wm_proxy; + wm_proxy.subscribe(api, HS_WmProxy::Event_ScreenUpdated); + return 0; +} /** * starting recover applications @@ -32,37 +88,60 @@ const char _keyArea[] = "area"; * None * */ -void HS_AppRecover::startRecovery(afb_api_t api, recover_map &map) +void HS_AppRecover::startRecovery(afb_api_t api) { - HS_AfmMainProxy afm_proxy; + HS_ClientManager::instance()->addListener(this); + 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.visibility = m.visibility; + for(auto &m : recover_app_map[key]){ + struct app_recover_info recover_info = { + .recover_type = key, + .visibility = m.visibility, + .after = m.after + }; 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)); + auto it = m_recovering_set.find(m.appid); + if(it == m_recovering_set.end()) { + m_recovering_set.insert(m.appid); + std::string &after = m_recover_apps_list[m.appid].after; + if(!after.empty()) { + auto w = m_wait_recover_set.find(m_recover_apps_list[m.appid].after); + if(w != m_wait_recover_set.end()) { + m_wait_recover_set[after].insert(m.appid); + } + else { + std::set new_set; + new_set.insert(m.appid); + m_wait_recover_set[after] = std::move(new_set); + } + continue; // don't immediately start application, wait until after applicaiton started. + } + startApplication(api, m.appid); + } } } + recover_app_map.clear(); } /** - * register started applications + * notify * * #### Parameters - * - appid : application id liked "dashboard" + * - api : the api + * - appid : application id * * #### Return - * false : not all application recovered - * true : all applications recovered + * None + * */ -bool HS_AppRecover::registerRecoveredApp(std::string &appid) +void HS_AppRecover::notify(afb_api_t api, std::string appid) { + AFB_INFO("recover appid=[%s].", appid.c_str()); auto it = m_recovering_set.find(appid); if(it != m_recovering_set.end()) { + this->removeListenAppId(appid); m_recovering_set.erase(appid); auto ip = m_recover_apps_list.find(appid); if(ip != m_recover_apps_list.end() @@ -71,5 +150,136 @@ bool HS_AppRecover::registerRecoveredApp(std::string &appid) } } - return m_recovering_set.empty() ? true : false; + // check wait recover application + auto w = m_wait_recover_set.find(appid); + if(w != m_wait_recover_set.end()) { + for(auto &ref : m_wait_recover_set[appid]) { + startApplication(api, ref); + } + m_wait_recover_set.erase(appid); + } + + if(m_recovering_set.empty()) { + clearListenAppSet(); + // HS_ClientManager::instance()->removeListener(this); + } +} + +/** + * screenUpdated event handler + * + * #### Parameters + * - obj : screenUpdate object + * + * #### Return + * None + * + */ +void HS_AppRecover::screenUpdated(struct json_object *obj) +{ + if(m_lastmode_list.empty()) { + AFB_NOTICE("init lastmode is null, so don't record lastmode."); + return; + } + + std::set s_mode; + struct json_object *ids_obj; + if(json_object_object_get_ex(obj, key_ids.c_str(), &ids_obj)) { + if(json_object_get_type(ids_obj) == json_type_array) { + int array_len = json_object_array_length(ids_obj); + for (int i = 0; i < array_len; ++i) { + struct json_object *j_id = json_object_array_get_idx(ids_obj, i); + std::string appid = json_object_get_string(j_id); + if(!isHomescreenApp(appid)) { + s_mode.insert(appid); + } + } + if(!s_mode.empty()) { + updateLastmode(s_mode); + } + } + else { + AFB_WARNING("screenUpdated list isn't array."); + } + } +} + +/** + * start application + * + * #### Parameters + * - api : the api + * - appid : application id liked "dashboard" + * + * #### Return + * None + * + */ +void HS_AppRecover::startApplication(afb_api_t api, const std::string &appid) +{ + this->addListenAppId(appid); + HS_AfmMainProxy afm_proxy; + afm_proxy.start(api, HS_AppInfo::instance()->getAppProperty(appid, _keyId)); +} + +/** + * update lastmode file + * + * #### Parameters + * - set : new lastmode set + * + * #### Return + * None + * + */ +void HS_AppRecover::updateLastmode(std::set &set) +{ + if(set.size() == m_lastmode_list.size()) { + bool is_same = true; + for(auto &m : set) { + auto it = m_lastmode_list.find(m); + if(it == m_lastmode_list.end()) { + is_same = false; + break; + } + } + if(is_same) { // lastmode aren't changed + return; + } + } + + m_lastmode_list.swap(set); + struct json_object *arr_obj = json_object_new_array(); + for(auto &it : m_lastmode_list) { + struct json_object *j_obj = json_object_new_object(); + json_object_object_add(j_obj, HS_Config::key_appid.c_str(), json_object_new_string(it.c_str())); + json_object_object_add(j_obj, HS_Config::key_visibility.c_str(), json_object_new_string("visible")); + json_object_array_add(arr_obj, j_obj); + } + + auto path = HS_Config::root_dir + "/etc/" + HS_Config::lastmode_json; + if(writeJsonFile(path.c_str(), arr_obj) < 0) { + AFB_ERROR("write lastmode error."); + } +} + +/** + * judge whether app is Homescreen app + * + * #### Parameters + * - appid : application id + * + * #### Return + * true : homescreen app + * false : not homescreen app + * + */ +bool HS_AppRecover::isHomescreenApp(const std::string &appid) const +{ + auto it = m_recover_apps_list.find(appid); + if(it != m_recover_apps_list.end() + && it->second.recover_type == HS_Config::keys_recover_type[0]) { + return true; + } + return false; } \ No newline at end of file