faft: Rewrite the test logic of FwScreenCloseLid FAFT

Rewrite the test logic of FwScreenCloseLid to support:
 - Keyboard controlled recovery switching;
 - Close lid during the new TO_NORM screen;
 - Wait longer for the screens without timeout.

BUG=chromium-os:32976
TEST=run firmware_FwScreenCloseLid on Link passed.

Change-Id: I4fd3404635d0068289c35dd26d93a98de0b9ea31
Reviewed-on: https://gerrit.chromium.org/gerrit/28585
Reviewed-by: Randall Spangler <rspangler@chromium.org>
Commit-Ready: Tom Wai-Hong Tam <waihong@chromium.org>
Tested-by: Tom Wai-Hong Tam <waihong@chromium.org>
diff --git a/server/cros/faftsequence.py b/server/cros/faftsequence.py
index 4c6366b..1989608 100644
--- a/server/cros/faftsequence.py
+++ b/server/cros/faftsequence.py
@@ -707,6 +707,12 @@
         self.servo.lid_close()
 
 
+    def wait_longer_fw_screen_and_close_lid(self):
+        """Wait for firmware screen without timeout and close lid."""
+        time.sleep(self.FIRMWARE_SCREEN_DELAY)
+        self.wait_fw_screen_and_close_lid()
+
+
     def setup_tried_fwb(self, tried_fwb):
         """Setup for fw B tried state.
 
diff --git a/server/site_tests/firmware_FwScreenCloseLid/control b/server/site_tests/firmware_FwScreenCloseLid/control
index 780d78b..8a8f54d 100644
--- a/server/site_tests/firmware_FwScreenCloseLid/control
+++ b/server/site_tests/firmware_FwScreenCloseLid/control
@@ -15,14 +15,14 @@
 DOC = """
 This test requires a USB disk plugged-in, which contains a Chrome OS test
 image (built by "build_image --test"). On runtime, this test triggers
-four firmware screens (developer, remove, insert, and yuck screens), and
-then closes the lid in order to power the machine down.
+firmware screens (developer, remove, insert, yuck, to_norm screens),
+and then closes the lid in order to power the machine down.
 """
 
 def run_fwscreencloselid(machine):
     host = hosts.create_host(machine)
     job.run_test("firmware_FwScreenCloseLid", host=host, cmdline_args=args,
                  use_faft=True, disable_sysinfo=True,
-                 dev_mode=False, tag="normal")
+                 dev_mode=True, tag="dev")
 
 parallel_simple(run_fwscreencloselid, machines)
diff --git a/server/site_tests/firmware_FwScreenCloseLid/firmware_FwScreenCloseLid.py b/server/site_tests/firmware_FwScreenCloseLid/firmware_FwScreenCloseLid.py
index 9e8db43..422343a 100644
--- a/server/site_tests/firmware_FwScreenCloseLid/firmware_FwScreenCloseLid.py
+++ b/server/site_tests/firmware_FwScreenCloseLid/firmware_FwScreenCloseLid.py
@@ -14,33 +14,33 @@
 
     This test requires a USB disk plugged-in, which contains a Chrome OS test
     image (built by "build_image --test"). On runtime, this test triggers
-    four firmware screens (developer, remove, insert, and yuck screens), and
-    then closes the lid in order to power the machine down.
+    firmware screens (developer, remove, insert, yuck, to_norm screens),
+    and then closes the lid in order to power the machine down.
     """
     version = 1
 
     has_lid = False
 
-    def wait_insert_screen_and_close_lid(self):
-        """Wait and trigger recovery insert screen and close lid."""
+
+    def wait_second_screen_and_close_lid(self):
+        """Wait and trigger TO_NORM or RECOVERY INSERT screen and close lid."""
         self.wait_fw_screen_and_trigger_recovery()
-        self.wait_fw_screen_and_close_lid()
+        self.wait_longer_fw_screen_and_close_lid()
 
 
     def wait_yuck_screen_and_close_lid(self):
-        """Wait and trigger yuck screen and close_lid."""
-        self.wait_fw_screen_and_trigger_recovery()
+        """Wait and trigger yuck screen and clod lid."""
         # Insert a corrupted USB stick. A yuck screen is expected.
-        time.sleep(self.USB_LOAD_DELAY)
         self.servo.set('usb_mux_sel1', 'dut_sees_usbkey')
-        self.wait_fw_screen_and_close_lid()
+        time.sleep(self.USB_LOAD_DELAY)
+        self.wait_longer_fw_screen_and_close_lid()
 
 
     def setup(self):
         super(firmware_FwScreenCloseLid, self).setup()
         if self.faft_client.get_platform_name() not in ('Stumpy'):
             self.has_lid = True
