handle action failure
authorYoungjae Shin <yj99.shin@samsung.com>
Thu, 19 Sep 2019 04:25:35 +0000 (13:25 +0900)
committerYoungjae Shin <yj99.shin@samsung.com>
Wed, 18 Mar 2020 08:53:50 +0000 (17:53 +0900)
14 files changed:
example/mode/tizen_ex1_mode.xml
example/mode/tizen_ex2_mode.xml
schema/tizen_mode.xsd
supervisor/Action.cpp
supervisor/Action.h
supervisor/Mode.cpp
supervisor/Mode.h
supervisor/ModeManager.cpp
supervisor/ModeTag.cpp
supervisor/ModeTag.h
supervisor/ModeXMLParser.cpp
supervisor/ModeXMLParser.h
supervisor/TAction.h
unittest/modes_test_parser.cpp

index 5d486d5ff35b2f7b20a2b353d90f6e7a22afb3cb..c906889b537367a6201abca41df61e3bc7d3d48c 100644 (file)
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="utf-8"?>
 <tizenModes xmlns="http://www.tizen.org" version="5.5">
   <mode name="ex1" type="normal">
-    <action ID="wifiOn" rule="wifi.power" type="sync" priority="-100">on</action>
+    <action ID="wifiOn" rule="wifi.power" priority="-100">on</action>
     <action rule="notification.donotdisturb">on</action>
     <action rule="application.launch" before="GoPbsKids">com.vpn.usa123</action>
     <action ID="GoPbsKids" rule="browser.url" after="wifiOn">https://pbskids.org/</action>
-    <action ID="BMJ" rule="bluetooth.connet" type="sync">Modes-JBL</action>
-    <action rule="media.music.player" type="async" after="BMJ">beatles-yesterday.mp3</action>
-    <action ID="1" rule="vconf.db.setting.psmode" type="async" priority="-100"
+    <action ID="BMJ" rule="bluetooth.connet">Modes-JBL</action>
+    <action rule="media.music.player" after="BMJ">beatles-yesterday.mp3</action>
+    <action ID="1" rule="vconf.db.setting.psmode" priority="-100"
          >SETTING_PSMODE_NORMAL</action>
   </mode>
 </tizenModes>
index 6c39ee1712c3118e48ef1296d0b4025aa5dc327c..6056c62aff04c6b1c72ea5af85c82b5fd552d6dc 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <tizenModes xmlns="http://www.tizen.org" version="5.5">
   <mode name="ex2" type="exclusive">
-    <action ID="1" rule="vconf.db.setting.psmode" type="async" restrict="lock" priority="-100">SETTING_PSMODE_WEARABLE</action>
-    <action ID="wifiOff" rule="wifi.power" restrict="lock" type="sync" priority="-100">off</action>
+    <action ID="1" rule="vconf.db.setting.psmode" stopOnErr="true" restrict="lock" priority="-100">SETTING_PSMODE_WEARABLE</action>
+    <action ID="wifiOff" rule="wifi.power" restrict="lock" priority="-100">off</action>
   </mode>
 </tizenModes>
index fc78dae8f418a7388f545754aa661cde01776450..e8be4b8cc1af35062a4233cf364a8e8c0a9825bd 100644 (file)
                     <xs:extension base="o:valueT">
                       <xs:attribute name="ID" type="xs:string" use="optional" />
                       <xs:attribute name="rule" type="xs:string" use="required" />
-                      <xs:attribute name="type" use="optional">
-                        <xs:simpleType>
-                          <xs:restriction base="xs:string">
-                            <xs:enumeration value="sync"/>
-                            <xs:enumeration value="async"/>
-                          </xs:restriction>
-                        </xs:simpleType>
-                      </xs:attribute>
+                      <xs:attribute name="stopOnErr" type="xs:boolean" use="optional" />
                       <xs:attribute name="restrict" use="optional">
                         <xs:simpleType>
                           <xs:restriction base="xs:string">
