From: Youngjae Shin Date: Mon, 21 Oct 2019 00:00:18 +0000 (+0900) Subject: apply permanent caretaker X-Git-Tag: submit/tizen/20200319.043412~47 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ebecbe95fc5ae23049d062bf8e9f9026cf8c6c0d;p=platform%2Fcore%2Fsystem%2Fmodes.git apply permanent caretaker --- diff --git a/Definitions.cmake b/Definitions.cmake index cb432d0..2c936ff 100644 --- a/Definitions.cmake +++ b/Definitions.cmake @@ -33,3 +33,9 @@ IF(NOT DEFINED MODES_XSD_DEFAULT_DIR) SET(MODES_XSD_DEFAULT_DIR "/usr/share/modes/schema") ENDIF(NOT DEFINED MODES_XSD_DEFAULT_DIR) ADD_DEFINITIONS("-DMODES_XSD_DEFAULT_DIR=\"${MODES_XSD_DEFAULT_DIR}\"") + +IF(NOT DEFINED MODES_UNDO_INFO_DEFAULT_DIR) + MESSAGE("No MODES_UNDO_INFO_DEFAULT_DIR. Check build system") + SET(MODES_UNDO_INFO_DEFAULT_DIR "/var/lib/modes/undo-info") +ENDIF(NOT DEFINED MODES_UNDO_INFO_DEFAULT_DIR) +ADD_DEFINITIONS("-DMODES_UNDO_INFO_DEFAULT_DIR=\"${MODES_UNDO_INFO_DEFAULT_DIR}\"") diff --git a/common/definitions.h b/common/definitions.h index 26d5314..78083bb 100644 --- a/common/definitions.h +++ b/common/definitions.h @@ -54,6 +54,11 @@ #warning "MODES_XSD_DEFAULT_DIR is redefined" #endif +#ifndef MODES_UNDO_INFO_DEFAULT_DIR +#define MODES_UNDO_INFO_DEFAULT_DIR "/var/lib/modes/undo-info" +#warning "MODES_UNDO_INFO_DEFAULT_DIR is redefined" +#endif + #define MODES_MODE_DEFAULT_XSD_FILE "tizen_mode.xsd" #define MODES_ACTIONRULE_DEFAULT_XSD_FILE "tizen_action_rule.xsd" #define MODES_MODE_DEFAULT_XSD MODES_XSD_DEFAULT_DIR "/" MODES_MODE_DEFAULT_XSD_FILE @@ -62,3 +67,5 @@ #define MODES_PLUGIN_LIB_PREFIX "libmodes-plugin" #define MODES_ACTIONRULE_FILE_SUFFIX "_rule.xml" #define MODES_MODE_FILE_SUFFIX "_mode.xml" + +#define MODES_UNDO_FILE_SUFFIX "_undo.xml" diff --git a/include/Plugin.h b/include/Plugin.h index 2f8a5d8..4d98c83 100644 --- a/include/Plugin.h +++ b/include/Plugin.h @@ -67,6 +67,14 @@ namespace ModeSupervisorNamespace { return ret; } + virtual PluginAction* getUndoAction(const std::string &key, const std::string &info) + { + return nullptr; + } + virtual int serializeAction(PluginAction *pluginAction, std::string *output) + { + return MODES_ERROR_NOT_SUPPORTED; + } void freeAction(PluginAction *pluginAction) { delete pluginAction; diff --git a/include/PluginAction.h b/include/PluginAction.h index cad479c..b564218 100644 --- a/include/PluginAction.h +++ b/include/PluginAction.h @@ -33,6 +33,14 @@ namespace ModeSupervisorNamespace { { return MODES_ERROR_NOT_SUPPORTED; } + virtual int serialize(std::string *output) + { + return MODES_ERROR_NOT_SUPPORTED; + } + virtual int parse(const std::string &data) + { + return MODES_ERROR_NOT_SUPPORTED; + } protected: void setName(const std::string &actionName) { diff --git a/packaging/modes.spec b/packaging/modes.spec index 0112a14..e2a8cfc 100644 --- a/packaging/modes.spec +++ b/packaging/modes.spec @@ -60,6 +60,7 @@ The %{name}-unittests pacakge contains programs for checking quality the %{name} %define modes_plugin_dir %{_libdir}/modes-plugins %define modes_data_dir %{_datadir}/%{name} %define modes_test_dir %{_bindir}/%{name} +%define modes_info_dir /var/lib/%{name} %prep %setup -q @@ -82,6 +83,7 @@ MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` -DSYSTEMD_DIR:PATH=%{_unitdir} \ -DSYSCONF_DIR:PATH=%{_sysconfdir} \ -DMODES_MODE_DEFAULT_DIR:PATH=%{modes_data_dir}/mode \ + -DMODES_UNDO_INFO_DEFAULT_DIR:PATH=%{modes_info_dir}/undo-info \ -DMODES_CUSTOM_MODE_DEFAULT_DIR:PATH=%{modes_data_dir}/custom-mode \ -DMODES_ACTIONRULE_DEFAULT_DIR:PATH=%{modes_data_dir}/rule \ -DMODES_XSD_DEFAULT_DIR:PATH=%{modes_data_dir}/schema \ @@ -96,6 +98,7 @@ make %{?_smp_mflags} install -d -m 755 %{buildroot}%{modes_data_dir}/mode install -d -m 755 %{buildroot}%{modes_data_dir}/rule install -d -m 755 %{buildroot}%{modes_data_dir}/custom-mode +install -d -m 755 %{buildroot}%{modes_info_dir}/undo-info install -m 0644 example/mode/*ex*_mode.xml %{buildroot}%{modes_data_dir}/mode/ install -m 0644 example/rule/*ex*_rule.xml %{buildroot}%{modes_data_dir}/rule/ install -m 0644 example/mode/*conflict*_mode.xml %{buildroot}%{modes_test_dir}/ @@ -126,7 +129,6 @@ rm -rf %{modes_test_dir}/*ex*.xml %{modes_test_dir}/*.xsd %{modes_test_dir}/extr systemctl restart %{name}.service %files -%attr(0755,system_fw,system_fw) %{modes_data_dir}/custom-mode %manifest %{name}.manifest %{_bindir}/mode-supervisor %{_unitdir}/%{name}.service @@ -135,7 +137,10 @@ systemctl restart %{name}.service %{modes_data_dir}/schema/* %dir %{modes_data_dir}/mode %dir %{modes_data_dir}/rule +%dir %{modes_info_dir}/undo-info +%attr(0755,system_fw,system_fw) %{modes_info_dir}/undo-info %dir %{modes_data_dir}/custom-mode +%attr(0755,system_fw,system_fw) %{modes_data_dir}/custom-mode %license LICENSE.APLv2 %files lib diff --git a/plugin/TestPlugin.cpp b/plugin/TestPlugin.cpp index a576559..ab22bcd 100644 --- a/plugin/TestPlugin.cpp +++ b/plugin/TestPlugin.cpp @@ -35,6 +35,8 @@ public: int set(const std::string &key, const std::string &val, PluginAction **pluginAction) override; int undo(PluginAction *pluginAction) override; + PluginAction* getUndoAction(const std::string &key, const std::string &info) override; + int serializeAction(PluginAction *pluginAction, std::string *output) override; int getInt(const std::string &key) override; double getDouble(const std::string &key) override; @@ -120,6 +122,28 @@ int TestPlugin::undo(PluginAction *pluginAction) return MODES_ERROR_NONE; } +PluginAction* TestPlugin::getUndoAction(const std::string &key, const std::string &info) +{ + // parse the key for making PluginAction + TestPluginAction *piAction = new TestPluginAction(); + piAction->parse(info); + + return piAction; +} + +int TestPlugin::serializeAction(PluginAction *piAction, std::string *output) +{ + RETV_IF(nullptr == piAction, MODES_ERROR_INVALID_PARAMETER); + + int ret = piAction->serialize(output); + if (MODES_ERROR_NONE != ret) { + ERR("serialize() Fail(%d)", ret); + return ret; + } + + return MODES_ERROR_NONE; +} + int TestPlugin::getInt(const std::string &key) { DBG("TestPlugin::getInt(%s)", key.c_str()); diff --git a/plugin/TestPluginAction.cpp b/plugin/TestPluginAction.cpp index 81b2658..2c4d519 100644 --- a/plugin/TestPluginAction.cpp +++ b/plugin/TestPluginAction.cpp @@ -16,6 +16,7 @@ #include "TestPluginAction.h" #include "modes_errors.h" +#include "common/log.h" #include "common/definitions.h" MODES_NAMESPACE_USE; @@ -31,5 +32,18 @@ TestPluginAction::~TestPluginAction() int TestPluginAction::undo() { + DBG("TestPluginAction::undo() is Called"); + return MODES_ERROR_NONE; +} + +int TestPluginAction::serialize(std::string *output) +{ + *output = "testAction"; + return MODES_ERROR_NONE; +} + +int TestPluginAction::parse(const std::string &info) +{ + DBG("serialized info(%s)", info.c_str()); return MODES_ERROR_NONE; } diff --git a/plugin/TestPluginAction.h b/plugin/TestPluginAction.h index 41caeeb..4664242 100644 --- a/plugin/TestPluginAction.h +++ b/plugin/TestPluginAction.h @@ -27,6 +27,8 @@ public: ~TestPluginAction() override; int undo() override; + int serialize(std::string *output) override; + int parse(const std::string &data) override; }; MODES_NAMESPACE_END diff --git a/supervisor/Action.cpp b/supervisor/Action.cpp index 52d7735..0429030 100644 --- a/supervisor/Action.cpp +++ b/supervisor/Action.cpp @@ -47,7 +47,7 @@ Action::~Action() void Action::printInfo() { - DBG("Action(%s):ID(%s), Restrict(%d)", getRuleName().c_str(), getID().c_str(), getRestrict()); + DBG("Action(%s):ID(%s), Restrict(%d) piAction(%p)", getRuleName().c_str(), getID().c_str(), getRestrict(), piAction); } void Action::setRuleName(const std::string &data) diff --git a/supervisor/Action.h b/supervisor/Action.h index ac8c184..a44e3ad 100644 --- a/supervisor/Action.h +++ b/supervisor/Action.h @@ -50,7 +50,8 @@ public: virtual int apply() = 0; virtual int applyOneShot() = 0; virtual void undo() = 0; - + virtual int restoreUndoInfo(const std::string &info) = 0; + virtual std::string backupUndoInfo() = 0; protected: std::string ruleName; Plugin *plugin; diff --git a/supervisor/ArgumentParser.cpp b/supervisor/ArgumentParser.cpp index f3bcf22..a0fca3b 100644 --- a/supervisor/ArgumentParser.cpp +++ b/supervisor/ArgumentParser.cpp @@ -28,13 +28,14 @@ char ArgumentParser::argp_doc[] = char ArgumentParser::args_doc[] = "modeXMLDirPath1 [modeXMLDirPath2] [--pluginDir=../plugin]" " [--modeXsdFilePath=..example/tizen_mode.xsd] [--ruleXsdFilePath=..example/tizen_rule.xsd]" - " [--ruleDir=../example] [--[--help]"; + " [--ruleDir=../example] [--undoInfoDir=../example] [--[--help]"; struct argp_option ArgumentParser::options[] = { {"pluginDir", 'p', "pluginDirPath", OPTION_ARG_OPTIONAL, "Set directory of plugin"}, {"modeXsdFilePath", 'm', "modeXsdFilePath", OPTION_ARG_OPTIONAL, "Set mode xsd(schema) file path"}, {"ruleXsdFilePath", 'a', "actionRuleXsdFilePath", OPTION_ARG_OPTIONAL, "Set action rule xsd(schema) file path"}, {"ruleDir", 's', "actionRuleDirPath", OPTION_ARG_OPTIONAL, "Set directory of Action Rule file"}, + {"undoInfoDir", 'u', "UndoInfoDirPath", OPTION_ARG_OPTIONAL, "Set directory of Undo Information file"}, { 0 } }; @@ -72,6 +73,13 @@ error_t ArgumentParser::parse_opt(int key, char *arg, struct argp_state *state) state->next++; } break; + case 'u': + nextArg = state->argv[state->next]; + if (nextArg && *nextArg != '-') { + parser->undoInfoDir = nextArg; + state->next++; + } + break; case ARGP_KEY_NO_ARGS: if (parser->modeDirCount == 0) argp_usage(state); @@ -92,7 +100,7 @@ struct argp ArgumentParser::argp_input = {options, parse_opt, args_doc, argp_doc ArgumentParser::ArgumentParser() :modeDirCount(0), modeXMLDirList(NULL), modeXsdFile(NULL), - actionRuleDir(NULL), actionRuleXsdFile(NULL), pluginDir(NULL) + actionRuleDir(NULL), actionRuleXsdFile(NULL), pluginDir(NULL), undoInfoDir(NULL) { } @@ -139,5 +147,12 @@ ModesConfig ArgumentParser::parse(int argc, char **argv) config.pluginDir = MODES_PLUGIN_DEFAULT_DIR; } + if (this->undoInfoDir) { + DBG("undoInfo dir path : %s", this->undoInfoDir); + config.undoInfoDir = this->undoInfoDir; + } else { + config.undoInfoDir = MODES_UNDO_INFO_DEFAULT_DIR; + } + return config; } diff --git a/supervisor/ArgumentParser.h b/supervisor/ArgumentParser.h index 9c78288..05126dc 100644 --- a/supervisor/ArgumentParser.h +++ b/supervisor/ArgumentParser.h @@ -33,6 +33,7 @@ private: char *actionRuleDir; char *actionRuleXsdFile; char *pluginDir; + char *undoInfoDir; static char argp_doc[]; static char args_doc[]; diff --git a/supervisor/Mode.h b/supervisor/Mode.h index a53e638..7cdf99b 100644 --- a/supervisor/Mode.h +++ b/supervisor/Mode.h @@ -49,6 +49,8 @@ public: void addUndo(Action *action); std::list> getUndoList() const; + void addUndoInfo(const std::string &rule, const std::string &info); + int apply(); int applyOneShot(); void undo(); diff --git a/supervisor/ModeCareTaker.cpp b/supervisor/ModeCareTaker.cpp index 045a998..0a97450 100644 --- a/supervisor/ModeCareTaker.cpp +++ b/supervisor/ModeCareTaker.cpp @@ -16,21 +16,36 @@ #include "ModeCareTaker.h" #include "mdss.h" +#include "XMLGenerator.h" MODES_NAMESPACE_USE; ModeCareTaker::ModeCareTaker() - : exclusive(false) + : undoDir(MODES_UNDO_INFO_DEFAULT_DIR), exclusive(false) { } -void ModeCareTaker::saveMode(const Mode &mode) +void ModeCareTaker::setOptions(const std::string &undoInfoDir) +{ + undoDir = undoInfoDir; +} + +void ModeCareTaker::restoreMode(const Mode &mode) +{ + savedModes.insert(std::pair(mode.getName(), mode)); + exclusive = (Mode::MODE_EXCLUSIVE == mode.getModeType()); +} + +void ModeCareTaker::pushMode(const Mode &mode) { savedModes.insert(std::pair(mode.getName(), mode)); exclusive = (Mode::MODE_EXCLUSIVE == mode.getModeType()); + + XMLGenerator gen; + gen.makeUndoInfoXML(undoDir + "/tizen_" + mode.getName() + MODES_UNDO_FILE_SUFFIX, mode); } -int ModeCareTaker::undoMode(const std::string &name) +int ModeCareTaker::popMode(const std::string &name, Mode &mode) { auto found = savedModes.find(name); if (savedModes.end() == found) { @@ -38,10 +53,13 @@ int ModeCareTaker::undoMode(const std::string &name) return MODES_ERROR_NO_DATA; } - Mode &mode = found->second; + std::string filePath = undoDir + "/tizen_" + name + MODES_UNDO_FILE_SUFFIX; + if (0 != remove(filePath.c_str())) + ERR("remove(%s) Fail(%s)", filePath.c_str(), strerror(errno)); + + mode = found->second; if (Mode::MODE_EXCLUSIVE == mode.getModeType()) exclusive = false; - mode.undo(); savedModes.erase(found); diff --git a/supervisor/ModeCareTaker.h b/supervisor/ModeCareTaker.h index c95a467..e871be2 100644 --- a/supervisor/ModeCareTaker.h +++ b/supervisor/ModeCareTaker.h @@ -27,14 +27,17 @@ public: ModeCareTaker(); ~ModeCareTaker() = default; - void saveMode(const Mode &mode); - int undoMode(const std::string &name); + void setOptions(const std::string &undoInfoDir); + void restoreMode(const Mode &mode); + void pushMode(const Mode &mode); + int popMode(const std::string &name, Mode &mode); bool isSavedMode(const std::string &name); bool isExclusive(); bool checkConflictAction(const Mode &mode); private: bool findRestrictAction(const std::string &ruleName); std::map savedModes; + std::string undoDir; bool exclusive; }; diff --git a/supervisor/ModeManager.cpp b/supervisor/ModeManager.cpp index 337261f..6658fe1 100644 --- a/supervisor/ModeManager.cpp +++ b/supervisor/ModeManager.cpp @@ -22,6 +22,7 @@ #include "mdss.h" #include "ModesEx.h" #include "ModeXMLParser.h" +#include "UndoInfoParser.h" #include "XMLGenerator.h" #include "ConflictManager.h" @@ -33,6 +34,15 @@ ModeManager::ModeManager(RuleManager &rMgr, PluginManager &pMgr) { } +//it should be called before init() +void ModeManager::setOptions(const std::set &modeDirs, const string &xsdFile, const string &undoInfoDir) +{ + modeDirList = modeDirs; + modeSyntaxFile = xsdFile; + undoDir = undoInfoDir; + careTaker.setOptions(undoDir); +} + //it should be called after setOption() void ModeManager::init() { @@ -42,13 +52,15 @@ void ModeManager::init() makeModeMap(*it); DBG("Mode Directory(%s) added", it->c_str()); } + restoreUndoInfo(undoDir); } // TODO: apply better polymorphism ModeParser* ModeManager::getModeParser(const string &path) { - int pos = path.find_last_of("."); - if (MDS_EQUAL == path.substr(pos + 1).compare("xml")) { + const size_t suffixLen = sizeof("xml") - 1; + if (suffixLen < path.length() + || path.compare(path.length() - suffixLen, suffixLen, "xml")) { return new ModeXMLParser(path, ruleMgr, pluginMgr); } else { ERR("Wrong path(%s)", path.c_str()); @@ -56,7 +68,7 @@ ModeParser* ModeManager::getModeParser(const string &path) } } -void ModeManager::addModeName(ModeParser *parser, string &path) +void ModeManager::addModeName(ModeParser *parser, const string &path) { string modeName = parser->getModeName(); modeMap.insert(std::pair(modeName, path)); @@ -101,7 +113,7 @@ int ModeManager::applyMode(const string &modeName) mode.undo(); return ret; } - careTaker.saveMode(mode); + careTaker.pushMode(mode); } } catch (ModesEx &e) { ERR("apply Fail(%s)", e.what()); @@ -111,7 +123,7 @@ int ModeManager::applyMode(const string &modeName) int ModeManager::registerMode(const Mode &mode) { - std::string filename; + string filename; XMLGenerator xmlWriter; try { @@ -128,30 +140,31 @@ int ModeManager::registerMode(const Mode &mode) return MODES_ERROR_NONE; } -int ModeManager::undoMode(const std::string & modeName) +int ModeManager::undoMode(const string &modeName) { - return careTaker.undoMode(modeName); + Mode mode; + int ret = careTaker.popMode(modeName, mode); + if (MODES_ERROR_NONE != ret) { + ERR("popMode() Fail(%d)", ret); + return ret; + } + mode.undo(); + + return MODES_ERROR_NONE; } -std::list> ModeManager::getModes() +std::list> ModeManager::getModes() { - std::list> modeList; + std::list> modeList; for (auto it = modeMap.begin(); it != modeMap.end(); ++it) { int state = careTaker.isSavedMode(it->first); - modeList.push_back(std::tuple(it->first, state)); + modeList.push_back(std::tuple(it->first, state)); } return modeList; } -//it should be called before init() -void ModeManager::setOptions(const std::set &modeDirs, const string &xsdFile) -{ - modeDirList = modeDirs; - modeSyntaxFile = xsdFile; -} - bool ModeManager::makeModeMap(const string &dirPath) { DBG("dirPath : [%s]", dirPath.c_str()); @@ -165,9 +178,9 @@ bool ModeManager::makeModeMap(const string &dirPath) struct dirent *entry; while ((entry = readdir(dir)) != NULL) { string file(entry->d_name); - size_t pos = file.find_last_of("_"); - if (string::npos == pos - || file.compare(pos, sizeof(MODES_MODE_FILE_SUFFIX) - 1, MODES_MODE_FILE_SUFFIX)) { + const size_t suffixLen = sizeof(MODES_MODE_FILE_SUFFIX) - 1; + if (file.length() < suffixLen + || file.compare(file.length() - suffixLen, suffixLen, MODES_MODE_FILE_SUFFIX)) { continue; } @@ -188,6 +201,52 @@ bool ModeManager::makeModeMap(const string &dirPath) return true; } +bool ModeManager::restoreUndoInfo(const string &dirPath) +{ + DBG("dirPath : [%s]", dirPath.c_str()); + + DIR *dir; + if ((dir = opendir(dirPath.c_str())) == NULL) { + ERR("opendir(%s) Fail(%s)", dirPath.c_str(), strerror(errno)); + return false; + } + + struct dirent *entry; + while ((entry = readdir(dir)) != NULL) { + string file(entry->d_name); + const size_t suffixLen = sizeof(MODES_UNDO_FILE_SUFFIX) - 1; + if (file.length() < suffixLen + || file.compare(file.length() - suffixLen, suffixLen, MODES_UNDO_FILE_SUFFIX)) { + continue; + } + + string fileFullPath = dirPath + "/" + string(entry->d_name); + try { + UndoInfoParser undoInfoParser(fileFullPath); + string modeName = undoInfoParser.getModeName(); + auto found = modeMap.find(modeName); + if (modeMap.end() == found) { + ERR("No Mode(%s)", modeName.c_str()); + throw ModesEx(ModesEx::NO_DATA); + } + + string path = found->second; + std::unique_ptr parser(getModeParser(path)); + Mode mode = parser->getMode(); + undoInfoParser.putUndoInfo(mode); + + careTaker.restoreMode(mode); + } catch (std::exception &e) { + ERR("parser(%s) Fail(%s)", fileFullPath.c_str(), e.what()); + if (0 != remove(fileFullPath.c_str())) + ERR("remove(%s) Fail(%s)", fileFullPath.c_str(), strerror(errno)); + } + } + + closedir(dir); + return true; +} + void ModeManager::addModeDirectory(const string &dirPath) { auto result = modeDirList.find(dirPath); diff --git a/supervisor/ModeManager.h b/supervisor/ModeManager.h index bc0fef8..e20f456 100644 --- a/supervisor/ModeManager.h +++ b/supervisor/ModeManager.h @@ -34,7 +34,7 @@ class ModeManager { public: ModeManager(RuleManager &rMgr, PluginManager &pMgr); - void setOptions(const std::set &modeDirs, const std::string &xsdFile); + void setOptions(const std::set &modeDirs, const std::string &xsdFile, const std::string &undoInfoDir); void init(); void addModeDirectory(const std::string &dirPath); int applyMode(const std::string &modeName); @@ -43,11 +43,13 @@ public: std::list> getModes(); private: bool makeModeMap(const std::string &dirPath); - void addModeName(ModeParser *parser, std::string &path); + bool restoreUndoInfo(const std::string &dirPath); + void addModeName(ModeParser *parser, const std::string &path); ModeParser* getModeParser(const std::string &path); std::map modeMap; std::set modeDirList; + std::string undoDir; std::string modeSyntaxFile; RuleManager &ruleMgr; PluginManager &pluginMgr; diff --git a/supervisor/ModeTag.cpp b/supervisor/ModeTag.cpp deleted file mode 100644 index 12beebb..0000000 --- a/supervisor/ModeTag.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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 "ModeTag.h" - -MODES_NAMESPACE_USE; - -const xmlChar* const ModeTag::XML_VERSION = (xmlChar*)"1.0"; -const xmlChar* const ModeTag::XML_ENCODING = (xmlChar*)"utf-8"; -const xmlChar* const ModeTag::TIZENMODES = (xmlChar*)"tizenModes"; -const xmlChar* const ModeTag::XMLNS = (xmlChar*)"xmlns"; -const xmlChar* const ModeTag::XMLNS_STR = (xmlChar*)"http://www.tizen.org"; -const xmlChar* const ModeTag::VERSION = (xmlChar*)"version"; -const xmlChar* const ModeTag::CUR_VERSION = (xmlChar*)"6.0"; -const xmlChar* const ModeTag::MODE = (xmlChar*)"mode"; -const xmlChar* const ModeTag::NAME = (xmlChar*)"name"; -const xmlChar* const ModeTag::TYPE = (xmlChar*)"type"; -const xmlChar* const ModeTag::CUSTOM = (xmlChar*)"custom"; -const xmlChar* const ModeTag::ACTION = (xmlChar*)"action"; -const xmlChar* const ModeTag::UNDO = (xmlChar*)"undo"; -const xmlChar* const ModeTag::RULE = (xmlChar*)"rule"; -const xmlChar* const ModeTag::STOP_ON_ERR = (xmlChar*)"stopOnErr"; -const xmlChar* const ModeTag::RESTICT = (xmlChar*)"restrict"; -const xmlChar* const ModeTag::ID = (xmlChar*)"ID"; -const char* const ModeTag::RESTICT_LOCK = "lock"; diff --git a/supervisor/ModeTag.h b/supervisor/ModeTag.h deleted file mode 100644 index 162b184..0000000 --- a/supervisor/ModeTag.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved - * - * 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. - */ -#pragma once - -#include -#include "mdss.h" - -MODES_NAMESPACE_BEGIN - -struct ModeTag { - static const xmlChar* const XML_VERSION; - static const xmlChar* const XML_ENCODING; - static const xmlChar* const TIZENMODES; - static const xmlChar* const XMLNS; - static const xmlChar* const XMLNS_STR; - static const xmlChar* const VERSION; - static const xmlChar* const CUR_VERSION; - static const xmlChar* const MODE; - static const xmlChar* const NAME; - static const xmlChar* const TYPE; - static const xmlChar* const CUSTOM; - static const xmlChar* const ACTION; - static const xmlChar* const UNDO; - static const xmlChar* const RULE; - static const xmlChar* const STOP_ON_ERR; - static const xmlChar* const RESTICT; - static const xmlChar* const ID; - static const xmlChar* const PRIORITY; - static const xmlChar* const BEFORE; - static const xmlChar* const AFTER; - static const char* const RESTICT_LOCK; -}; - -MODES_NAMESPACE_END diff --git a/supervisor/ModeXMLParser.cpp b/supervisor/ModeXMLParser.cpp index b318073..1d61977 100644 --- a/supervisor/ModeXMLParser.cpp +++ b/supervisor/ModeXMLParser.cpp @@ -23,39 +23,33 @@ #include "ModesEx.h" #include "TAction.h" #include "XMLParser.h" -#include "ModeTag.h" +#include "ModesXMLTag.h" MODES_NAMESPACE_USE; ModeXMLParser::ModeXMLParser(const std::string &modeFile, RuleManager &rMgr, PluginManager &pMgr) - : ModeParser(rMgr), pluginManager(pMgr) + : ModeParser(rMgr), XMLParser(modeFile), pluginManager(pMgr) { - this->modeFile = modeFile; } Mode ModeXMLParser::getMode() { - XMLParser parser(modeFile); - iterateElement(parser.getRoot()); + iterateElement(getRoot()); return mode; } std::string ModeXMLParser::getModeName() { - if (!mode.getName().empty()) { + if (!mode.getName().empty()) return mode.getName(); - } - - XMLParser parser(modeFile); - xmlNodePtr cur, root; - root = parser.getRoot(); - for (cur = root->children; cur; cur = cur->next) { + xmlNodePtr root = getRoot(); + for (xmlNodePtr cur = root->children; cur; cur = cur->next) { if (xmlIsBlankNode(cur)) continue; - if (MDS_EQUAL == xmlStrcmp(cur->name, ModeTag::MODE)) { - mode.setName(getModeName(cur)); + if (MDS_EQUAL == xmlStrcmp(cur->name, ModesXMLTag::MODE)) { + mode.setName(extractModeName(cur)); break; } } @@ -65,9 +59,8 @@ std::string ModeXMLParser::getModeName() void ModeXMLParser::validateMode(const std::string &xsd) { - XMLParser parser = XMLParser(modeFile); try { - parser.validate(xsd); + validate(xsd); } catch (ModesEx &e) { ERR("validate() Fail(%s)", e.what()); throw ModesEx(ModesEx::INVALID_ARG); @@ -81,18 +74,18 @@ void ModeXMLParser::iterateElement(xmlNodePtr node) if (xmlIsBlankNode(cur)) continue; - getDatafromNode(cur); + parseElement(cur); iterateElement(cur->children); } } -void ModeXMLParser::getDatafromNode(xmlNodePtr node) +void ModeXMLParser::parseElement(xmlNodePtr node) { - if (MDS_EQUAL == xmlStrcmp(node->name, ModeTag::MODE)) { + if (MDS_EQUAL == xmlStrcmp(node->name, ModesXMLTag::MODE)) { parseMode(node); - } else if (MDS_EQUAL == xmlStrcmp(node->name, ModeTag::ACTION)) { + } else if (MDS_EQUAL == xmlStrcmp(node->name, ModesXMLTag::ACTION)) { parseAction(node); - } else if (MDS_EQUAL == xmlStrcmp(node->name, ModeTag::UNDO)) { + } else if (MDS_EQUAL == xmlStrcmp(node->name, ModesXMLTag::UNDO)) { parseUndo(node); } else { DBG("Unhandled node : %s", node->name); @@ -101,44 +94,27 @@ void ModeXMLParser::getDatafromNode(xmlNodePtr node) void ModeXMLParser::parseMode(xmlNodePtr node) { - mode.setName(getModeName(node)); - mode.setModeType(getModeType(node)); - mode.setCustomized(getModeCustom(node)); + mode.setName(extractModeName(node)); + mode.setModeType(extractModeType(node)); + mode.setCustomized(extractModeCustom(node)); } -std::string ModeXMLParser::getModeName(xmlNodePtr node) +std::string ModeXMLParser::extractModeName(xmlNodePtr node) { - return getXmlTagStringValue(node, ModeTag::NAME); + return extractValueOfTag(node, ModesXMLTag::NAME); } -std::string ModeXMLParser::getModeType(xmlNodePtr node) +std::string ModeXMLParser::extractModeType(xmlNodePtr node) { - return getXmlTagStringValue(node, ModeTag::TYPE); + return extractValueOfTag(node, ModesXMLTag::TYPE); } -bool ModeXMLParser::getModeCustom(xmlNodePtr node) +bool ModeXMLParser::extractModeCustom(xmlNodePtr node) { - std::string data = getXmlTagStringValue(node, ModeTag::CUSTOM); + std::string data = extractValueOfTag(node, ModesXMLTag::CUSTOM); return ("yes" == data); } -std::string ModeXMLParser::getXmlTagStringValue(xmlNodePtr node, const xmlChar* tag) -{ - char *xmlTagValue; - std::string xmlTagString; - - xmlTagValue = (char*)xmlGetProp(node, tag); - if (xmlTagValue == NULL) { - ERR("attribute(%s) is NULL. ", tag); - xmlTagString = ""; - return xmlTagString; - } - - xmlTagString = xmlTagValue; - xmlFree(xmlTagValue); - return xmlTagString; -} - void ModeXMLParser::parseUndo(xmlNodePtr node) { Action *action = parseActionInfo(node); @@ -147,14 +123,14 @@ void ModeXMLParser::parseUndo(xmlNodePtr node) void ModeXMLParser::parseActionAttr(xmlNodePtr node, Action *action) { - char *restictProp = (char*)xmlGetProp(node, ModeTag::RESTICT); - if (restictProp && MDS_EQUAL == strcmp(restictProp, ModeTag::RESTICT_LOCK)) + char *restictProp = (char*)xmlGetProp(node, ModesXMLTag::RESTICT); + if (restictProp && MDS_EQUAL == strcmp(restictProp, ModesXMLTag::RESTICT_LOCK)) action->setRestrict(Action::REQ_LOCK); else action->setRestrict(Action::REQ_NONE); xmlFree(restictProp); - char *stopOnErrProp = (char*)xmlGetProp(node, ModeTag::STOP_ON_ERR); + char *stopOnErrProp = (char*)xmlGetProp(node, ModesXMLTag::STOP_ON_ERR); if (stopOnErrProp && MDS_EQUAL == strcmp(stopOnErrProp, "true")) action->setStopOnErr(true); else @@ -170,9 +146,9 @@ void ModeXMLParser::parseAction(xmlNodePtr node) Action* ModeXMLParser::parseActionInfo(xmlNodePtr node) { - char *ruleProp = (char*)xmlGetProp(node, ModeTag::RULE); + char *ruleProp = (char*)xmlGetProp(node, ModesXMLTag::RULE); if (ruleProp == NULL) { - ERR("rule attribute is null! [%s]", ModeTag::RULE); + ERR("rule attribute is null! [%s]", ModesXMLTag::RULE); throw ModesEx(ModesEx::PARSER_ERROR, "rule attribute is null!"); } diff --git a/supervisor/ModeXMLParser.h b/supervisor/ModeXMLParser.h index 5ef9a77..3419a0a 100644 --- a/supervisor/ModeXMLParser.h +++ b/supervisor/ModeXMLParser.h @@ -18,11 +18,12 @@ #include #include "mdss.h" #include "ModeParser.h" +#include "XMLParser.h" #include "PluginManager.h" MODES_NAMESPACE_BEGIN -class ModeXMLParser : public ModeParser { +class ModeXMLParser : public ModeParser, public XMLParser { public: ModeXMLParser(const std::string &modeFile, RuleManager &mgr, PluginManager &pluginMgr); ~ModeXMLParser() = default; @@ -33,12 +34,11 @@ public: private: void iterateElement(xmlNodePtr node); - void getDatafromNode(xmlNodePtr node); + void parseElement(xmlNodePtr node); void parseMode(xmlNodePtr node); - std::string getModeName(xmlNodePtr node); - std::string getModeType(xmlNodePtr node); - bool getModeCustom(xmlNodePtr node); - std::string getXmlTagStringValue(xmlNodePtr node, const xmlChar *tag); + std::string extractModeName(xmlNodePtr node); + std::string extractModeType(xmlNodePtr node); + bool extractModeCustom(xmlNodePtr node); void parseActionAttr(xmlNodePtr node, Action *action); void parseAction(xmlNodePtr node); void parseUndo(xmlNodePtr node); @@ -47,7 +47,7 @@ private: PluginManager &pluginManager; Mode mode; - std::string modeFile; + std::string filePath; }; MODES_NAMESPACE_END diff --git a/supervisor/ModesConfig.h b/supervisor/ModesConfig.h index b42ce05..ba0d9cf 100644 --- a/supervisor/ModesConfig.h +++ b/supervisor/ModesConfig.h @@ -27,6 +27,7 @@ struct ModesConfig { std::string modeXsdFile; std::string actionRuleXsdFile; std::string actionRuleDir; + std::string undoInfoDir; }; MODES_NAMESPACE_END diff --git a/supervisor/ModesXMLTag.cpp b/supervisor/ModesXMLTag.cpp new file mode 100644 index 0000000..f1b8e9b --- /dev/null +++ b/supervisor/ModesXMLTag.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "ModesXMLTag.h" + +MODES_NAMESPACE_USE; + +//common +const xmlChar* const ModesXMLTag::XML_VERSION = (xmlChar*)"1.0"; +const xmlChar* const ModesXMLTag::XML_ENCODING = (xmlChar*)"utf-8"; +const xmlChar* const ModesXMLTag::TIZENMODES = (xmlChar*)"tizenModes"; +const xmlChar* const ModesXMLTag::XMLNS = (xmlChar*)"xmlns"; +const xmlChar* const ModesXMLTag::XMLNS_STR = (xmlChar*)"http://www.tizen.org"; +const xmlChar* const ModesXMLTag::VERSION = (xmlChar*)"version"; +const xmlChar* const ModesXMLTag::CUR_VERSION = (xmlChar*)"6.0"; +//Mode +const xmlChar* const ModesXMLTag::MODE = (xmlChar*)"mode"; +const xmlChar* const ModesXMLTag::NAME = (xmlChar*)"name"; +const xmlChar* const ModesXMLTag::TYPE = (xmlChar*)"type"; +const xmlChar* const ModesXMLTag::CUSTOM = (xmlChar*)"custom"; +//Action +const xmlChar* const ModesXMLTag::ACTION = (xmlChar*)"action"; +const xmlChar* const ModesXMLTag::UNDO = (xmlChar*)"undo"; +const xmlChar* const ModesXMLTag::RULE = (xmlChar*)"rule"; +const xmlChar* const ModesXMLTag::STOP_ON_ERR = (xmlChar*)"stopOnErr"; +const xmlChar* const ModesXMLTag::RESTICT = (xmlChar*)"restrict"; +const char* const ModesXMLTag::RESTICT_LOCK = "lock"; +const xmlChar* const ModesXMLTag::ID = (xmlChar*)"ID"; +//UndoInfo +const xmlChar* const ModesXMLTag::UNDO_INFO = (xmlChar*)"UndoInfo"; +const xmlChar* const ModesXMLTag::INFO = (xmlChar*)"info"; diff --git a/supervisor/ModesXMLTag.h b/supervisor/ModesXMLTag.h new file mode 100644 index 0000000..c88db3a --- /dev/null +++ b/supervisor/ModesXMLTag.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +#pragma once + +#include +#include "mdss.h" + +MODES_NAMESPACE_BEGIN + +struct ModesXMLTag { +//common + static const xmlChar* const XML_VERSION; + static const xmlChar* const XML_ENCODING; + static const xmlChar* const TIZENMODES; + static const xmlChar* const XMLNS; + static const xmlChar* const XMLNS_STR; + static const xmlChar* const VERSION; + static const xmlChar* const CUR_VERSION; +//Mode + static const xmlChar* const MODE; + static const xmlChar* const NAME; + static const xmlChar* const TYPE; + static const xmlChar* const CUSTOM; +//Action + static const xmlChar* const ACTION; + static const xmlChar* const UNDO; + static const xmlChar* const RULE; + static const xmlChar* const STOP_ON_ERR; + static const xmlChar* const RESTICT; + static const char* const RESTICT_LOCK; + static const xmlChar* const ID; +//UndoInfo + static const xmlChar* const UNDO_INFO; + static const xmlChar* const INFO; +}; + +MODES_NAMESPACE_END diff --git a/supervisor/RuleManager.cpp b/supervisor/RuleManager.cpp index 9908832..f12a5a2 100644 --- a/supervisor/RuleManager.cpp +++ b/supervisor/RuleManager.cpp @@ -48,9 +48,9 @@ void RuleManager::makeRuleMap() struct dirent *entry; while ((entry = readdir(dir)) != NULL) { string file(entry->d_name); - size_t pos = file.find_last_of("_"); - if (string::npos == pos - || file.compare(pos, sizeof(MODES_ACTIONRULE_FILE_SUFFIX) - 1, MODES_ACTIONRULE_FILE_SUFFIX)) { + const size_t suffixLen = sizeof(MODES_ACTIONRULE_FILE_SUFFIX) - 1; + if (file.length() < suffixLen + || file.compare(file.length() - suffixLen, suffixLen, MODES_ACTIONRULE_FILE_SUFFIX)) { continue; } diff --git a/supervisor/Supervisor.cpp b/supervisor/Supervisor.cpp index 45b0d62..e633e8f 100644 --- a/supervisor/Supervisor.cpp +++ b/supervisor/Supervisor.cpp @@ -55,7 +55,7 @@ void Supervisor::deInit() void Supervisor::setOptions(const ModesConfig &config) { - modeMgr.setOptions(config.modeXMLDirs, config.modeXsdFile); + modeMgr.setOptions(config.modeXMLDirs, config.modeXsdFile, config.undoInfoDir); pluginMgr.setPluginDir(config.pluginDir); ruleMgr.setOptions(config.actionRuleDir, config.actionRuleXsdFile); } diff --git a/supervisor/TAction.h b/supervisor/TAction.h index 939b3e3..8275fb3 100644 --- a/supervisor/TAction.h +++ b/supervisor/TAction.h @@ -72,6 +72,35 @@ public: return MODES_ERROR_NONE; } + int restoreUndoInfo(const std::string &info) override + { + RETVM_IF(NULL == plugin, MODES_ERROR_NO_DATA, "Action(%s) : No plugin", ruleName.c_str()); + + int pos = ruleName.find_first_of("."); + PluginAction *tmpAction = plugin->getUndoAction(ruleName.substr(pos + 1), info); + if (nullptr == tmpAction) { + ERR("plugin(%s) getUndoAction() Fail", plugin->getName().c_str()); + return MODES_ERROR_NOT_SUPPORTED; + } + plugin->setChangedCallback(valueChangedCallback, ruleName.substr(pos + 1), this); + + piAction = tmpAction; + return MODES_ERROR_NONE; + } + + std::string backupUndoInfo() override + { + RETVM_IF(NULL == plugin, std::string(), "Action(%s) : No plugin", ruleName.c_str()); + + std::string backup; + int ret = plugin->serializeAction(piAction, &backup); + if (MODES_ERROR_NONE != ret) { + ERR("plugin(%s) serializeAction() Fail(%d)", plugin->getName().c_str(), ret); + return std::string(); + } + return backup; + } + int apply() override { RETVM_IF(NULL == plugin, MODES_ERROR_NO_DATA, "Action(%s) : No plugin", ruleName.c_str()); @@ -80,7 +109,7 @@ public: PluginAction *tmpAction = nullptr; int ret = plugin->set(ruleName.substr(pos + 1), value, &tmpAction); if (MODES_ERROR_NONE != ret) { - ERR("plugin(%s) set Fail(%d)", plugin->getName().c_str(), ret); + ERR("plugin(%s) set() Fail(%d)", plugin->getName().c_str(), ret); return ret; } plugin->setChangedCallback(valueChangedCallback, ruleName.substr(pos + 1), this); @@ -97,7 +126,7 @@ public: PluginAction *tmpAction = nullptr; int ret = plugin->set(ruleName.substr(pos + 1), value, &tmpAction); if (MODES_ERROR_NONE != ret) { - ERR("plugin(%s) set Fail(%d)", plugin->getName().c_str(), ret); + ERR("plugin(%s) set() Fail(%d)", plugin->getName().c_str(), ret); return ret; } diff --git a/supervisor/UndoInfoParser.cpp b/supervisor/UndoInfoParser.cpp new file mode 100644 index 0000000..03de0a2 --- /dev/null +++ b/supervisor/UndoInfoParser.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "UndoInfoParser.h" +#include +#include +#include +#include +#include +#include "mdss.h" +#include "ModesEx.h" +#include "XMLParser.h" +#include "ModesXMLTag.h" + +MODES_NAMESPACE_USE; + +UndoInfoParser::UndoInfoParser(const std::string &file) + : XMLParser(file) +{ +} + +std::string UndoInfoParser::getModeName() +{ + XMLParser parser(filePath); + xmlNodePtr root = parser.getRoot(); + for (xmlNodePtr cur = root->children; cur; cur = cur->next) { + if (xmlIsBlankNode(cur)) + continue; + + if (MDS_EQUAL == xmlStrcmp(cur->name, ModesXMLTag::UNDO_INFO)) + return extractValueOfTag(cur, ModesXMLTag::NAME); + } + + return std::string(); +} + +void UndoInfoParser::putUndoInfo(Mode &mode) +{ + std::list> actionList = mode.getActionList(); + + iterateElement(getRoot(), actionList); +} + +void UndoInfoParser::iterateElement(xmlNodePtr node, const std::list> &actionList) +{ + xmlNode *cur = NULL; + for (cur = node; cur; cur = cur->next) { + if (xmlIsBlankNode(cur)) + continue; + else if (MDS_EQUAL == xmlStrcmp(cur->name, ModesXMLTag::INFO)) + parseInfo(cur, actionList); + else + DBG("Unhandled node : %s", node->name); + + iterateElement(cur->children, actionList); + } +} + +void UndoInfoParser::parseInfo(xmlNodePtr node, const std::list> &actionList) +{ + char *ruleName = (char*)xmlGetProp(node, ModesXMLTag::RULE); + if (ruleName == NULL) { + ERR("rule attribute is null! [%s]", ModesXMLTag::RULE); + throw ModesEx(ModesEx::PARSER_ERROR, "rule attribute is null!"); + } + + auto it = std::find_if_not(actionList.begin(), actionList.end(), [ruleName](std::shared_ptr a)->bool {return a->getRuleName().compare(ruleName);}); + std::shared_ptr action = *it; + if (action == nullptr) { + ERR("Find Action(%s) Fail", ruleName); + xmlFree(ruleName); + throw ModesEx(ModesEx::PARSER_ERROR, "Action is null!"); + } + xmlFree(ruleName); + + char *nodeContent = (char*)xmlNodeGetContent(node); + if (nodeContent == NULL) + ERR("Node Content is null!"); + + int ret = action->restoreUndoInfo(nodeContent ? nodeContent : ""); + xmlFree(nodeContent); + + if (MODES_ERROR_NONE != ret) { + ERR("Action(%s) setValue() Fail(%d)", action->getRuleName().c_str(), ret); + throw ModesEx(ModesEx::PARSER_ERROR, "Invalid Action Value"); + } + + action->printInfo(); +} diff --git a/supervisor/UndoInfoParser.h b/supervisor/UndoInfoParser.h new file mode 100644 index 0000000..bd21332 --- /dev/null +++ b/supervisor/UndoInfoParser.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +#pragma once + +#include +#include "mdss.h" +#include "Mode.h" +#include "XMLParser.h" + +MODES_NAMESPACE_BEGIN + +class UndoInfoParser : public XMLParser { +public: + UndoInfoParser(const std::string &file); + ~UndoInfoParser() = default; + + std::string getModeName(); + void putUndoInfo(Mode &mode); +private: + void iterateElement(xmlNodePtr node, const std::list>& actionList); + void parseInfo(xmlNodePtr node, const std::list> &actionList); + + std::string filePath; +}; + +MODES_NAMESPACE_END diff --git a/supervisor/XMLGenerator.cpp b/supervisor/XMLGenerator.cpp index e15de79..302a341 100644 --- a/supervisor/XMLGenerator.cpp +++ b/supervisor/XMLGenerator.cpp @@ -16,14 +16,14 @@ #include #include #include "Action.h" -#include "ModeTag.h" +#include "ModesXMLTag.h" #include "ModesEx.h" #include "XMLGenerator.h" MODES_NAMESPACE_USE; XMLGenerator::XMLGenerator() - : doc(NULL), rootNode(NULL), modeNode(NULL) + : doc(NULL), rootNode(NULL) { } @@ -33,13 +33,13 @@ XMLGenerator::~XMLGenerator() void XMLGenerator::createRootNode() { - doc = xmlNewDoc(ModeTag::XML_VERSION); - doc->encoding = ModeTag::XML_ENCODING; + doc = xmlNewDoc(ModesXMLTag::XML_VERSION); + doc->encoding = ModesXMLTag::XML_ENCODING; doc->charset = 1; - rootNode = xmlNewNode(NULL, ModeTag::TIZENMODES); - xmlSetProp(rootNode, ModeTag::XMLNS, ModeTag::XMLNS_STR); - xmlSetProp(rootNode, ModeTag::VERSION, ModeTag::CUR_VERSION); + rootNode = xmlNewNode(NULL, ModesXMLTag::TIZENMODES); + xmlSetProp(rootNode, ModesXMLTag::XMLNS, ModesXMLTag::XMLNS_STR); + xmlSetProp(rootNode, ModesXMLTag::VERSION, ModesXMLTag::CUR_VERSION); xmlDocSetRootElement(doc, rootNode); return; } @@ -80,32 +80,62 @@ void XMLGenerator::makeModeXML(const std::string &filename, const Mode &mode) const std::string modeType = getModeTypeStr(mode.getModeType()); std::string modeName = mode.getName(); - modeNode = xmlNewNode(NULL, ModeTag::MODE); + xmlNodePtr modeNode = xmlNewNode(NULL, ModesXMLTag::MODE); - xmlSetProp(modeNode, ModeTag::NAME, (xmlChar*)modeName.c_str()); - xmlSetProp(modeNode, ModeTag::TYPE, (xmlChar*)modeType.c_str()); - xmlSetProp(modeNode, ModeTag::CUSTOM, (xmlChar*)((mode.getCustomized())? "yes": "no")); + xmlSetProp(modeNode, ModesXMLTag::NAME, (xmlChar*)modeName.c_str()); + xmlSetProp(modeNode, ModesXMLTag::TYPE, (xmlChar*)modeType.c_str()); + xmlSetProp(modeNode, ModesXMLTag::CUSTOM, (xmlChar*)((mode.getCustomized())? "yes": "no")); xmlAddChild(rootNode, modeNode); std::list> actionList = mode.getActionList(); - std::list>::iterator it; - for (it = actionList.begin(); it != actionList.end(); it++) { - xmlNodePtr reqNode; + for (auto it = actionList.begin(); it != actionList.end(); it++) { + xmlNodePtr actionNode; Action::ActionRestrict restriction = (*it)->getRestrict(); - reqNode = xmlNewNode(NULL, ModeTag::ACTION); + actionNode = xmlNewNode(NULL, ModesXMLTag::ACTION); if (!(*it)->getID().empty()) - xmlSetProp(reqNode, ModeTag::ID, (xmlChar*)(*it)->getID().c_str()); + xmlSetProp(actionNode, ModesXMLTag::ID, (xmlChar*)(*it)->getID().c_str()); - xmlSetProp(reqNode, ModeTag::RULE, (xmlChar*)(*it)->getRuleName().c_str()); + xmlSetProp(actionNode, ModesXMLTag::RULE, (xmlChar*)(*it)->getRuleName().c_str()); if (restriction == Action::ActionRestrict::REQ_LOCK) - xmlSetProp(reqNode, ModeTag::RESTICT, (xmlChar*)ModeTag::RESTICT_LOCK); + xmlSetProp(actionNode, ModesXMLTag::RESTICT, (xmlChar*)ModesXMLTag::RESTICT_LOCK); - xmlNodeSetContent(reqNode, (xmlChar*)(*it)->getStringOfValue().c_str()); + xmlNodeSetContent(actionNode, (xmlChar*)(*it)->getStringOfValue().c_str()); - xmlAddChild(modeNode, reqNode); + xmlAddChild(modeNode, actionNode); + } + + write(filename); + + doc->encoding = NULL; + xmlFreeDoc(doc); + return; +} + +void XMLGenerator::makeUndoInfoXML(const std::string &filename, const Mode &mode) +{ + if (filename.empty()) { + ERR("filename empty!!"); + throw ModesEx(ModesEx::INVALID_ARG); + } + + createRootNode(); + + xmlNodePtr undoInfoNode = xmlNewNode(NULL, ModesXMLTag::UNDO_INFO); + xmlSetProp(undoInfoNode, ModesXMLTag::NAME, (xmlChar*)mode.getName().c_str()); + xmlAddChild(rootNode, undoInfoNode); + + std::list> actionList = mode.getActionList(); + for (auto it = actionList.begin(); it != actionList.end(); it++) { + if ((*it)->backupUndoInfo().empty()) + continue; + + xmlNodePtr infoNode = xmlNewNode(NULL, ModesXMLTag::INFO); + xmlSetProp(infoNode, ModesXMLTag::RULE, (xmlChar*)(*it)->getRuleName().c_str()); + xmlNodeSetContent(infoNode, (xmlChar*)(*it)->backupUndoInfo().c_str()); + xmlAddChild(undoInfoNode, infoNode); } write(filename); diff --git a/supervisor/XMLGenerator.h b/supervisor/XMLGenerator.h index 88be425..335e7fb 100644 --- a/supervisor/XMLGenerator.h +++ b/supervisor/XMLGenerator.h @@ -28,6 +28,7 @@ public: ~XMLGenerator(); void makeModeXML(const std::string &filename, const Mode &mode); + void makeUndoInfoXML(const std::string &filename, const Mode &mode); private: void createRootNode(); @@ -36,6 +37,5 @@ private: xmlDocPtr doc; xmlNodePtr rootNode; - xmlNodePtr modeNode; }; MODES_NAMESPACE_END diff --git a/supervisor/XMLParser.cpp b/supervisor/XMLParser.cpp index 476e78e..bd0d5d8 100644 --- a/supervisor/XMLParser.cpp +++ b/supervisor/XMLParser.cpp @@ -13,11 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include "ModesEx.h" #include "XMLParser.h" + #include #include +#include "mdss.h" +#include "ModesEx.h" MODES_NAMESPACE_USE; @@ -86,3 +87,18 @@ void XMLParser::validate(const std::string &xsd) return; } + +std::string XMLParser::extractValueOfTag(xmlNodePtr node, const xmlChar *tag) +{ + char *value; + + value = (char*)xmlGetProp(node, tag); + if (value == NULL) { + ERR("attribute(%s) is NULL. ", tag); + return std::string(); + } + + std::string valueStr = value; + xmlFree(value); + return valueStr; +} diff --git a/supervisor/XMLParser.h b/supervisor/XMLParser.h index 4f7fd04..a64a2ce 100644 --- a/supervisor/XMLParser.h +++ b/supervisor/XMLParser.h @@ -16,6 +16,7 @@ #pragma once #include +#include #include "mdss.h" MODES_NAMESPACE_BEGIN @@ -26,6 +27,7 @@ public: ~XMLParser(); void validate(const std::string &xsd); + std::string extractValueOfTag(xmlNodePtr node, const xmlChar * tag); xmlNodePtr getRoot(); private: diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 16d8b24..93614ad 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -33,13 +33,14 @@ INSTALL(TARGETS ${TEST_APPLY_MODE} DESTINATION ${TEST_INSTALL_DIR}) #=======================================================================================# SET(GTEST_MODEMGR "modes-gtest-modemgr") FILE(GLOB GTEST_MODEMGR_SRCS - ${SUPERVISOR_DIR}/ModeTag.cpp + ${SUPERVISOR_DIR}/ModesXMLTag.cpp ${SUPERVISOR_DIR}/XMLParser.cpp ${SUPERVISOR_DIR}/XMLGenerator.cpp ${SUPERVISOR_DIR}/ModeManager.cpp ${SUPERVISOR_DIR}/ConflictManager.cpp ${SUPERVISOR_DIR}/ModeCareTaker.cpp ${SUPERVISOR_DIR}/ModeXMLParser.cpp + ${SUPERVISOR_DIR}/UndoInfoParser.cpp ${SUPERVISOR_DIR}/Action.cpp ${SUPERVISOR_DIR}/ActionRule.cpp ${SUPERVISOR_DIR}/RuleManager.cpp @@ -75,7 +76,7 @@ FILE(GLOB GTEST_PARSER_SRCS ${SUPERVISOR_DIR}/ModeXMLParser.cpp ${SUPERVISOR_DIR}/ModesEx.cpp ${SUPERVISOR_DIR}/Mode.cpp - ${SUPERVISOR_DIR}/ModeTag.cpp + ${SUPERVISOR_DIR}/ModesXMLTag.cpp ${SUPERVISOR_DIR}/ValueChecker.cpp modes_test_parser.cpp ) @@ -86,7 +87,7 @@ INSTALL(TARGETS ${GTEST_PARSER} DESTINATION ${TEST_INSTALL_DIR}) SET(GTEST_GENERATOR "modes-gtest-generator") FILE(GLOB GTEST_GENERATOR_SRCS ${SUPERVISOR_DIR}/XMLGenerator.cpp - ${SUPERVISOR_DIR}/ModeTag.cpp + ${SUPERVISOR_DIR}/ModesXMLTag.cpp ${SUPERVISOR_DIR}/ModeXMLParser.cpp ${SUPERVISOR_DIR}/XMLParser.cpp ${SUPERVISOR_DIR}/Mode.cpp @@ -108,11 +109,12 @@ FILE(GLOB GTEST_CONFLICT_SRCS ${SUPERVISOR_DIR}/ConflictManager.cpp ${SUPERVISOR_DIR}/Mode.cpp ${SUPERVISOR_DIR}/ModeCareTaker.cpp + ${SUPERVISOR_DIR}/XMLGenerator.cpp ${SUPERVISOR_DIR}/Action.cpp ${SUPERVISOR_DIR}/ModeXMLParser.cpp ${SUPERVISOR_DIR}/XMLParser.cpp ${SUPERVISOR_DIR}/ModesEx.cpp - ${SUPERVISOR_DIR}/ModeTag.cpp + ${SUPERVISOR_DIR}/ModesXMLTag.cpp ${SUPERVISOR_DIR}/PluginManager.cpp ${SUPERVISOR_DIR}/RuleManager.cpp ${SUPERVISOR_DIR}/ActionRule.cpp diff --git a/unittest/modes_test_conflict.cpp b/unittest/modes_test_conflict.cpp index 2c4546e..91e56a6 100644 --- a/unittest/modes_test_conflict.cpp +++ b/unittest/modes_test_conflict.cpp @@ -28,12 +28,13 @@ protected: void SetUp() override { ModeXMLParser modeparser("tizen_conflict1_mode.xml", ruleMgr, piMgr); - careTaker.saveMode(modeparser.getMode()); + careTaker.pushMode(modeparser.getMode()); } void TearDown() override { - careTaker.undoMode("conflict1"); + Mode mode; + careTaker.popMode("conflict1", mode); } PluginManager piMgr; @@ -46,15 +47,17 @@ ConflictTest::ConflictTest() ModesConfig config; config.actionRuleDir = "."; config.actionRuleXsdFile = "./" MODES_ACTIONRULE_DEFAULT_XSD_FILE; + config.undoInfoDir = "."; ruleMgr.setOptions(config.actionRuleDir, config.actionRuleXsdFile); ruleMgr.makeRuleMap(); + careTaker.setOptions(config.undoInfoDir); } TEST_F(ConflictTest, isSavedMode) { - ModeXMLParser modeparser("tizen_conflict2_mode.xml", ruleMgr, piMgr); + ModeXMLParser modeparser("tizen_conflict1_mode.xml", ruleMgr, piMgr); EXPECT_TRUE(careTaker.isSavedMode(modeparser.getModeName())); } @@ -63,10 +66,11 @@ TEST_F(ConflictTest, isExcluded) { ModeXMLParser modeparser("tizen_conflict3_mode.xml", ruleMgr, piMgr); - careTaker.saveMode(modeparser.getMode()); + careTaker.pushMode(modeparser.getMode()); EXPECT_TRUE(careTaker.isExclusive()); - careTaker.undoMode(modeparser.getModeName()); + Mode mode; + careTaker.popMode(modeparser.getModeName(), mode); EXPECT_FALSE(careTaker.isExclusive()); } diff --git a/unittest/modes_test_modemgr.cpp b/unittest/modes_test_modemgr.cpp index 7869516..39457a8 100644 --- a/unittest/modes_test_modemgr.cpp +++ b/unittest/modes_test_modemgr.cpp @@ -42,8 +42,9 @@ ModeManagerTest::ModeManagerTest() ModesConfig config; config.modeXMLDirs.insert("."); config.modeXsdFile = "./" MODES_MODE_DEFAULT_XSD_FILE; + config.undoInfoDir = "./"; - mdMgr.setOptions(config.modeXMLDirs, config.modeXsdFile); + mdMgr.setOptions(config.modeXMLDirs, config.modeXsdFile, config.undoInfoDir); mdMgr.init(); }