Add abstract factory to create button iface objects

A abstract factory class is implemented  to return
the instance of button interface class based on the
button iface formfactor name provided as
parameter to the abstract factory createInstance
 method.

Signed-off-by: Naveen Moses <naveen.mosess@hcl.com>
Change-Id: Ia791a2b6f52d09dd87da0e50a709fc72ac9d1bd7
diff --git a/inc/power_button.hpp b/inc/power_button.hpp
index 283b149..bef2662 100644
--- a/inc/power_button.hpp
+++ b/inc/power_button.hpp
@@ -15,6 +15,8 @@
 */
 
 #pragma once
+#include "button_factory.hpp"
+#include "button_interface.hpp"
 #include "common.hpp"
 #include "gpio.hpp"
 #include "xyz/openbmc_project/Chassis/Buttons/Power/server.hpp"
@@ -25,159 +27,45 @@
 #include <chrono>
 #include <phosphor-logging/elog-errors.hpp>
 
-const static constexpr char* POWER_BUTTON = "POWER_BUTTON";
+static constexpr std::string_view POWER_BUTTON = "POWER_BUTTON";
 
-struct PowerButton
-    : sdbusplus::server::object::object<
-          sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Power>
+class PowerButton
+    : public sdbusplus::server::object::object<
+          sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Power>,
+      public ButtonIface
 {
-
+  public:
     PowerButton(sdbusplus::bus::bus& bus, const char* path, EventPtr& event,
-                buttonConfig& buttonCfg,
-                sd_event_io_handler_t handler = PowerButton::EventHandler) :
+                buttonConfig& buttonCfg) :
         sdbusplus::server::object::object<
             sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Power>(
             bus, path),
-        fd(-1), buttonIFConfig(buttonCfg), bus(bus), event(event),
-        callbackHandler(handler)
+        ButtonIface(bus, event, buttonCfg)
     {
-
-        int ret = -1;
-
-        // config group gpio based on the gpio defs read from the json file
-        ret = configGroupGpio(bus, buttonIFConfig);
-
-        if (ret < 0)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "POWER_BUTTON: failed to config GPIO");
-            throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-                IOError();
-        }
-
-        // initialize the button io fd from the buttonConfig
-        // which has fd stored when configGroupGpio is called
-        fd = buttonIFConfig.gpios[0].fd;
-
-        char buf;
-        ::read(fd, &buf, sizeof(buf));
-
-        ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI,
-                              callbackHandler, this);
-        if (ret < 0)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "POWER_BUTTON: failed to add to event loop");
-            ::closeGpio(fd);
-            throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-                IOError();
-        }
+        init();
     }
 
     ~PowerButton()
     {
-        ::closeGpio(fd);
+
+        deInit();
     }
 
     void simPress() override;
     void simLongPress() override;
 
-    static const std::string getGpioName()
+    static constexpr std::string_view getFormFactorName()
     {
         return POWER_BUTTON;
     }
-
-    void updatePressedTime()
+    static constexpr const char* getDbusObjectPath()
     {
-        pressedTime = std::chrono::steady_clock::now();
+        return POWER_DBUS_OBJECT_NAME;
     }
+    void updatePressedTime();
+    auto getPressTime() const;
+    void handleEvent(sd_event_source* es, int fd, uint32_t revents) override;
 
-    auto getPressTime() const
-    {
-        return pressedTime;
-    }
-
-    static int EventHandler(sd_event_source* es, int fd, uint32_t revents,
-                            void* userdata)
-    {
-
-        int n = -1;
-        char buf = '0';
-
-        if (!userdata)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "POWER_BUTTON: userdata null!");
-            throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-                IOError();
-        }
-
-        PowerButton* powerButton = static_cast<PowerButton*>(userdata);
-
-        if (!powerButton)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "POWER_BUTTON: null pointer!");
-            throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-                IOError();
-        }
-
-        n = ::lseek(fd, 0, SEEK_SET);
-
-        if (n < 0)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "POWER_BUTTON: lseek error!");
-            throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-                IOError();
-        }
-
-        n = ::read(fd, &buf, sizeof(buf));
-        if (n < 0)
-        {
-            phosphor::logging::log<phosphor::logging::level::ERR>(
-                "POWER_BUTTON: read error!");
-            throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
-                IOError();
-        }
-
-        if (buf == '0')
-        {
-            phosphor::logging::log<phosphor::logging::level::DEBUG>(
-                "POWER_BUTTON: pressed");
-
-            powerButton->updatePressedTime();
-            // emit pressed signal
-            powerButton->pressed();
-        }
-        else
-        {
-            phosphor::logging::log<phosphor::logging::level::DEBUG>(
-                "POWER_BUTTON: released");
-
-            auto now = std::chrono::steady_clock::now();
-            auto d = std::chrono::duration_cast<std::chrono::milliseconds>(
-                now - powerButton->getPressTime());
-
-            if (d > std::chrono::milliseconds(LONG_PRESS_TIME_MS))
-            {
-                powerButton->pressedLong();
-            }
-            else
-            {
-                // released
-                powerButton->released();
-            }
-        }
-
-        return 0;
-    }
-
-  private:
-    int fd;
-    buttonConfig buttonIFConfig; // button iface io details
-    sdbusplus::bus::bus& bus;
-    EventPtr& event;
-    sd_event_io_handler_t callbackHandler;
+  protected:
     decltype(std::chrono::steady_clock::now()) pressedTime;
 };