Add long press support to the power button

If the power button has been pressed longer than
LONG_PRESS_TIME_MS, then issue the PressedLong signal
instead of the Released signal.

LONG_PRESS_TIME_MS can be changed at compile time.

Change-Id: Iad4922735a378e45e58d70b9e1400d0e09f784c6
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5115501..c62c187 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,11 +14,13 @@
 set(RESET_DBUS_OBJECT_NAME "xyz/openbmc_project/Chassis/Buttons/Reset")
 set(ID_DBUS_OBJECT_NAME "xyz/openbmc_project/Chassis/Buttons/ID")
 set(GPIO_BASE_LABEL_NAME "1e780000.gpio")
+set(LONG_PRESS_TIME_MS 3000)
 
 add_definitions(-DPOWER_DBUS_OBJECT_NAME="/${POWER_DBUS_OBJECT_NAME}0")
 add_definitions(-DRESET_DBUS_OBJECT_NAME="/${RESET_DBUS_OBJECT_NAME}0")
 add_definitions(-DID_DBUS_OBJECT_NAME="/${ID_DBUS_OBJECT_NAME}0")
 add_definitions(-DGPIO_BASE_LABEL_NAME="${GPIO_BASE_LABEL_NAME}")
+add_definitions(-DLONG_PRESS_TIME_MS=${LONG_PRESS_TIME_MS})
 set(SRC_FILES src/power_button.cpp
     src/reset_button.cpp
     src/id_button.cpp
diff --git a/inc/power_button.hpp b/inc/power_button.hpp
index e4cc660..ce8df46 100644
--- a/inc/power_button.hpp
+++ b/inc/power_button.hpp
@@ -22,6 +22,7 @@
 
 #include <unistd.h>
 
+#include <chrono>
 #include <phosphor-logging/elog-errors.hpp>
 
 const static constexpr char* POWER_BUTTON = "POWER_BUTTON";
@@ -76,6 +77,16 @@
         return POWER_BUTTON;
     }
 
+    void updatePressedTime()
+    {
+        pressedTime = std::chrono::steady_clock::now();
+    }
+
+    auto getPressTime() const
+    {
+        return pressedTime;
+    }
+
     static int EventHandler(sd_event_source* es, int fd, uint32_t revents,
                             void* userdata)
     {
@@ -124,6 +135,8 @@
         {
             phosphor::logging::log<phosphor::logging::level::DEBUG>(
                 "POWER_BUTTON: pressed");
+
+            powerButton->updatePressedTime();
             // emit pressed signal
             powerButton->pressed();
         }
@@ -131,8 +144,20 @@
         {
             phosphor::logging::log<phosphor::logging::level::DEBUG>(
                 "POWER_BUTTON: released");
-            // released
-            powerButton->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;
@@ -143,4 +168,5 @@
     sdbusplus::bus::bus& bus;
     EventPtr& event;
     sd_event_io_handler_t callbackHandler;
+    decltype(std::chrono::steady_clock::now()) pressedTime;
 };