예제 #1
0
        /**
         * Sets the goal for the rule-sets supplied.
         * @param A goal with the name of a rule-set and parameters.
         * @return true if the goal can be met by a rule-set.
         */
        public bool setGoal(EmptyElement goal)
        {
            if (m_ruleSets == null || m_ruleSets.Count == 0)
            {
                m_log.writeEltTime("fail");
                m_log.writeAttr("rule-set", "none");
                m_log.endElt();
                return(false);
            }
            if (m_goal == null && goal == null)
            {
                m_log.writeEltTime("fail");
                m_log.writeAttr("goal", "none");
                m_log.endElt();
                return(false);
            }
            if (goal != null)
            {
                m_goal = goal;                           // overwrite m_goal
            }
            else
            {
                goal = m_goal;
            }
            m_log.writeEltTime("new-goal");
            goal.log();
            m_log.endElt();
            string name = goal.getName();

            foreach (RuleSet rs in m_ruleSets)
            {
                if (name.Equals(rs.getName()))
                {
                    m_ruleSet = rs; break;
                }                                          // skip the rest of the rule-sets
            }
            if (m_ruleSet == null)
            {
                m_log.writeEltTime("fail");
                m_log.writeAttr("goal", "no rule-set can solve");
                m_log.endElt();
                return(false);
            }
            m_substitutes = new ArrayList(2);
            for (int p = 0; p < m_ruleSet.formals(); p++)
            {             // goal attributes are named the same as rule-set parameters
                string paramName = m_ruleSet.getParameterName(p);
                string value     = goal.getValue(paramName);
                string formal    = m_ruleSet.getParameterValue(p);
                m_substitutes.Add(new Substitute(formal, value));
            }
            m_rules = m_ruleSet.getRules();             // use the active rule set
            return(true);
        }
예제 #2
0
        /** Determines if this EmptyElement is the same as another.
         * Priority is ignored, negation is not ignored.
         * @param ee another EmptyElement that may be equal to this one
         * @return true if it is the same
         */
        public bool equals(EmptyElement ee)
        {
            if (ee == null)
            {
                return(false);
            }
            bool same = m_name.Equals(ee.getName());

            if (same)
            {
                return(hasSameAttributes(ee));
            }
            return(false);
        }
