169 lines
6.9 KiB
Python
169 lines
6.9 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 server side resolution display test using the Chameleon board."""
|
|
|
|
import logging
|
|
import os
|
|
import time
|
|
|
|
from autotest_lib.client.bin import utils
|
|
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.client.cros.chameleon import edid
|
|
from autotest_lib.server import test
|
|
from autotest_lib.server.cros.multimedia import remote_facade_factory
|
|
|
|
|
|
class display_Resolution(test.test):
|
|
"""Server side external display test.
|
|
|
|
This test talks to a Chameleon board and a DUT to set up, run, and verify
|
|
external display function of the DUT.
|
|
"""
|
|
version = 1
|
|
|
|
# Allowed timeout for reboot.
|
|
REBOOT_TIMEOUT = 30
|
|
# Time to allow lid transition to take effect
|
|
WAIT_TIME_LID_TRANSITION = 5
|
|
|
|
DEFAULT_RESOLUTION_LIST = [
|
|
('EDIDv1', 1280, 800),
|
|
('EDIDv1', 1440, 900),
|
|
('EDIDv1', 1600, 900),
|
|
('EDIDv1', 1680, 1050),
|
|
('EDIDv2', 1280, 720),
|
|
('EDIDv2', 1920, 1080),
|
|
]
|
|
# These boards are unable to work with servo - crosbug.com/p/27591.
|
|
INCOMPATIBLE_SERVO_BOARDS = ['daisy', 'falco']
|
|
|
|
# These boards and EDID resolutions are not compatible -crbug.com/905415
|
|
INCOMPATIBLE_EDID_RESOLUTION_LIST = [
|
|
('EDIDv1', 1280, 800),
|
|
('EDIDv1', 1600, 900),
|
|
]
|
|
INCOMPATIBLE_EDID_BOARDS = ['coral', 'eve', 'grunt', 'nami', 'rammus',
|
|
'zork']
|
|
|
|
def run_once(self, host, test_mirrored=False, test_suspend_resume=False,
|
|
test_reboot=False, test_lid_close_open=False,
|
|
resolution_list=None):
|
|
"""Check conditions, do setup and run test.
|
|
"""
|
|
|
|
# Check the servo object.
|
|
if test_lid_close_open and host.servo is None:
|
|
raise error.TestError('Invalid servo object found on the host.')
|
|
if test_lid_close_open and not host.get_board_type() == 'CHROMEBOOK':
|
|
raise error.TestNAError('DUT is not Chromebook. Test Skipped')
|
|
if test_mirrored and 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
|
|
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)
|
|
|
|
errors = []
|
|
if resolution_list is None:
|
|
resolution_list = self.DEFAULT_RESOLUTION_LIST
|
|
|
|
# Remove board specific incompatible EDIDs.
|
|
if board_name.replace('-kernelnext', '') in \
|
|
self.INCOMPATIBLE_EDID_BOARDS:
|
|
for edid_value in self.INCOMPATIBLE_EDID_RESOLUTION_LIST:
|
|
if edid_value in resolution_list:
|
|
resolution_list.remove(edid_value)
|
|
|
|
chameleon_supported = True
|
|
for chameleon_port in finder.iterate_all_ports():
|
|
screen_test = chameleon_screen_test.ChameleonScreenTest(
|
|
host, chameleon_port, display_facade, self.outputdir)
|
|
chameleon_port_name = chameleon_port.get_connector_type()
|
|
logging.info('Detected %s chameleon port.', chameleon_port_name)
|
|
for label, width, height in resolution_list:
|
|
test_resolution = (width, height)
|
|
test_name = "%s_%dx%d" % ((label,) + test_resolution)
|
|
|
|
# The chameleon DP RX doesn't support 4K resolution.
|
|
# The max supported resolution is 2560x1600.
|
|
# See crbug/585900
|
|
if (chameleon_port_name.startswith('DP') and
|
|
test_resolution > (2560,1600)):
|
|
chameleon_supported = False
|
|
|
|
if not edid.is_edid_supported(host, width, height):
|
|
logging.info('Skip unsupported EDID: %s', test_name)
|
|
continue
|
|
|
|
if test_lid_close_open:
|
|
logging.info('Close lid...')
|
|
host.servo.lid_close()
|
|
time.sleep(self.WAIT_TIME_LID_TRANSITION)
|
|
|
|
if test_reboot:
|
|
# Unplug the monitor explicitly. Otherwise, the following
|
|
# use_edid_file() call would expect a valid video signal,
|
|
# which is not true during reboot.
|
|
chameleon_port.unplug()
|
|
logging.info('Reboot...')
|
|
boot_id = host.get_boot_id()
|
|
host.reboot(wait=False)
|
|
host.test_wait_for_shutdown(self.REBOOT_TIMEOUT)
|
|
|
|
path = os.path.join(self.bindir, 'test_data', 'edids',
|
|
test_name)
|
|
logging.info('Use EDID: %s', test_name)
|
|
with chameleon_port.use_edid_file(path):
|
|
if test_lid_close_open:
|
|
logging.info('Open lid...')
|
|
host.servo.lid_open()
|
|
time.sleep(self.WAIT_TIME_LID_TRANSITION)
|
|
|
|
if test_reboot:
|
|
host.test_wait_for_boot(boot_id)
|
|
chameleon_port.plug()
|
|
|
|
utils.wait_for_value_changed(
|
|
display_facade.get_external_connector_name,
|
|
old_value=False)
|
|
|
|
logging.info('Set mirrored: %s', test_mirrored)
|
|
display_facade.set_mirrored(test_mirrored)
|
|
if test_suspend_resume:
|
|
if test_mirrored:
|
|
# magic sleep to wake up nyan_big in mirrored mode
|
|
# TODO: find root cause
|
|
time.sleep(6)
|
|
logging.info('Going to suspend...')
|
|
display_facade.suspend_resume()
|
|
logging.info('Resumed back')
|
|
|
|
screen_test.test_screen_with_image(test_resolution,
|
|
test_mirrored, errors, chameleon_supported)
|
|
|
|
if errors:
|
|
raise error.TestFail('; '.join(set(errors)))
|
|
|
|
def cleanup(self):
|
|
"""Test cleanup"""
|
|
# Keep device in lid open sate.
|
|
if self.host.servo:
|
|
logging.info('Open lid...')
|
|
self.host.servo.lid_open()
|
|
time.sleep(self.WAIT_TIME_LID_TRANSITION)
|