index e30d8db5905c4c2abfc21fad1c9862463c6defc4..52d77354f62733465a8265ee5574ace89ff1f650 100644 (file)
@@ -28,16 +28,23 @@ void Action::valueChangedCallback(const std::string &key, void *userData)
                DBG("Action(%s) Changed", key.c_str());
        }
 }
+
 Action::Action()
-       :plugin(nullptr), piAction(nullptr), isChanged(false), restriction(REQ_NONE)
+       :plugin(nullptr), piAction(nullptr), stopOnErr(false), isChanged(false), restriction(REQ_NONE)
 {
 }
 
 Action::Action(const std::string &name)
-       :ruleName(name), plugin(nullptr), piAction(nullptr), isChanged(false), restriction(REQ_NONE)
+       :ruleName(name), plugin(nullptr), piAction(nullptr), stopOnErr(false), isChanged(false), restriction(REQ_NONE)
 {
 }
 
+Action::~Action()
+{
+       if (plugin)
+               plugin->freeAction(piAction);
+}
+
 void Action::printInfo()
 {
        DBG("Action(%s):ID(%s), Restrict(%d)", getRuleName().c_str(), getID().c_str(), getRestrict());
@@ -68,6 +75,16 @@ void Action::setRestrict(const ActionRestrict &data)
        restriction = data;
 }
 
+void Action::setStopOnErr(bool val)
+{
+       stopOnErr = val;
+}
+
+bool Action::getStopOnErr()
+{
+       return stopOnErr;
+}
+
 Action::ActionRestrict Action::getRestrict()
 {
        return restriction;
index 4c6774b999515ab55d924051ad00784bf6ea88fd..2817a62c318df6e0baa7743460a1cd297dd3087c 100644 (file)
@@ -29,9 +29,9 @@ public:
                REQ_LOCK
        }ActionRestrict;
 
-       virtual ~Action() = default;
        Action();
        Action(const std::string &ruleName);
+       virtual ~Action();
 
        void printInfo();
        void setRuleName(const std::string &data);
@@ -40,13 +40,15 @@ public:
        std::string getID();
        void setRestrict(const ActionRestrict &data);
        ActionRestrict getRestrict();
-       void setPlugin(Plugin *pi);
+       void setStopOnErr(bool val);
+       bool getStopOnErr();
        void setIsChanged();
        bool getIsChanged();
+       void setPlugin(Plugin *pi);
        virtual void setValue(const std::string &val) = 0;
        virtual std::string getStringOfValue() = 0;
-       virtual void apply() = 0;
-       virtual void applyOneShot() = 0;
+       virtual int apply() = 0;
+       virtual int applyOneShot() = 0;
        virtual void undo() = 0;
 
 protected:
@@ -56,8 +58,9 @@ protected:
        static void valueChangedCallback(const std::string &key, void *userData);
 
 private:
-       bool isChanged;
        std::string id;
+       bool stopOnErr;
+       bool isChanged;
        ActionRestrict restriction;
 };
 
index 5acc8d3d293722a6a9a50e91585e885040f917bd..84b9d8ca6a10f92611977faadd49c06643505337 100644 (file)
@@ -84,18 +84,30 @@ const bool Mode::getCustomized() const
        return customized;
 }
 
-void Mode::apply()
+int Mode::apply()
 {
        std::list<std::shared_ptr<Action>>::iterator it;
-       for (it = actionList.begin(); it != actionList.end(); it++)
-               (*it)->apply();
+       for (it = actionList.begin(); it != actionList.end(); it++) {
+               int ret = (*it)->apply();
+               if (MODES_ERROR_NONE != ret && (*it)->getStopOnErr()) {
+                       ERR("Action(%s) apply Fail(%d)", (*it)->getRuleName().c_str(), ret);
+                       return ret;
+               }
+       }
+       return MODES_ERROR_NONE;
 }
 
