Activation: Support to update multiple PSUs

Queue the update on multiple PSUs, and do the update one-by-one.

Tested: Write unit test cases and verify the cases pass.
        On witherspoon, verify the dummy update services are run on all
        PSUs.

Signed-off-by: Lei YU <mine260309@gmail.com>
Change-Id: Icfe0f6e74623e54840df8d731d852d53d6071768
diff --git a/src/activation.hpp b/src/activation.hpp
index d7880f6..59364e4 100644
--- a/src/activation.hpp
+++ b/src/activation.hpp
@@ -4,6 +4,7 @@
 
 #include "types.hpp"
 
+#include <queue>
 #include <sdbusplus/server.hpp>
 #include <xyz/openbmc_project/Association/Definitions/server.hpp>
 #include <xyz/openbmc_project/Software/Activation/server.hpp>
@@ -11,6 +12,8 @@
 #include <xyz/openbmc_project/Software/ActivationProgress/server.hpp>
 #include <xyz/openbmc_project/Software/ExtendedVersion/server.hpp>
 
+class TestActivation;
+
 namespace phosphor
 {
 namespace software
@@ -106,7 +109,9 @@
 class Activation : public ActivationInherit
 {
   public:
+    friend class ::TestActivation;
     using Status = Activations;
+
     /** @brief Constructs Activation Software Manager
      *
      * @param[in] bus    - The Dbus bus object
@@ -118,9 +123,7 @@
      */
     Activation(sdbusplus::bus::bus& bus, const std::string& path,
                const std::string& versionId, const std::string& extVersion,
-               sdbusplus::xyz::openbmc_project::Software::server::Activation::
-                   Activations activationStatus,
-               const AssociationList& assocs) :
+               Status activationStatus, const AssociationList& assocs) :
         ActivationInherit(bus, path.c_str(), true),
         versionId(versionId), bus(bus), path(path),
         systemdSignals(
@@ -146,7 +149,7 @@
      *
      * @return Success or exception thrown
      */
-    Activations activation(Activations value) override;
+    Status activation(Status value) override;
 
     /** @brief Activation */
     using ActivationInherit::activation;
@@ -180,8 +183,28 @@
      */
     void deleteImageManagerObject();
 
+    /** @brief Invoke the update service for the PSU
+     *
+     * @param[in] psuInventoryPath - The PSU inventory to be updated.
+     *
+     * @return true if the update starts, and false if it fails.
+     */
+    bool doUpdate(const std::string& psuInventoryPath);
+
+    /** @brief Do PSU update one-by-one
+     *
+     * @return true if the update starts, and false if it fails.
+     */
+    bool doUpdate();
+
+    /** @brief Handle an update done event */
+    void onUpdateDone();
+
+    /** @brief Handle an update failure event */
+    void onUpdateFailed();
+
     /** @brief Start PSU update */
-    void startActivation();
+    Status startActivation();
 
     /** @brief Finish PSU update */
     void finishActivation();
@@ -195,6 +218,12 @@
     /** @brief Used to subscribe to dbus systemd signals */
     sdbusplus::bus::match_t systemdSignals;
 
+    /** @brief The queue of psu objects to be updated */
+    std::queue<std::string> psuQueue;
+
+    /** @brief The progress step for each PSU update is done */
+    uint32_t progressStep;
+
     /** @brief The PSU update systemd unit */
     std::string psuUpdateUnit;