faft: Implement Jetstream ModeSwitcher logic
This change adds the Jetstream ModeSwitcher implementation and
uses the new jetstream FAFT config as parent.
BUG=chrome-os-partner:16231,chrome-os-partner:39744
TEST=Ran suite:faft_lv1 and suite:faft_lv2 on Whirlwind. Some tests
failed and will be fixed by some future CLs.
Change-Id: I23c71ba86889a132cb54c7be169b0c9010880052
Reviewed-on: https://chromium-review.googlesource.com/272432
Tested-by: Tom Tam <waihong@google.com>
Reviewed-by: Yusuf Mohsinally <mohsinally@chromium.org>
Commit-Queue: Tom Tam <waihong@google.com>
diff --git a/server/cros/faft/config/jetstream.py b/server/cros/faft/config/jetstream.py
new file mode 100644
index 0000000..33599c2
--- /dev/null
+++ b/server/cros/faft/config/jetstream.py
@@ -0,0 +1,17 @@
+# Copyright 2015 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""FAFT configuration overrides for JetStream."""
+
+
+class Values(object):
+ """FAFT config values for JetStream."""
+
+ mode_switcher_type = 'jetstream_switcher'
+ fw_bypasser_type = 'jetstream_bypasser'
+
+ has_lid = False
+ has_keyboard = False
+ keyboard_dev = False
+ rec_button_dev_switch = True
diff --git a/server/cros/faft/config/storm.py b/server/cros/faft/config/storm.py
index bee346c..e97c5fb 100644
--- a/server/cros/faft/config/storm.py
+++ b/server/cros/faft/config/storm.py
@@ -4,10 +4,9 @@
"""FAFT configuration overrides for Storm."""
+from autotest_lib.server.cros.faft.config import jetstream
-class Values(object):
- """FAFT config values for Storm."""
- has_lid = False
- has_keyboard = False
- keyboard_dev = False
- rec_button_dev_switch = True
+
+class Values(jetstream.Values):
+ """Inherit overrides from Jetstream."""
+ pass
diff --git a/server/cros/faft/config/whirlwind.py b/server/cros/faft/config/whirlwind.py
new file mode 100644
index 0000000..85f7744
--- /dev/null
+++ b/server/cros/faft/config/whirlwind.py
@@ -0,0 +1,12 @@
+# Copyright 2015 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""FAFT configuration overrides for Whirlwind."""
+
+from autotest_lib.server.cros.faft.config import jetstream
+
+
+class Values(jetstream.Values):
+ """Inherit overrides from Jetstream."""
+ pass
diff --git a/server/cros/faft/utils/mode_switcher.py b/server/cros/faft/utils/mode_switcher.py
index e1dfd8c..68015da 100644
--- a/server/cros/faft/utils/mode_switcher.py
+++ b/server/cros/faft/utils/mode_switcher.py
@@ -102,6 +102,52 @@
self.servo.enter_key()
+class _JetstreamBypasser(_BaseFwBypasser):
+ """Controls bypass logic of Jetstream devices."""
+
+ def bypass_dev_mode(self):
+ """Bypass the dev mode firmware logic to boot internal image."""
+ # Jetstream does nothing to bypass.
+ pass
+
+
+ def bypass_dev_boot_usb(self):
+ """Bypass the dev mode firmware logic to boot USB."""
+ # TODO: Confirm if it is a proper way to trigger dev boot USB.
+ # We can't verify it this time due to a bug that always boots into
+ # USB on dev mode.
+ self.servo.enable_development_mode()
+ self.servo.switch_usbkey('dut')
+ time.sleep(self.faft_config.firmware_screen)
+ self.servo.toggle_development_switch()
+
+
+ def bypass_rec_mode(self):
+ """Bypass the rec mode firmware logic to boot USB."""
+ self.servo.switch_usbkey('host')
+ time.sleep(self.faft_config.usb_plug)
+ self.servo.switch_usbkey('dut')
+
+
+ def trigger_dev_to_rec(self):
+ """Trigger to the rec mode from the dev screen."""
+ # Jetstream does not have this triggering logic.
+ raise NotImplementedError
+
+
+ def trigger_rec_to_dev(self):
+ """Trigger to the dev mode from the rec screen."""
+ self.servo.disable_development_mode()
+ time.sleep(self.faft_config.firmware_screen)
+ self.servo.toggle_development_switch()
+
+
+ def trigger_dev_to_normal(self):
+ """Trigger to the normal mode from the dev screen."""
+ # Jetstream does not have this triggering logic.
+ raise NotImplementedError
+
+
def _create_fw_bypasser(servo, faft_config):
"""Creates a proper firmware bypasser.
@@ -113,6 +159,9 @@
if bypasser_type == 'ctrl_d_bypasser':
logging.info('Create a CtrlDBypasser')
return _CtrlDBypasser(servo, faft_config)
+ if bypasser_type == 'jetstream_bypasser':
+ logging.info('Create a JetstreamBypasser')
+ return _JetstreamBypasser(servo, faft_config)
else:
raise NotImplementedError('Not supported fw_bypasser_type: %s',
bypasser_type)
@@ -357,6 +406,26 @@
self.bypasser.trigger_dev_to_normal()
+class _JetstreamSwitcher(_BaseModeSwitcher):
+ """Class that switches firmware mode in Jetstream devices."""
+
+ def _enable_dev_mode_and_reboot(self):
+ """Switch to developer mode and reboot."""
+ logging.info("Enabling Jetstream developer mode")
+ self._enable_rec_mode_and_reboot(usb_state='host')
+ self.faft_framework.wait_for_client_offline()
+ self.bypasser.trigger_rec_to_dev()
+
+
+ def _enable_normal_mode_and_reboot(self):
+ """Switch to normal mode and reboot."""
+ logging.info("Disabling Jetstream developer mode")
+ self.servo.disable_development_mode()
+ self._enable_rec_mode_and_reboot(usb_state='host')
+ time.sleep(self.faft_config.firmware_screen)
+ self._disable_rec_mode_and_reboot(usb_state='host')
+
+
def create_mode_switcher(faft_framework):
"""Creates a proper mode switcher.
@@ -369,6 +438,9 @@
elif switcher_type == 'keyboard_dev_switcher':
logging.info('Create a KeyboardDevSwitcher')
return _KeyboardDevSwitcher(faft_framework)
+ elif switcher_type == 'jetstream_switcher':
+ logging.info('Create a JetstreamSwitcher')
+ return _JetstreamSwitcher(faft_framework)
else:
raise NotImplementedError('Not supported mode_switcher_type: %s',
switcher_type)
diff --git a/server/cros/servo/servo.py b/server/cros/servo/servo.py
index e0dd832..1b3d87f 100644
--- a/server/cros/servo/servo.py
+++ b/server/cros/servo/servo.py
@@ -146,6 +146,9 @@
# Time to toggle recovery switch on and off.
REC_TOGGLE_DELAY = 0.1
+ # Time to toggle development switch on and off.
+ DEV_TOGGLE_DELAY = 0.1
+
# Time between an usb disk plugged-in and detected in the system.
USB_DETECTION_DELAY = 10
# Time to keep USB power off before and after USB mux direction is changed
@@ -362,6 +365,13 @@
self.set('rec_mode', 'off')
+ def toggle_development_switch(self):
+ """Toggle development switch on and off."""
+ self.enable_development_mode()
+ time.sleep(self.DEV_TOGGLE_DELAY)
+ self.disable_development_mode()
+
+
def enable_development_mode(self):
"""Enable development mode on device."""
self.set('dev_mode', 'on')