-void Mode::applyOneShot()
+int Mode::applyOneShot()
 {
        std::list<std::shared_ptr<Action>>::iterator it;
-       for (it = actionList.begin(); it != actionList.end(); it++)
-               (*it)->applyOneShot();
+       for (it = actionList.begin(); it != actionList.end(); it++) {
+               int ret = (*it)->applyOneShot();
+               if (MODES_ERROR_NONE != ret && (*it)->getStopOnErr()) {
+                       ERR("Action(%s) applyOneShot Fail(%d)", (*it)->getRuleName().c_str(), ret);
+                       return ret;
+               }
+       }
+       return MODES_ERROR_NONE;
 }
 
 void Mode::undo()
index c82d0e0e414f219001a39907ac0e157c87d24813..be93091d1c6c951e37dcc5b87a79623917bcb121 100644 (file)
@@ -45,8 +45,8 @@ public:
 
        void addAction(Action *action);
        std::list<std::shared_ptr<Action>> getActionList() const;
-       void apply();
-       void applyOneShot();
+       int apply();
+       int applyOneShot();
        void undo();
 private:
        bool customized;
index dd10851ebc68961f47776ef792c0506d03e36640..6e39da0777b699dd3efc7bc4ad221cfa0dcd32b3 100644 (file)
@@ -76,7 +76,7 @@ int ModeManager::applyMode(const string &modeName)
        DBG("applyMode(%s)", path.c_str());
 
        try {
-               ModeParser *parser = getModeParser(path);
+               std::unique_ptr<ModeParser> parser(getModeParser(path));
                Mode mode = parser->getMode();
 
                DBG("applyMode(%s) Run", mode.getName().c_str());
@@ -87,16 +87,22 @@ int ModeManager::applyMode(const string &modeName)
                        return MODES_ERROR_CONFLICT;
                }
 
-               if (Mode::MODE_ONESHOT != mode.getModeType()) {
-                       mode.apply();
-                       careTaker.saveMode(mode);
+               if (Mode::MODE_ONESHOT == mode.getModeType()) {
+                       int ret = mode.applyOneShot();
+                       if (MODES_ERROR_NONE != ret) {
+                               mode.undo();
+                               return ret;
+                       }
                } else {
-                       mode.applyOneShot();
+                       int ret = mode.apply();
+                       if (MODES_ERROR_NONE != ret) {
+                               mode.undo();
+                               return ret;
+                       }
+                       careTaker.saveMode(mode);
                }
-
-               delete parser;
        } catch (ModesEx &e) {
-               ERR("parser Fail(%s)", e.what());
+               ERR("apply Fail(%s)", e.what());
        }
        return MODES_ERROR_NONE;
 }
