apply permanent caretaker
authorYoungjae Shin <yj99.shin@samsung.com>
Mon, 21 Oct 2019 00:00:18 +0000 (09:00 +0900)
committerYoungjae Shin <yj99.shin@samsung.com>
Wed, 18 Mar 2020 08:53:50 +0000 (17:53 +0900)
36 files changed:
Definitions.cmake
common/definitions.h
include/Plugin.h
include/PluginAction.h
packaging/modes.spec
plugin/TestPlugin.cpp
plugin/TestPluginAction.cpp
plugin/TestPluginAction.h
supervisor/Action.cpp
supervisor/Action.h
supervisor/ArgumentParser.cpp
supervisor/ArgumentParser.h
supervisor/Mode.h
supervisor/ModeCareTaker.cpp
supervisor/ModeCareTaker.h
supervisor/ModeManager.cpp
supervisor/ModeManager.h
supervisor/ModeTag.cpp [deleted file]
supervisor/ModeTag.h [deleted file]
supervisor/ModeXMLParser.cpp
supervisor/ModeXMLParser.h
supervisor/ModesConfig.h
supervisor/ModesXMLTag.cpp [new file with mode: 0644]
supervisor/ModesXMLTag.h [new file with mode: 0644]
supervisor/RuleManager.cpp
supervisor/Supervisor.cpp
supervisor/TAction.h
supervisor/UndoInfoParser.cpp [new file with mode: 0644]
supervisor/UndoInfoParser.h [new file with mode: 0644]
supervisor/XMLGenerator.cpp
supervisor/XMLGenerator.h
supervisor/XMLParser.cpp
supervisor/XMLParser.h
unittest/CMakeLists.txt
unittest/modes_test_conflict.cpp
unittest/modes_test_modemgr.cpp

index cb432d0c2d0dc3ecbb61fe4c45f636c2e4822f1c..2c936ff061cd04f7f1a3604e396681508fd44467 100644 (file)
@@ -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}\"")
index 26d53148d847c4e4adb814dfc07bc8a2949b7edd..78083bbbfddf86d62d75683f7b4f9841fbc6724a 100644 (file)
 #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"
index 2f8a5d887900cd38d05437059fbcba9f64c047de..4d98c83c3356eadb6112132da0502d0e16d08c7d 100644 (file)
@@ -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;
index cad479c9f52f4e986e32e5067c594dcfc462a498..b5642183e24a6293a1d7a37662ec579639daf595 100644 (file)
@@ -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)
                {
index 0112a1427921ae636bb5257412773054ac9223a9..e2a8cfc0c999ccd73a108d899c2f78455fa4ca89 100644 (file)
@@ -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
index a576559df68e3d9e2ced266f3420ecd158c642c6..ab22bcdefad355e88b9031d888cd2cab3b38aec2 100644 (file)
@@ -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());
index 81b2658548ce864c8b5c6c286da6d2040b31af30..2c4d51960d24c65e144ed29ba24e39eb4885ec14 100644 (file)
@@ -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;
 }
index 41caeebeb5efc5d75b899c9ec7250c362ff6869f..4664242a01fb00d95af4144f21d65797214f6b17 100644 (file)
@@ -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
index 52d77354f62733465a8265ee5574ace89ff1f650..0429030f3451e2df7a2f4b5be26b567eb6e9ef0c 100644 (file)
@@ -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)
index ac8c184fdf5fe6e5045e49044e7dac25f13e277d..a44e3ad99d983d79250197f1f126090a065bf734 100644 (file)
@@ -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;
index f3bcf22400e05e8299f86aa63f71e7940117d53e..a0fca3bdfc4c6767d46014b1516b8b403136c5dc 100644 (file)
@@ -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;
 }
index 9c78288db582400bdd382246d42b93618e8c794f..05126dceb3c23c78134ea3f184390beff44b6255 100644 (file)
@@ -33,6 +33,7 @@ private:
        char *actionRuleDir;
        char *actionRuleXsdFile;
        char *pluginDir;
+       char *undoInfoDir;
 
        static char argp_doc[];
        static char args_doc[];
index a53e638eb1cb51566e4919ae22ecb2f1e51e99a4..7cdf99b51872aa657030465ae59ded9d8bb1f393 100644 (file)
@@ -49,6 +49,8 @@ public:
        void addUndo(Action *action);
        std::list<std::shared_ptr<Action>> getUndoList() const;
 
+       void addUndoInfo(const std::string &rule, const std::string &info);
+
        int apply();
        int applyOneShot();
        void undo();
index 045a998f2f697c529a53bc377a601b74f687ae6b..0a9745023820e07c8fc9b2d8a3720d52e9e82f1f 100644 (file)
 #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<std::string, Mode>(mode.getName(), mode));
