1# Copyright 2014 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""This is a server side resolution display test using the Chameleon board.""" 6 7import logging 8import os 9import time 10 11from autotest_lib.client.bin import utils 12from autotest_lib.client.common_lib import error 13from autotest_lib.client.cros.chameleon import chameleon_port_finder 14from autotest_lib.client.cros.chameleon import chameleon_screen_test 15from autotest_lib.client.cros.chameleon import edid 16from autotest_lib.server import test 17from autotest_lib.server.cros.multimedia import remote_facade_factory 18 19 20class display_Resolution(test.test): 21 """Server side external display test. 22 23 This test talks to a Chameleon board and a DUT to set up, run, and verify 24 external display function of the DUT. 25 """ 26 version = 1 27 28 # Allowed timeout for reboot. 29 REBOOT_TIMEOUT = 30 30 # Time to allow lid transition to take effect 31 WAIT_TIME_LID_TRANSITION = 5 32 33 DEFAULT_RESOLUTION_LIST = [ 34 ('EDIDv1', 1280, 800), 35 ('EDIDv1', 1440, 900), 36 ('EDIDv1', 1600, 900), 37 ('EDIDv1', 1680, 1050), 38 ('EDIDv2', 1280, 720), 39 ('EDIDv2', 1920, 1080), 40 ] 41 # These boards are unable to work with servo - crosbug.com/p/27591. 42 INCOMPATIBLE_SERVO_BOARDS = ['daisy', 'falco'] 43 44 def run_once(self, host, test_mirrored=False, test_suspend_resume=False, 45 test_reboot=False, test_lid_close_open=False, 46 resolution_list=None): 47 48 # Check the servo object. 49 if test_lid_close_open and host.servo is None: 50 raise error.TestError('Invalid servo object found on the host.') 51 if test_lid_close_open and not host.get_board_type() == 'CHROMEBOOK': 52 raise error.TestNAError('DUT is not Chromebook. Test Skipped') 53 if test_mirrored and not host.get_board_type() == 'CHROMEBOOK': 54 raise error.TestNAError('DUT is not Chromebook. Test Skipped') 55 56 # Check for incompatible with servo chromebooks. 57 board_name = host.get_board().split(':')[1] 58 if board_name in self.INCOMPATIBLE_SERVO_BOARDS: 59 raise error.TestNAError( 60 'DUT is incompatible with servo. Skipping test.') 61 62 factory = remote_facade_factory.RemoteFacadeFactory(host) 63 display_facade = factory.create_display_facade() 64 chameleon_board = host.chameleon 65 66 chameleon_board.setup_and_reset(self.outputdir) 67 finder = chameleon_port_finder.ChameleonVideoInputFinder( 68 chameleon_board, display_facade) 69 70 errors = [] 71 if resolution_list is None: 72 resolution_list = self.DEFAULT_RESOLUTION_LIST 73 chameleon_supported = True 74 for chameleon_port in finder.iterate_all_ports(): 75 screen_test = chameleon_screen_test.ChameleonScreenTest( 76 chameleon_port, display_facade, self.outputdir) 77 chameleon_port_name = chameleon_port.get_connector_type() 78 logging.info('Detected %s chameleon port.', chameleon_port_name) 79 for label, width, height in resolution_list: 80 test_resolution = (width, height) 81 test_name = "%s_%dx%d" % ((label,) + test_resolution) 82 83 # The chameleon DP RX doesn't support 4K resolution. 84 # The max supported resolution is 2560x1600. 85 # See crbug/585900 86 if (chameleon_port_name.startswith('DP') and 87 test_resolution > (2560,1600)): 88 chameleon_supported = False 89 90 if not edid.is_edid_supported(host, width, height): 91 logging.info('Skip unsupported EDID: %s', test_name) 92 continue 93 94 if test_lid_close_open: 95 logging.info('Close lid...') 96 host.servo.lid_close() 97 time.sleep(self.WAIT_TIME_LID_TRANSITION) 98 99 if test_reboot: 100 logging.info('Reboot...') 101 boot_id = host.get_boot_id() 102 host.reboot(wait=False) 103 host.test_wait_for_shutdown(self.REBOOT_TIMEOUT) 104 105 path = os.path.join(self.bindir, 'test_data', 'edids', 106 test_name) 107 logging.info('Use EDID: %s', test_name) 108 with chameleon_port.use_edid_file(path): 109 if test_lid_close_open: 110 logging.info('Open lid...') 111 host.servo.lid_open() 112 time.sleep(self.WAIT_TIME_LID_TRANSITION) 113 114 if test_reboot: 115 host.test_wait_for_boot(boot_id) 116 117 utils.wait_for_value_changed( 118 display_facade.get_external_connector_name, 119 old_value=False) 120 121 logging.info('Set mirrored: %s', test_mirrored) 122 display_facade.set_mirrored(test_mirrored) 123 if test_suspend_resume: 124 if test_mirrored: 125 # magic sleep to wake up nyan_big in mirrored mode 126 # TODO: find root cause 127 time.sleep(6) 128 logging.info('Going to suspend...') 129 display_facade.suspend_resume() 130 logging.info('Resumed back') 131 132 screen_test.test_screen_with_image(test_resolution, 133 test_mirrored, errors, chameleon_supported) 134 135 if errors: 136 raise error.TestFail('; '.join(set(errors))) 137