#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
* 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<std::string> 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()
}
}
- 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<std::string> 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<std::string> &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