+       exclusive = (Mode::MODE_EXCLUSIVE == mode.getModeType());
+}
+
+void ModeCareTaker::pushMode(const Mode &mode)
 {
        savedModes.insert(std::pair<std::string, Mode>(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);
 
index c95a467d54b7f33953434cd4cce2e4a5687a5753..e871be2ed099fd7cc31d11a654e8dd0a906520d9 100644 (file)
@@ -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<std::string, Mode> savedModes;
+       std::string undoDir;
        bool exclusive;
 };
 
index 337261fa79539aa10a05c9c428f1bbd1111e3241..6658fe11c53fc6bdb7af2300c7457923917ce6dd 100644 (file)
@@ -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<string> &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<string, string>(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<std::tuple<std::string, int>> ModeManager::getModes()
+std::list<std::tuple<string, int>> ModeManager::getModes()
 {
-       std::list<std::tuple<std::string, int>> modeList;
+       std::list<std::tuple<string, int>> modeList;
 
        for (auto it = modeMap.begin(); it != modeMap.end(); ++it) {
                int state = careTaker.isSavedMode(it->first);
-               modeList.push_back(std::tuple<std::string, int>(it->first, state));
+               modeList.push_back(std::tuple<string, int>(it->first, state));
        }
 
        return modeList;
 }
 
-//it should be called before init()
-void ModeManager::setOptions(const std::set<string> &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<ModeParser> 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);
index bc0fef810954df7d47fdfc675fb3237d4846639a..e20f456c81049b4356f891de52e5aa45a2cb8f10 100644 (file)
@@ -34,7 +34,7 @@ class ModeManager {
 public:
        ModeManager(RuleManager &rMgr, PluginManager &pMgr);
 
-       void setOptions(const std::set<std::string> &modeDirs, const std::string &xsdFile);
+       void setOptions(const std::set<std::string> &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<std::tuple<std::string, int>> 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<std::string, std::string> modeMap;
        std::set<std::string> 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 (file)
index 12beebb..0000000
+++ /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 (file)
index 162b184..0000000
+++ /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 <libxml/tree.h>
-#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
index b31807357ada8ba91a8fd8e44714488cc4e10440..1d61977573bc1502a1eae8567097d59d1070630c 100644 (file)
 #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!");
        }
 
index 5ef9a772aba03511f2596097c2a5bf618546fe5e..3419a0ad918a1bec818300b1ecc485a69afd8966 100644 (file)
 #include <libxml/tree.h>
 #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
index b42ce051aa6d6ee466b1ef891cc421c29d4b6bad..ba0d9cf44d73a027788d47dad7105b7b57013c07 100644 (file)
@@ -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 (file)
index 0000000..f1b8e9b
--- /dev/null
@@ -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 (file)
index 0000000..c88db3a
--- /dev/null
@@ -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 <libxml/tree.h>
+#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
index 9908832078a9eb037a883cbabd141e474da28dd4..f12a5a2f1504b4f98e7ca5227b6d50099ac4b603 100644 (file)
@@ -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;
                }
 
index 45b0d62e8c74831cb802df7f2ee6d50f4c4614a2..e633e8f332ef85230e13869b499f4ce0aa68837d 100644 (file)
@@ -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);
 }
index 939b3e3393d88ce2361328054ef5c2eaef243257..8275fb3d14dc692484e7640063994c3a38bbebff 100644 (file)
@@ -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 (file)
index 0000000..03de0a2
--- /dev/null
@@ -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 <cstring>
+#include <string>
+#include <algorithm>
+#include <libxml/tree.h>
+#include <libxml/xmlschemas.h>
+#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<std::shared_ptr<Action>> actionList = mode.getActionList();
+
+       iterateElement(getRoot(), actionList);
+}
+
+void UndoInfoParser::iterateElement(xmlNodePtr node, const std::list<std::shared_ptr<Action>> &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<std::shared_ptr<Action>> &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<Action> a)->bool {return a->getRuleName().compare(ruleName);});
+       std::shared_ptr<Action> 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 (file)
index 0000000..bd21332
--- /dev/null
@@ -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 <libxml/tree.h>
+#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<std::shared_ptr<Action>>& actionList);
+       void parseInfo(xmlNodePtr node, const std::list<std::shared_ptr<Action>> &actionList);
+
+       std::string filePath;
+};
+
+MODES_NAMESPACE_END
index e15de79423d045837cb8b65ecca902151998f7e3..302a341530a6f720d342a5d1d23af5682c58d4e6 100644 (file)
 #include <libxml/tree.h>
 #include <libxml/xmlschemas.h>
 #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<std::shared_ptr<Action>> actionList = mode.getActionList();
-       std::list<std::shared_ptr<Action>>::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<std::shared_ptr<Action>> 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);
index 88be4258c01b4463f7ff89288696dd4d55946f14..335e7fbc8b692acac7c98e769947d0cd33894870 100644 (file)
@@ -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
index 476e78e5fa183ec5a46c5d366f82eb2c9c254c31..bd0d5d82397f6b84219aafdff682899d163512a9 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-#include "ModesEx.h"
 #include "XMLParser.h"
+
 #include <libxml/tree.h>
 #include <libxml/xmlschemas.h>
+#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;
+}
index 4f7fd049a7d89d556952db41ccf2178b5e66832c..a64a2ceea44e68fc80c588efa88d84c26f1f5a01 100644 (file)
@@ -16,6 +16,7 @@
 #pragma once
 
 #include <libxml/tree.h>
+#include <string>
 #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:
index 16d8b24c48b84df9ca3be69615ab5aa7749d71d2..93614ad43795438b7d00a812deb94e0d06eb00dc 100644 (file)
@@ -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
index 2c4546ec91912f2874846b1a71d129490693411f..91e56a6a64d55275776d35724b6c3c653c79be9f 100644 (file)
@@ -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());
 }
 
index 7869516f5416216acd1086578fc2518b41408c7f..39457a8e6aa8d918a6f43f473ebbbffaf40e2c93 100644 (file)
@@ -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();
 }