예제 #3
0
 /// <summary>
 /// Determines the result of a Simian action.
 /// When actions can't be performed the problem is logged
 /// and false is returned.
 /// </summary>
 /// <param name="actionRef">An action in a rule.</param>
 /// <returns>true if the action was initiated successfully.</returns>
 public bool doAction(EmptyElement actionRef)
 {
     if (actionRef.getName().Equals("launch"))
     {   // launch the specified application
         bool usedModel = false;
         string path = actionRef.getValue("path");
         if (path == null)
         {
             path = m_Config.getExePath();
             usedModel = true;
         }
         string name = actionRef.getValue("name");
         if (name == null) name = m_Config.getExeName();
         string args = actionRef.getValue("args");
         if (args == null && usedModel) args = m_Config.getExeArgs();
         string work = actionRef.getValue("work");
         if (work == null && usedModel) work = m_Config.getWorkDir();
         return LaunchApp(path, name, args, work);
     }
     if (actionRef.getName().Equals("mark"))
     {   // mark the node as indicated
         string id = actionRef.getValue("id"); // a VarNode
         if (id == null) return false;
         string As = actionRef.getValue("as"); // How to mark the node
         // As == null is valid for removing the mark.
         return m_views.Mark(id, As);
     }
     if (actionRef.getName().Equals("free"))
     {   // free the VarNode named
         string id = actionRef.getValue("id"); // the VarNode to free
         if (id == null) return false;
         m_varNodes.add(id, null);
     }
     if (actionRef.getName().Equals("choose"))
     {   // choose the control via the method and name it via id
         string control = actionRef.getValue("control"); // Type of the control to choose
         string id = actionRef.getValue("id"); // a VarNode
         string exclude = actionRef.getValue("exclude"); // How to choose
         string method = actionRef.getValue("method"); // How to choose
         if (!Utilities.isGoodStr(control)) return false;
         if (!Utilities.isGoodStr(id)) return false;
         if (!Utilities.isGoodStr(method)) return false;
         MarkedNode mn = null;
         if (control.Equals("view")) mn = m_views.Choose(method, exclude);
         if (mn == null)
         {
             m_log.writeEltTime("fail");
             m_log.writeAttr(control, mn.node.Name);
             m_log.writeAttr("was", "not known");
             m_log.endElt();
             return false;
         }
         else
         {
             m_varNodes.add(id, mn);
             m_log.writeEltTime("selected");
             m_log.writeAttr(control, mn.node.Name);
             m_log.writeAttr("as", id);
             m_log.endElt();
         }
     }
     if (actionRef.getName().Equals("nav"))
     {   // find a model path to the referenced node
         string to = actionRef.getValue("to"); // a VarNode
         string via = actionRef.getValue("via"); // a VarNode name, not set yet
         if (!Utilities.isGoodStr(to)) return false;
         MarkedNode mn = m_varNodes.get(to);
         if (mn == null) return false;
         // What kind of node is this?
         string role = XmlFiler.getStringAttr((XmlElement)mn.node, "role", "*not Found*");
         if (role.Equals("*not Found*")) return false;
         MarkedNode viaN = null;
         if (role.Equals("view"))
         {  // get the menu node via mn and name it "via"
             string xPath = "menubar//" + mn.node.Name + "[@role='menu']";
             XmlPath mPath = m_GuiModel.selectToXmlPath(null, xPath);
             if (mPath == null) return false; // really bad!
             XmlNode menuNode = mPath.ModelNode;
             if (menuNode == null) return false; // really bad again!
             viaN = new MarkedNode(menuNode, null);
             m_varNodes.add(via, viaN);
         }
         if (viaN == null) return false; // nothing more to do at the moment
     }
     if (actionRef.getName().Equals("click"))
     {   // click the specified control
         string id = actionRef.getValue("id"); // a VarNode
         string appPath = actionRef.getValue("on"); // an appPath
         string guiPath = actionRef.getValue("at"); // a giuPath
         string side = actionRef.getValue("side"); // "left" or "right"
         bool leftSide = true;
         if (side != null && side.Equals("right")) leftSide = false;
         // Id provides a context ah that must be used to find the rest of the path!
         // can't just use the appPath from it. What if it's a dialog?
         XmlNode context = null;
         MarkedNode mn = null;
         if (Utilities.isGoodStr(id))
         {
             mn = m_varNodes.get(id);
             // bail out if id not defined yet.
             if (mn == null || mn.node == null) return false;
             context = mn.node;
         }
         return click(context, appPath, guiPath, leftSide);
     }
     if (actionRef.getName().Equals("close"))
     {   // close the specified application
         if (m_proc != null) closeWindow(m_proc);
     }
     return true;
 }
