Refresh service states for a group

Prior to an action resulting from missing service owners, all of the
services for a group should be refreshed to ensure they are in the most
up-to-date state. Ensuring the service states are current allows the
action to be correctly taken since owners of services could change at
anytime.

Change-Id: I59c59c6fcf456fa9c0a733d6406c90ea11f6e2b2
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/actions.cpp b/control/actions.cpp
index 66bba2b..8ecd30c 100644
--- a/control/actions.cpp
+++ b/control/actions.cpp
@@ -83,6 +83,8 @@
 
 void default_floor_on_missing_owner(Zone& zone, const Group& group)
 {
+    // Set/update the services of the group
+    zone.setServices(&group);
     auto services = zone.getGroupServices(&group);
     auto defFloor = std::any_of(
         services.begin(),
@@ -103,6 +105,8 @@
 {
     return [speed](control::Zone& zone, const Group& group)
     {
+        // Set/update the services of the group
+        zone.setServices(&group);
         auto services = zone.getGroupServices(&group);
         auto missingOwner = std::any_of(
             services.begin(),
diff --git a/control/zone.cpp b/control/zone.cpp
index cb8ebfa..5fe9b01 100644
--- a/control/zone.cpp
+++ b/control/zone.cpp
@@ -150,6 +150,36 @@
     }
 }
 
+void Zone::setServices(const Group* group)
+{
+    // TODO Remove empty service name if exists
+    for (auto it = group->begin(); it != group->end(); ++it)
+    {
+        std::string name;
+        bool hasOwner = false;
+        try
+        {
+            name = util::SDBusPlus::getService(
+                    _bus,
+                    it->first,
+                    std::get<intfPos>(it->second));
+            hasOwner = util::SDBusPlus::callMethodAndRead<bool>(
+                    _bus,
+                    "org.freedesktop.DBus",
+                    "/org/freedesktop/DBus",
+                    "org.freedesktop.DBus",
+                    "NameHasOwner",
+                    name);
+        }
+        catch (const InternalFailure& ife)
+        {
+            // Failed to get service name owner state
+            hasOwner = false;
+        }
+        setServiceOwner(group, name, hasOwner);
+    }
+}
+
 void Zone::setFloor(uint64_t speed)
 {
     // Check all entries are set to allow floor to be set
diff --git a/control/zone.hpp b/control/zone.hpp
index fa3ed82..9565933 100644
--- a/control/zone.hpp
+++ b/control/zone.hpp
@@ -151,6 +151,13 @@
                              const bool hasOwner);
 
         /**
+         * @brief Set or update all services for a group
+         *
+         * @param[in] group - Group to get service names for
+         */
+        void setServices(const Group* group);
+
+        /**
          * @brief Get the group's list of service names
          *
          * @param[in] group - Group to get service names for