Refactor: Split Activation into common and ubi

Activations has a few functions coupled with ubi, split them into
ubi/activation_ubi

* Keep common code in activation.
* Make start/finishActivation() pure virtual.
* Move ubi specific code into ubi.
* Move ubiVolumnCreated into ubi.
* Make validateSignature() not inline, otherwise it gets compile error.

Tested: On the last commit of the patch series, run code update and
        factory reset on Witherspoon and all work fine.

Change-Id: I7c8a0de6b0be4b1e9814ea75fd802a014b4aacfc
Signed-off-by: Lei YU <mine260309@gmail.com>
diff --git a/ubi/activation_ubi.cpp b/ubi/activation_ubi.cpp
new file mode 100644
index 0000000..9ce7085
--- /dev/null
+++ b/ubi/activation_ubi.cpp
@@ -0,0 +1,183 @@
+#include "activation_ubi.hpp"
+
+#include "item_updater.hpp"
+#include "serialize.hpp"
+
+#include <experimental/filesystem>
+
+namespace openpower
+{
+namespace software
+{
+namespace updater
+{
+namespace fs = std::experimental::filesystem;
+namespace softwareServer = sdbusplus::xyz::openbmc_project::Software::server;
+
+uint8_t RedundancyPriorityUbi::priority(uint8_t value)
+{
+    storeToFile(parent.versionId, value);
+    return RedundancyPriority::priority(value);
+}
+
+auto ActivationUbi::activation(Activations value) -> Activations
+{
+
+    if (value != softwareServer::Activation::Activations::Active)
+    {
+        redundancyPriority.reset(nullptr);
+    }
+
+    if (value == softwareServer::Activation::Activations::Activating)
+    {
+        parent.freeSpace();
+        softwareServer::Activation::activation(value);
+
+        if (ubiVolumesCreated == false)
+        {
+            // Enable systemd signals
+            subscribeToSystemdSignals();
+
+#ifdef WANT_SIGNATURE_VERIFY
+            // Validate the signed image.
+            if (!validateSignature())
+            {
+                // Cleanup
+                activationBlocksTransition.reset(nullptr);
+                activationProgress.reset(nullptr);
+
+                return softwareServer::Activation::activation(
+                    softwareServer::Activation::Activations::Failed);
+            }
+#endif
+            startActivation();
+            return softwareServer::Activation::activation(value);
+        }
+        else if (ubiVolumesCreated == true)
+        {
+            // Only when the squashfs image is finished loading AND the RW
+            // volumes have been created do we proceed with activation. To
+            // verify that this happened, we check for the mount dirs PNOR_PRSV
+            // and PNOR_RW_PREFIX_<versionid>, as well as the image dir R0.
+
+            if ((fs::is_directory(PNOR_PRSV)) &&
+                (fs::is_directory(PNOR_RW_PREFIX + versionId)) &&
+                (fs::is_directory(PNOR_RO_PREFIX + versionId)))
+            {
+                finishActivation();
+                return softwareServer::Activation::activation(
+                    softwareServer::Activation::Activations::Active);
+            }
+            else
+            {
+                activationBlocksTransition.reset(nullptr);
+                activationProgress.reset(nullptr);
+                return softwareServer::Activation::activation(
+                    softwareServer::Activation::Activations::Failed);
+            }
+        }
+    }
+    else
+    {
+        activationBlocksTransition.reset(nullptr);
+        activationProgress.reset(nullptr);
+    }
+
+    return softwareServer::Activation::activation(value);
+}
+
+auto ActivationUbi::requestedActivation(RequestedActivations value)
+    -> RequestedActivations
+{
+    ubiVolumesCreated = false;
+    return Activation::requestedActivation(value);
+}
+
+void ActivationUbi::startActivation()
+{
+    // Since the squashfs image has not yet been loaded to pnor and the
+    // RW volumes have not yet been created, we need to start the
+    // service files for each of those actions.
+
+    if (!activationProgress)
+    {
+        activationProgress = std::make_unique<ActivationProgress>(bus, path);
+    }
+
+    if (!activationBlocksTransition)
+    {
+        activationBlocksTransition =
+            std::make_unique<ActivationBlocksTransition>(bus, path);
+    }
+
+    constexpr auto ubimountService = "obmc-flash-bios-ubimount@";
+    auto ubimountServiceFile =
+        std::string(ubimountService) + versionId + ".service";
+    auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
+                                      SYSTEMD_INTERFACE, "StartUnit");
+    method.append(ubimountServiceFile, "replace");
+    bus.call_noreply(method);
+
+    activationProgress->progress(10);
+}
+
+void ActivationUbi::unitStateChange(sdbusplus::message::message& msg)
+{
+    uint32_t newStateID{};
+    sdbusplus::message::object_path newStateObjPath;
+    std::string newStateUnit{};
+    std::string newStateResult{};
+
+    // Read the msg and populate each variable
+    msg.read(newStateID, newStateObjPath, newStateUnit, newStateResult);
+
+    auto ubimountServiceFile =
+        "obmc-flash-bios-ubimount@" + versionId + ".service";
+
+    if (newStateUnit == ubimountServiceFile && newStateResult == "done")
+    {
+        ubiVolumesCreated = true;
+        activationProgress->progress(activationProgress->progress() + 50);
+    }
+
+    if (ubiVolumesCreated)
+    {
+        activation(softwareServer::Activation::Activations::Activating);
+    }
+
+    if ((newStateUnit == ubimountServiceFile) &&
+        (newStateResult == "failed" || newStateResult == "dependency"))
+    {
+        activation(softwareServer::Activation::Activations::Failed);
+    }
+
+    return;
+}
+
+void ActivationUbi::finishActivation()
+{
+    activationProgress->progress(90);
+
+    // Set Redundancy Priority before setting to Active
+    if (!redundancyPriority)
+    {
+        redundancyPriority =
+            std::make_unique<RedundancyPriorityUbi>(bus, path, *this, 0);
+    }
+
+    activationProgress->progress(100);
+
+    activationBlocksTransition.reset(nullptr);
+    activationProgress.reset(nullptr);
+
+    ubiVolumesCreated = false;
+    unsubscribeFromSystemdSignals();
+    // Remove version object from image manager
+    deleteImageManagerObject();
+    // Create active association
+    parent.createActiveAssociation(path);
+}
+
+} // namespace updater
+} // namespace software
+} // namespace openpower