예제 #4
0
 /// <summary>
 /// Determines the result of a Simian sensation.
 /// Problems with sensors are not generally logged
 /// since they are frequently called and most are not
 /// fatal.
 /// </summary>
 /// <param name="sensorRef">A sensor expression in a rule.</param>
 /// <returns>true if the sensor detected its target.</returns>
 public bool sensation(EmptyElement sensorRef)
 {
     if (sensorRef.getName().Equals("window"))
     {   // is the window showing?
         string id = sensorRef.getValue("id"); // a VarNode
         string title = sensorRef.getValue("title");
         MarkedNode mn = null;
         if (Utilities.isGoodStr(id) && Utilities.isGoodStr(title))
         {  // fetch the title from the model node via id + title
             mn = m_varNodes.get(id);
             // bail out if id not defined yet.
             if (mn == null) return false;
             if (mn.node != null)
                 title = m_GuiModel.selectToString(mn.node, title, "title");
             if (!Utilities.isGoodStr(title)) return false;
         }
         else if (id == null && title == null)
         {   // get the main window title from the model
             title = m_Config.getDataBase()+m_GuiModel.getTitle();
         }
         if (title == null) return false;  // model lacks title
         if (Utilities.isGoodStr(title))
         {
             IntPtr winHand = FindWindow(null, title);
             if ((int)winHand != 0)
             {
                 AccessibilityHelper ah = new AccessibilityHelper(winHand);
                 // look for a titlebar
                 GuiPath gPath = new GuiPath("1:NAMELESS");
                 AccessibilityHelper tah = ah.SearchPath(gPath, this);
                 if (tah == null || !tah.Value.Equals(title)) return false;
                 m_ah = ah;
                 return true;
             }
         }
     }
     if (sensorRef.getName().Equals("tested"))
     {
         string id = sensorRef.getValue("id"); // which controls
         string control = sensorRef.getValue("control"); // which controls
         string count = sensorRef.getValue("count"); // indicates how many
         if (control != null && count == null) return false;
         if (control == null && count != null) return false;
         if (control == null && count == null && id == null) return false;
         if (id != null)
         {
             MarkedNode mn = m_varNodes.get(id);
             if (mn != null)
             {
                 if (mn.mark == null) return false;
                 return mn.mark.Equals("tested");
             }
         }
         // if id fails to return a marked node, try a control count
         if (control != null)
         {
             int n = 0; int k = 0;
             if (control.Equals("view"))
             {
                 if (m_views == null) m_views = new MarkedList(m_GuiModel, "//*[@role='view']");
                 n = m_views.Count();
                 k = m_views.Count("tested");
             }
             if (count.Equals("all") && n == k) return true;
             if (count.Equals("not-all") && k < n) return true;
             return false;
         }
         return false;
     }
     if (sensorRef.getName().Equals("glimpse"))
     {
         string id = sensorRef.getValue("id"); // a VarNode
         string appPath = sensorRef.getValue("on"); // an appPath
         string guiPath = sensorRef.getValue("at"); // a giuPath
         string property = sensorRef.getValue("prop"); // an ah property
         string expect = sensorRef.getValue("expect"); // value expected
         // Id provides a context ah that must be used to find the rest of the path!
         // can't just use the appPath from it. What if it's a dialog?
         XmlNode context = null;
         MarkedNode mn = null;
         if (Utilities.isGoodStr(id))
         {
             mn = m_varNodes.get(id);
             // bail out if id not defined yet.
             if (mn == null) return false;
             if (mn.node != null) context = mn.node;
         }
         return glimpse(context, appPath, guiPath, property, expect);
     }
     return false;
 }
예제 #5
0
 /**
  * Sets the goal for the rule-sets supplied.
  * @param A goal with the name of a rule-set and parameters.
  * @return true if the goal can be met by a rule-set.
  */
 public bool setGoal(EmptyElement goal)
 {
     if (m_ruleSets == null || m_ruleSets.Count == 0)
     {
         m_log.writeEltTime("fail");
         m_log.writeAttr("rule-set","none");
         m_log.endElt();
         return false;
     }
     if (m_goal == null && goal == null)
     {
         m_log.writeEltTime("fail");
         m_log.writeAttr("goal","none");
         m_log.endElt();
         return false;
     }
     if (goal != null) m_goal = goal; // overwrite m_goal
     else              goal = m_goal;
     m_log.writeEltTime("new-goal");
     goal.log();
     m_log.endElt();
     string name = goal.getName();
     foreach (RuleSet rs in m_ruleSets)
     {   if (name.Equals(rs.getName()))
         { m_ruleSet = rs; break; } // skip the rest of the rule-sets
     }
     if (m_ruleSet == null)
     {
         m_log.writeEltTime("fail");
         m_log.writeAttr("goal","no rule-set can solve");
         m_log.endElt();
         return false;
     }
     m_substitutes = new ArrayList(2);
     for (int p = 0; p < m_ruleSet.formals(); p++)
     { // goal attributes are named the same as rule-set parameters
         string paramName = m_ruleSet.getParameterName(p);
         string value = goal.getValue(paramName);
         string formal = m_ruleSet.getParameterValue(p);
         m_substitutes.Add(new Substitute(formal,value));
     }
     m_rules = m_ruleSet.getRules(); // use the active rule set
     return true;
 }