-            self.setup_dev_mode(dev_mode=False)
+            self.setup_dev_mode(dev_mode=True)
             self.servo.set('usb_mux_sel1', 'servo_sees_usbkey')
             usb_dev = self.servo.probe_host_usb_dev()
             # Corrupt the kernel of USB stick. It is needed for triggering a
@@ -59,47 +59,61 @@
 
     def run_once(self, host=None):
         self.register_faft_sequence((
-            {   # Step 1, enable dev mode and dev firmware. When the developer
-                # screen shown, close lid to make DUT shutdown.
+            {   # Step 1, expected dev mode and reboot.
+                # When the next DEVELOPER SCREEN shown, close lid
+                # to make DUT shutdown.
                 'state_checker': (self.crossystem_checker, {
-                    'devsw_boot': '0',
-                    'mainfw_type': 'normal',
+                    'devsw_boot': '1',
+                    'mainfw_type': 'developer',
                     'recoverysw_boot': '0',
                 }),
-                'userspace_action': self.enable_dev_mode_and_fw,
-                'reboot_action': None,
                 'firmware_action': (self.run_shutdown_process,
                                     self.wait_fw_screen_and_close_lid,
                                     self.servo.lid_open,
                                     self.wait_fw_screen_and_ctrl_d),
             },
             {   # Step 2, reboot. When the developer screen shown, press
-                # enter key to trigger recovery insert screen. Then close
-                # lid to make DUT shutdown.
+                # enter key to trigger either TO_NORM screen (new) or
+                # RECOVERY INSERT screen (old). Then close lid to
+                # make DUT shutdown.
                 'state_checker': (self.crossystem_checker, {
                     'devsw_boot': '1',
                     'mainfw_type': 'developer',
                     'recoverysw_boot': '0',
                 }),
                 'firmware_action': (self.run_shutdown_process,
-                                    self.wait_insert_screen_and_close_lid,
+                                    self.wait_second_screen_and_close_lid,
                                     self.servo.lid_open,
                                     self.wait_fw_screen_and_ctrl_d),
             },
-            {   # Step 3, reboot. When the developer screen shown, press
-                # enter key and insert a corrupted USB stick to trigger
-                # yuck screen. Then close lid to make DUT shutdown.
+            {   # Step 3, request recovery boot. When the RECOVERY INSERT
+                # screen shows, close lid to make DUT shutdown.
                 'state_checker': (self.crossystem_checker, {
                     'devsw_boot': '1',
                     'mainfw_type': 'developer',
                     'recoverysw_boot': '0',
                 }),
+                'userspace_action': self.faft_client.request_recovery_boot,
+                'firmware_action': (self.run_shutdown_process,
+                                    self.wait_longer_fw_screen_and_close_lid,
+                                    self.servo.lid_open,
+                                    self.wait_fw_screen_and_ctrl_d),
+            },
+            {   # Step 4, request recovery boot again. When the recovery
+                # insert screen shows, insert a corrupted USB and trigger
+                # a YUCK SCREEN. Then close lid to make DUT shutdown.
+                'state_checker': (self.crossystem_checker, {
+                    'devsw_boot': '1',
+                    'mainfw_type': 'developer',
+                    'recoverysw_boot': '0',
+                }),
+                'userspace_action': self.faft_client.request_recovery_boot,
                 'firmware_action': (self.run_shutdown_process,
                                     self.wait_yuck_screen_and_close_lid,
                                     self.servo.lid_open,
                                     self.wait_fw_screen_and_ctrl_d),
             },
-            {   # Step 4, enable normal mode and normal firmware.
+            {   # Step 5, switch back to normal mode.
                 'state_checker': (self.crossystem_checker, {
                     'devsw_boot': '1',
                     'mainfw_type': 'developer',
@@ -108,9 +122,9 @@
                 'userspace_action': self.enable_normal_mode_and_fw,
                 'reboot_action': None,
             },
-            {   # Step 5, turn on the recovery boot. Since a USB stick was
-                # inserted in step 3, a recovery remove screen is shown.
-                # Close lid to make DUT shutdown.
+            {   # Step 6, expected normal mode and request recovery boot.
+                # Because an USB stick is inserted, a RECOVERY REMOVE screen
+                # shows. Close lid to make DUT shutdown.
                 'state_checker': (self.crossystem_checker, {
                     'devsw_boot': '0',
                     'mainfw_type': 'normal',
@@ -118,10 +132,11 @@
                 }),
                 'userspace_action': self.faft_client.request_recovery_boot,
                 'firmware_action': (self.run_shutdown_process,
-                                    self.wait_fw_screen_and_close_lid,
-                                    self.servo.lid_open),
+                                    self.wait_longer_fw_screen_and_close_lid,
+                                    self.servo.lid_open,
+                                    None),
             },
-            {   # Step 6, done.
+            {   # Step 7, done.
                 'state_checker': (self.crossystem_checker, {
                     'devsw_boot': '0',
                     'mainfw_type': 'normal',