FAFT: pulling wake* common code into firmware_test

Pulling delayed, wake_by_power_button,
wake_by_lid_switch, suspend_as_reboot into
firmware_test as it's common to both
firmware_DevModeStress and firmware_ECWakeSource.
Also increased WAKE_DELAY to 10, which is needed
for gnawty.

BUG=chromium:259640
BRANCH=none
TEST=tested on gnawty

Change-Id: Ib699f325b6d88980a1e028b770bcd0ea7febd166
Signed-off-by: Shelley Chen <shchen@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/307837
Reviewed-by: Wai-Hong Tam <waihong@chromium.org>
diff --git a/server/cros/faft/firmware_test.py b/server/cros/faft/firmware_test.py
index 6b0d322..a372e31 100644
--- a/server/cros/faft/firmware_test.py
+++ b/server/cros/faft/firmware_test.py
@@ -11,6 +11,7 @@
 import time
 import uuid
 
+from threading import Timer
 from autotest_lib.client.bin import utils
 from autotest_lib.client.common_lib import error
 from autotest_lib.server import test
@@ -59,6 +60,15 @@
     CHROMEOS_MAGIC = "CHROMEOS"
     CORRUPTED_MAGIC = "CORRUPTD"
 
+    # Delay for waiting client to return before EC suspend
+    EC_SUSPEND_DELAY = 5
+
+    # Delay between EC suspend and wake
+    WAKE_DELAY = 10
+
+    # Delay between closing and opening lid
+    LID_DELAY = 1
+
     _SERVOD_LOG = '/var/log/servod.log'
 
     _ROOTFS_PARTITION_NUMBER = 3
@@ -715,6 +725,43 @@
                 pass
         return False
 
+    def delayed(seconds):
+        logging.info("delaying %d seconds" % seconds)
+        def decorator(f):
+            def wrapper(*args, **kargs):
+                t = Timer(seconds, f, args, kargs)
+                t.start()
+            return wrapper
+        return decorator
+
+    @delayed(WAKE_DELAY)
+    def wake_by_power_button(self):
+        """Delay by WAKE_DELAY seconds and then wake DUT with power button."""
+        self.servo.power_normal_press()
+
+    @delayed(WAKE_DELAY)
+    def wake_by_lid_switch(self):
+        """Delay by WAKE_DELAY seconds and then wake DUT with lid switch."""
+        self.servo.set('lid_open', 'no')
+        time.sleep(self.LID_DELAY)
+        self.servo.set('lid_open', 'yes')
+
+    def suspend_as_reboot(self, wake_func):
+        """
+        Suspend DUT and also kill FAFT client so that this acts like a reboot.
+
+        Args:
+          wake_func: A function that is called to wake DUT. Note that this
+            function must delay itself so that we don't wake DUT before
+            suspend_as_reboot returns.
+        """
+        cmd = '(sleep %d; powerd_dbus_suspend) &' % self.EC_SUSPEND_DELAY
+        self.faft_client.system.run_shell_command(cmd)
+        self.faft_client.disconnect()
+        time.sleep(self.EC_SUSPEND_DELAY)
+        logging.info("wake function disabled")
+        wake_func()
+
     def _fetch_servo_log(self):
         """Fetch the servo log."""
         cmd = '[ -e %s ] && cat %s || echo NOTFOUND' % ((self._SERVOD_LOG,) * 2)