예제 #6
0
        /**
         * Perform goal-driven actions based on sensor readings.
         * Performance continues until a "done" action is encountered.
         * Performance may be interrupted if a "fail" action,
         * runtime error or timeout occurs.
         * Rule order is important. Rules are evaluated in order.
         * The most difficult to evaluate should be the first rule,
         * the easiest to satisfy, the last.
         * @return true if the "done" action is reached, otherwise false.
         */
        public bool act()
        {
            bool alive     = true;
            bool result    = false;
            Rule lastFired = null;

            while (alive)
            {               // evaluate the rules in order.
                // the same rule can not fire twice in a row
                foreach (Rule rule in m_rules)
                {
                    if (rule.evaluate(m_sensors, m_substitutes))
                    {                       // fire: get the rule's actions
                        if (rule == lastFired && !rule.isFireAlways())
                        {
                            break;
                        }                                   // skip the rest of the rules
                        lastFired = rule;
                        rule.logCondition(true, m_substitutes);
                        ArrayList actions = rule.getActions();
                        // foreach action:
                        foreach (EmptyElement act in actions)
                        {                           // log the action.
                            EmptyElement action = act.SubstituteCopy(m_substitutes);
                            action.log(true);
                            // if it is a sensact action, consume it
                            string name = action.getName();
                            if (name.Equals("done"))
                            {
                                return(true);
                            }
                            if (name.Equals("fail"))
                            {
                                return(false);
                            }
                            // if (name.Equals("try")) {}
                            // if (name.Equals("lookup")) {}
                            // if (name.Equals("log")) {}
                            // does the action activate another rule-set?
                            RuleSet ActivateRs = null;
                            foreach (RuleSet rs in m_ruleSets)
                            {
                                if (name.Equals(rs.getName()))
                                {
                                    ActivateRs = rs; break;
                                }                                                           // skip the rest of the rule-sets
                            }
                            if (ActivateRs != null)
                            {                               // instantiate another Sensact to use the rule-set
                                // suspend this rule-set, activate rs.
                                result = doSubGoal(ActivateRs, action);
                                alive  = result;
                            }
                            else
                            {                             // otherwise, send it to the appliction to exectue
                                result = m_actions.doAction(action);
                                alive  = result;
                            }
                            if (!alive)
                            {
                                break;
                            }
                        }         // end of for each action
                        break;    // skip the rest of the rules
                    }             // end of if rule fired
                }                 // end for each rule
            }
            return(result);
        }
