# 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)