index 1d019d6ac02835fc03afb8112830f11bcc8e7b93..6ce1a2f57f3fb58a4c9cf5e1657bad95e20be0c1 100644 (file)
@@ -31,6 +31,7 @@ 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::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";
index c8a63caeb1eb4fe1b859f2678c92136a05761186..77171d848fe0cc46c481b6bc7e138a9633070f27 100644 (file)
@@ -34,6 +34,7 @@ struct ModeTag {
        static const xmlChar* const CUSTOM;
        static const xmlChar* const ACTION;
        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;
index e9c99d1a319ba5c08442150b3f39005f90e7e86a..de32f3525b5f04faf41ffe9f91bf07d6126cf07b 100644 (file)
@@ -137,6 +137,23 @@ std::string ModeXMLParser::getXmlTagStringValue(xmlNodePtr node, const xmlChar*
        return xmlTagString;
 }
 
+void ModeXMLParser::parseActionAttr(xmlNodePtr node, Action *action)
+{
+       char *restictProp = (char*)xmlGetProp(node, ModeTag::RESTICT);
+       if (restictProp && MDS_EQUAL == strcmp(restictProp, ModeTag::RESTICT_LOCK))
+               action->setRestrict(Action::REQ_LOCK);
+       else
+               action->setRestrict(Action::REQ_NONE);
+       xmlFree(restictProp);
+
+       char *stopOnErrProp = (char*)xmlGetProp(node, ModeTag::STOP_ON_ERR);
+       if (stopOnErrProp && MDS_EQUAL == strcmp(stopOnErrProp, "true"))
+               action->setStopOnErr(true);
+       else
+               action->setStopOnErr(false);
+       xmlFree(stopOnErrProp);
+}
+
 void ModeXMLParser::parseAction(xmlNodePtr node)
 {
        char *ruleProp = (char*)xmlGetProp(node, ModeTag::RULE);
@@ -158,13 +175,7 @@ void ModeXMLParser::parseAction(xmlNodePtr node)
        bindPlugin(ruleProp, action);
        xmlFree(ruleProp);
 
-       char *restictProp = (char*)xmlGetProp(node, ModeTag::RESTICT);
-       if (restictProp && MDS_EQUAL == strcmp(restictProp, ModeTag::RESTICT_LOCK)) {
-               action->setRestrict(Action::REQ_LOCK);
-       } else {
-               action->setRestrict(Action::REQ_NONE);
-       }
-       xmlFree(restictProp);
+       parseActionAttr(node, action);
 
        char *nodeContent = (char*)xmlNodeGetContent(node);
        if (nodeContent == NULL) {
index 527440157d947fa5ecd1acbf1ee1364b55908e92..9613698e197fd5b094d95a55da3ce8da09dd4d17 100644 (file)
@@ -39,6 +39,7 @@ private:
        std::string getModeType(xmlNodePtr node);
        bool getModeCustom(xmlNodePtr node);
        std::string getXmlTagStringValue(xmlNodePtr node, const xmlChar *tag);
+       void parseActionAttr(xmlNodePtr node, Action *action);
        void parseAction(xmlNodePtr node);
        void bindPlugin(const std::string &name, Action *action);
 
index c85536cd5f6956e9183efd49b162998f0fbd95f4..c0a57a16b014afabe13fc61e3424e00daf63356a 100644 (file)
@@ -63,21 +63,37 @@ public:
                }
        }
 
-       void apply() override
+       int apply() override
        {
-               RETM_IF(NULL == plugin, "Action(%s) : No plugin", ruleName.c_str());
+               RETVM_IF(NULL == plugin, MODES_ERROR_NO_DATA, "Action(%s) : No plugin", ruleName.c_str());
 
                int pos = ruleName.find_first_of(".");
-               plugin->set(ruleName.substr(pos + 1), value, &piAction);
+               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);
+                       return ret;
+               }
                plugin->setChangedCallback(valueChangedCallback, ruleName.substr(pos + 1), this);
+
+               piAction = tmpAction;
+               return MODES_ERROR_NONE;
        }
 
-       void applyOneShot() override
+       int applyOneShot() override
        {
-               RETM_IF(NULL == plugin, "Action(%s) : No plugin", ruleName.c_str());
+               RETVM_IF(NULL == plugin, MODES_ERROR_NO_DATA, "Action(%s) : No plugin", ruleName.c_str());
 
                int pos = ruleName.find_first_of(".");
-               plugin->set(ruleName.substr(pos + 1), value, nullptr);
+               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);
+                               return ret;
+               }
+
+               piAction = tmpAction;
+               return MODES_ERROR_NONE;
        }
 
        void undo() override
index e98c86cb7f67b06df86a5352520dc0ff4110cc37..951a46f33f05c0fb673629852425aaa1e94abb41 100644 (file)
@@ -47,17 +47,7 @@ TEST(XMLParser, getModeName)
        EXPECT_EQ("ex1", modeparser.getModeName());
 }
 
-TEST(XMLParser, getMode)
-{
-       PluginManager pluginManager;
-       RuleManager ruleMgr;
-       ModeXMLParser modeparser("tizen_ex2_mode.xml", ruleMgr, pluginManager);
-       Mode mode = modeparser.getMode();
-
-       //EXPECT_TRUE(mode.empty());
-}
-
-TEST(Mode, getModeName)
+TEST(Mode, modeGetName)
 {
        PluginManager pluginManager;
        RuleManager ruleMgr;