예제 #7
0
 /// <summary>
 /// Determines the result of a Simian sensation.
 /// Problems with sensors are not generally logged
 /// since they are frequently called and most are not
 /// fatal.
 /// </summary>
 /// <param name="sensorRef">A sensor expression in a rule.</param>
 /// <returns>true if the sensor detected its target.</returns>
 public bool sensation(EmptyElement sensorRef)
 {
     if (sensorRef.getName().Equals("window"))
     {                                                // is the window showing?
         string     id    = sensorRef.getValue("id"); // a VarNode
         string     title = sensorRef.getValue("title");
         MarkedNode mn    = null;
         if (Utilities.isGoodStr(id) && Utilities.isGoodStr(title))
         {                  // fetch the title from the model node via id + title
             mn = m_varNodes.get(id);
             // bail out if id not defined yet.
             if (mn == null)
             {
                 return(false);
             }
             if (mn.node != null)
             {
                 title = m_GuiModel.selectToString(mn.node, title, "title");
             }
             if (!Utilities.isGoodStr(title))
             {
                 return(false);
             }
         }
         else if (id == null && title == null)
         {                   // get the main window title from the model
             title = m_Config.getDataBase() + m_GuiModel.getTitle();
         }
         if (title == null)
         {
             return(false);                                // model lacks title
         }
         if (Utilities.isGoodStr(title))
         {
             IntPtr winHand = FindWindow(null, title);
             if ((int)winHand != 0)
             {
                 AccessibilityHelper ah = new AccessibilityHelper(winHand);
                 // look for a titlebar
                 GuiPath             gPath = new GuiPath("1:NAMELESS");
                 AccessibilityHelper tah   = ah.SearchPath(gPath, this);
                 if (tah == null || !tah.Value.Equals(title))
                 {
                     return(false);
                 }
                 m_ah = ah;
                 return(true);
             }
         }
     }
     if (sensorRef.getName().Equals("tested"))
     {
         string id      = sensorRef.getValue("id");            // which controls
         string control = sensorRef.getValue("control");       // which controls
         string count   = sensorRef.getValue("count");         // indicates how many
         if (control != null && count == null)
         {
             return(false);
         }
         if (control == null && count != null)
         {
             return(false);
         }
         if (control == null && count == null && id == null)
         {
             return(false);
         }
         if (id != null)
         {
             MarkedNode mn = m_varNodes.get(id);
             if (mn != null)
             {
                 if (mn.mark == null)
                 {
                     return(false);
                 }
                 return(mn.mark.Equals("tested"));
             }
         }
         // if id fails to return a marked node, try a control count
         if (control != null)
         {
             int n = 0; int k = 0;
             if (control.Equals("view"))
             {
                 if (m_views == null)
                 {
                     m_views = new MarkedList(m_GuiModel, "//*[@role='view']");
                 }
                 n = m_views.Count();
                 k = m_views.Count("tested");
             }
             if (count.Equals("all") && n == k)
             {
                 return(true);
             }
             if (count.Equals("not-all") && k < n)
             {
                 return(true);
             }
             return(false);
         }
         return(false);
     }
     if (sensorRef.getName().Equals("glimpse"))
     {
         string id       = sensorRef.getValue("id");           // a VarNode
         string appPath  = sensorRef.getValue("on");           // an appPath
         string guiPath  = sensorRef.getValue("at");           // a giuPath
         string property = sensorRef.getValue("prop");         // an ah property
         string expect   = sensorRef.getValue("expect");       // value expected
         // Id provides a context ah that must be used to find the rest of the path!
         // can't just use the appPath from it. What if it's a dialog?
         XmlNode    context = null;
         MarkedNode mn      = null;
         if (Utilities.isGoodStr(id))
         {
             mn = m_varNodes.get(id);
             // bail out if id not defined yet.
             if (mn == null)
             {
                 return(false);
             }
             if (mn.node != null)
             {
                 context = mn.node;
             }
         }
         return(glimpse(context, appPath, guiPath, property, expect));
     }
     return(false);
 }
