224 lines
8.8 KiB
Python
224 lines
8.8 KiB
Python
# Copyright 2014 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.
|
|
|
|
"""This is a display lid close and open test using the Chameleon board."""
|
|
|
|
import logging, time
|
|
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.client.cros.chameleon import chameleon_port_finder
|
|
from autotest_lib.client.cros.chameleon import chameleon_screen_test
|
|
from autotest_lib.server import test
|
|
from autotest_lib.server.cros.multimedia import remote_facade_factory
|
|
|
|
class display_LidCloseOpen(test.test):
|
|
"""External Display Lid Close/Open test. """
|
|
version = 1
|
|
|
|
# Time to check if device is suspended
|
|
TIMEOUT_SUSPEND_CHECK = 5
|
|
# Allowed timeout for the transition of suspend.
|
|
TIMEOUT_SUSPEND_TRANSITION = 30
|
|
# Allowed timeout for the transition of resume.
|
|
TIMEOUT_RESUME_TRANSITION = 60
|
|
# Time to allow for table video input
|
|
WAIT_TIME_STABLE_VIDEO_INPUT = 10
|
|
# Time to allow lid transition to take effect
|
|
WAIT_TIME_LID_TRANSITION = 5
|
|
# Time to allow display port plug transition to take effect
|
|
WAIT_TIME_PLUG_TRANSITION = 5
|
|
# Some boards do not play well with servo - crosbug.com/p/27591
|
|
INCOMPATIBLE_SERVO_BOARDS = ['daisy', 'falco', 'auron_paine']
|
|
|
|
|
|
def close_lid(self):
|
|
"""Close lid through servo"""
|
|
logging.info('CLOSING LID...')
|
|
self.host.servo.lid_close()
|
|
time.sleep(self.WAIT_TIME_LID_TRANSITION)
|
|
|
|
|
|
def open_lid(self):
|
|
"""Open lid through servo"""
|
|
logging.info('OPENING LID...')
|
|
self.host.servo.lid_open()
|
|
time.sleep(self.WAIT_TIME_LID_TRANSITION)
|
|
|
|
|
|
def check_primary_display_on_internal_screen(self):
|
|
"""Checks primary display is on onboard/internal screen"""
|
|
if not self.display_facade.is_display_primary(internal=True):
|
|
raise error.TestFail('Primary display is not on internal screen')
|
|
|
|
|
|
def check_primary_display_on_external_screen(self):
|
|
"""Checks primary display is on external screen"""
|
|
if not self.display_facade.is_display_primary(internal=False):
|
|
raise error.TestFail('Primary display is not on external screen')
|
|
|
|
|
|
def check_mode(self):
|
|
"""Checks the display mode is as expected"""
|
|
if self.display_facade.is_mirrored_enabled() is not self.test_mirrored:
|
|
raise error.TestFail('Display mode %s is not preserved!' %
|
|
('mirrored' if self.test_mirrored
|
|
else 'extended'))
|
|
|
|
|
|
def check_docked(self):
|
|
"""Checks DUT is docked"""
|
|
# Device does not suspend
|
|
if self.host.ping_wait_down(timeout=self.TIMEOUT_SUSPEND_TRANSITION):
|
|
raise error.TestFail('Device suspends when docked!')
|
|
# Verify Chameleon displays main screen
|
|
self.check_primary_display_on_external_screen()
|
|
logging.info('DUT IS DOCKED!')
|
|
return self.chameleon_port.wait_video_input_stable(
|
|
timeout=self.WAIT_TIME_STABLE_VIDEO_INPUT)
|
|
|
|
|
|
def check_still_suspended(self):
|
|
"""Checks DUT is (still) suspended"""
|
|
if not self.host.ping_wait_down(timeout=self.TIMEOUT_SUSPEND_CHECK):
|
|
raise error.TestFail('Device does not stay suspended!')
|
|
logging.info('DUT STILL SUSPENDED')
|
|
|
|
|
|
def check_external_display(self):
|
|
"""Display status check"""
|
|
# Check connector
|
|
if self.screen_test.check_external_display_connected(
|
|
self.connector_used, self.errors) is None:
|
|
# Check mode is same as beginning of the test
|
|
self.check_mode()
|
|
# Check test image
|
|
resolution = self.chameleon_port.get_resolution()
|
|
self.screen_test.test_screen_with_image(
|
|
resolution, self.test_mirrored, self.errors)
|
|
|
|
|
|
def run_once(self, host, plug_status, test_mirrored=False):
|
|
|
|
# Check for chromebook type devices
|
|
if not host.get_board_type() == 'CHROMEBOOK':
|
|
raise error.TestNAError('DUT is not Chromebook. Test Skipped')
|
|
|
|
# Check for incompatible with servo chromebooks
|
|
board_name = host.get_board().split(':')[1]
|
|
if board_name in self.INCOMPATIBLE_SERVO_BOARDS:
|
|
raise error.TestNAError(
|
|
'DUT is incompatible with servo. Skipping test.')
|
|
|
|
self.host = host
|
|
self.test_mirrored = test_mirrored
|
|
self.errors = list()
|
|
|
|
# Check the servo object
|
|
if self.host.servo is None:
|
|
raise error.TestError('Invalid servo object found on the host.')
|
|
|
|
factory = remote_facade_factory.RemoteFacadeFactory(host)
|
|
display_facade = factory.create_display_facade()
|
|
chameleon_board = host.chameleon
|
|
|
|
chameleon_board.setup_and_reset(self.outputdir)
|
|
finder = chameleon_port_finder.ChameleonVideoInputFinder(
|
|
chameleon_board, display_facade)
|
|
for chameleon_port in finder.iterate_all_ports():
|
|
self.run_test_on_port(chameleon_port, display_facade, plug_status)
|
|
|
|
|
|
def run_test_on_port(self, chameleon_port, display_facade, plug_status):
|
|
"""Run the test on the given Chameleon port.
|
|
|
|
@param chameleon_port: a ChameleonPorts object.
|
|
@param display_facade: a display facade object.
|
|
@param plug_status: the plugged status before_close, after_close,
|
|
and before_open
|
|
"""
|
|
self.chameleon_port = chameleon_port
|
|
self.display_facade = display_facade
|
|
self.screen_test = chameleon_screen_test.ChameleonScreenTest(
|
|
self.host, chameleon_port, display_facade, self.outputdir)
|
|
|
|
# Get connector type used (HDMI,DP,...)
|
|
self.connector_used = self.display_facade.get_external_connector_name()
|
|
# Set main display mode for the test
|
|
self.display_facade.set_mirrored(self.test_mirrored)
|
|
|
|
for (plugged_before_close,
|
|
plugged_after_close,
|
|
plugged_before_open) in plug_status:
|
|
logging.info('TEST CASE: %s > CLOSE_LID > %s > %s > OPEN_LID',
|
|
'PLUG' if plugged_before_close else 'UNPLUG',
|
|
'PLUG' if plugged_after_close else 'UNPLUG',
|
|
'PLUG' if plugged_before_open else 'UNPLUG')
|
|
|
|
is_suspended = False
|
|
boot_id = self.host.get_boot_id()
|
|
|
|
# Plug before close
|
|
self.chameleon_port.set_plug(plugged_before_close)
|
|
self.chameleon_port.wait_video_input_stable(
|
|
timeout=self.WAIT_TIME_STABLE_VIDEO_INPUT)
|
|
|
|
# Close lid and check
|
|
self.close_lid()
|
|
if plugged_before_close:
|
|
self.check_docked()
|
|
else:
|
|
self.host.test_wait_for_sleep(self.TIMEOUT_SUSPEND_TRANSITION)
|
|
is_suspended = True
|
|
|
|
# Plug after close and check
|
|
if plugged_after_close is not plugged_before_close:
|
|
self.chameleon_port.set_plug(plugged_after_close)
|
|
self.chameleon_port.wait_video_input_stable(
|
|
timeout=self.WAIT_TIME_STABLE_VIDEO_INPUT)
|
|
if not plugged_before_close:
|
|
self.check_still_suspended()
|
|
else:
|
|
self.host.test_wait_for_sleep(
|
|
self.TIMEOUT_SUSPEND_TRANSITION)
|
|
is_suspended = True
|
|
|
|
# Plug before open and check
|
|
if plugged_before_open is not plugged_after_close:
|
|
self.chameleon_port.set_plug(plugged_before_open)
|
|
self.chameleon_port.wait_video_input_stable(
|
|
timeout=self.WAIT_TIME_STABLE_VIDEO_INPUT)
|
|
if not plugged_before_close or not plugged_after_close:
|
|
self.check_still_suspended()
|
|
else:
|
|
self.host.test_wait_for_sleep(
|
|
self.TIMEOUT_SUSPEND_TRANSITION)
|
|
is_suspended = True
|
|
|
|
# Open lid and check
|
|
self.open_lid()
|
|
if is_suspended:
|
|
self.host.test_wait_for_resume(boot_id,
|
|
self.TIMEOUT_RESUME_TRANSITION)
|
|
is_suspended = False
|
|
|
|
# Check internal screen switch to primary display
|
|
self.check_primary_display_on_internal_screen()
|
|
|
|
# Plug monitor if not plugged, such that we can test the screen.
|
|
if not plugged_before_open:
|
|
self.chameleon_port.set_plug(True)
|
|
self.chameleon_port.wait_video_input_stable(
|
|
timeout=self.WAIT_TIME_STABLE_VIDEO_INPUT)
|
|
|
|
# Check status
|
|
self.check_external_display()
|
|
|
|
if self.errors:
|
|
raise error.TestFail('; '.join(set(self.errors)))
|
|
|
|
def cleanup(self):
|
|
"""Test cleanup"""
|
|
# Keep device in lid open sate.
|
|
self.open_lid()
|