예제 #8
0
 /// <summary>
 /// Determines the result of a Simian action.
 /// When actions can't be performed the problem is logged
 /// and false is returned.
 /// </summary>
 /// <param name="actionRef">An action in a rule.</param>
 /// <returns>true if the action was initiated successfully.</returns>
 public bool doAction(EmptyElement actionRef)
 {
     if (actionRef.getName().Equals("launch"))
     {               // launch the specified application
         bool   usedModel = false;
         string path      = actionRef.getValue("path");
         if (path == null)
         {
             path      = m_Config.getExePath();
             usedModel = true;
         }
         string name = actionRef.getValue("name");
         if (name == null)
         {
             name = m_Config.getExeName();
         }
         string args = actionRef.getValue("args");
         if (args == null && usedModel)
         {
             args = m_Config.getExeArgs();
         }
         string work = actionRef.getValue("work");
         if (work == null && usedModel)
         {
             work = m_Config.getWorkDir();
         }
         return(LaunchApp(path, name, args, work));
     }
     if (actionRef.getName().Equals("mark"))
     {                                         // mark the node as indicated
         string id = actionRef.getValue("id"); // a VarNode
         if (id == null)
         {
             return(false);
         }
         string As = actionRef.getValue("as");                 // How to mark the node
         // As == null is valid for removing the mark.
         return(m_views.Mark(id, As));
     }
     if (actionRef.getName().Equals("free"))
     {                                         // free the VarNode named
         string id = actionRef.getValue("id"); // the VarNode to free
         if (id == null)
         {
             return(false);
         }
         m_varNodes.add(id, null);
     }
     if (actionRef.getName().Equals("choose"))
     {                                                   // choose the control via the method and name it via id
         string control = actionRef.getValue("control"); // Type of the control to choose
         string id      = actionRef.getValue("id");      // a VarNode
         string exclude = actionRef.getValue("exclude"); // How to choose
         string method  = actionRef.getValue("method");  // How to choose
         if (!Utilities.isGoodStr(control))
         {
             return(false);
         }
         if (!Utilities.isGoodStr(id))
         {
             return(false);
         }
         if (!Utilities.isGoodStr(method))
         {
             return(false);
         }
         MarkedNode mn = null;
         if (control.Equals("view"))
         {
             mn = m_views.Choose(method, exclude);
         }
         if (mn == null)
         {
             m_log.writeEltTime("fail");
             m_log.writeAttr(control, mn.node.Name);
             m_log.writeAttr("was", "not known");
             m_log.endElt();
             return(false);
         }
         else
         {
             m_varNodes.add(id, mn);
             m_log.writeEltTime("selected");
             m_log.writeAttr(control, mn.node.Name);
             m_log.writeAttr("as", id);
             m_log.endElt();
         }
     }
     if (actionRef.getName().Equals("nav"))
     {                                           // find a model path to the referenced node
         string to  = actionRef.getValue("to");  // a VarNode
         string via = actionRef.getValue("via"); // a VarNode name, not set yet
         if (!Utilities.isGoodStr(to))
         {
             return(false);
         }
         MarkedNode mn = m_varNodes.get(to);
         if (mn == null)
         {
             return(false);
         }
         // What kind of node is this?
         string role = XmlFiler.getStringAttr((XmlElement)mn.node, "role", "*not Found*");
         if (role.Equals("*not Found*"))
         {
             return(false);
         }
         MarkedNode viaN = null;
         if (role.Equals("view"))
         {                  // get the menu node via mn and name it "via"
             string  xPath = "menubar//" + mn.node.Name + "[@role='menu']";
             XmlPath mPath = m_GuiModel.selectToXmlPath(null, xPath);
             if (mPath == null)
             {
                 return(false);                                   // really bad!
             }
             XmlNode menuNode = mPath.ModelNode;
             if (menuNode == null)
             {
                 return(false);                                      // really bad again!
             }
             viaN = new MarkedNode(menuNode, null);
             m_varNodes.add(via, viaN);
         }
         if (viaN == null)
         {
             return(false);                              // nothing more to do at the moment
         }
     }
     if (actionRef.getName().Equals("click"))
     {                                                 // click the specified control
         string id       = actionRef.getValue("id");   // a VarNode
         string appPath  = actionRef.getValue("on");   // an appPath
         string guiPath  = actionRef.getValue("at");   // a giuPath
         string side     = actionRef.getValue("side"); // "left" or "right"
         bool   leftSide = true;
         if (side != null && side.Equals("right"))
         {
             leftSide = false;
         }
         // Id provides a context ah that must be used to find the rest of the path!
         // can't just use the appPath from it. What if it's a dialog?
         XmlNode    context = null;
         MarkedNode mn      = null;
         if (Utilities.isGoodStr(id))
         {
             mn = m_varNodes.get(id);
             // bail out if id not defined yet.
             if (mn == null || mn.node == null)
             {
                 return(false);
             }
             context = mn.node;
         }
         return(click(context, appPath, guiPath, leftSide));
     }
     if (actionRef.getName().Equals("close"))
     {               // close the specified application
         if (m_proc != null)
         {
             closeWindow(m_proc);
         }
     }
     return(true);
 }
예제 #9
0
 /** Determines if this EmptyElement is the same as another.
  * Priority is ignored, negation is not ignored.
  * @param ee another EmptyElement that may be equal to this one
  * @return true if it is the same
  */
 public bool equals(EmptyElement ee)
 {
     if (ee == null) return false;
     bool same = m_name.Equals(ee.getName());
     if (same) return hasSameAttributes(ee);
     return false;
 }