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 # These boards and EDID resolutions are not compatible -crbug.com/905415 45 INCOMPATIBLE_EDID_RESOLUTION_LIST = [ 46 ('EDIDv1', 1280, 800), 47 ('EDIDv1', 1600, 900), 48 ] 49 INCOMPATIBLE_EDID_BOARDS = [ 'coral', 'eve', 'grunt', 'nami'] 50 51 def run_once(self, host, test_mirrored=False, test_suspend_resume=False, 52 test_reboot=False, test_lid_close_open=False, 53 resolution_list=None): 54 55 # Check the servo object. 56 if test_lid_close_open and host.servo is None: 57 raise error.TestError('Invalid servo object found on the host.') 58 if test_lid_close_open and not host.get_board_type() == 'CHROMEBOOK': 59 raise error.TestNAError('DUT is not Chromebook. Test Skipped') 60 if test_mirrored and not host.get_board_type() == 'CHROMEBOOK': 61 raise error.TestNAError('DUT is not Chromebook. Test Skipped') 62 63 # Check for incompatible with servo chromebooks. 64 board_name = host.get_board().split(':')[1] 65 if board_name in self.INCOMPATIBLE_SERVO_BOARDS: 66 raise error.TestNAError( 67 'DUT is incompatible with servo. Skipping test.') 68 69 self.host = host 70 factory = remote_facade_factory.RemoteFacadeFactory(host) 71 display_facade = factory.create_display_facade() 72 chameleon_board = host.chameleon 73 74 chameleon_board.setup_and_reset(self.outputdir) 75 finder = chameleon_port_finder.ChameleonVideoInputFinder( 76 chameleon_board, display_facade) 77 78 errors = [] 79 if resolution_list is None: 80 resolution_list = self.DEFAULT_RESOLUTION_LIST 81 82 # Remove board specific incompatible EDIDs. 83 if board_name in self.INCOMPATIBLE_EDID_BOARDS: 84 for edid_value in self.INCOMPATIBLE_EDID_RESOLUTION_LIST: 85 if edid_value in resolution_list: 86 resolution_list.remove(edid_value) 87 88 chameleon_supported = True 89 for chameleon_port in finder.iterate_all_ports(): 90 screen_test = chameleon_screen_test.ChameleonScreenTest( 91 host, chameleon_port, display_facade, self.outputdir) 92 chameleon_port_name = chameleon_port.get_connector_type() 93 logging.info('Detected %s chameleon port.', chameleon_port_name) 94 for label, width, height in resolution_list: 95 test_resolution = (width, height) 96 test_name = "%s_%dx%d" % ((label,) + test_resolution) 97 98 # The chameleon DP RX doesn't support 4K resolution. 99 # The max supported resolution is 2560x1600. 100 # See crbug/585900 101 if (chameleon_port_name.startswith('DP') and 102 test_resolution > (2560,1600)): 103 chameleon_supported = False 104 105 if not edid.is_edid_supported(host, width, height): 106 logging.info('Skip unsupported EDID: %s', test_name) 107 continue 108 109 if test_lid_close_open: 110 logging.info('Close lid...') 111 host.servo.lid_close() 112 time.sleep(self.WAIT_TIME_LID_TRANSITION) 113 114 if test_reboot: 115 # Unplug the monitor explicitly. Otherwise, the following 116 # use_edid_file() call would expect a valid video signal, 117 # which is not true during reboot. 118 chameleon_port.unplug() 119 logging.info('Reboot...') 120 boot_id = host.get_boot_id() 121 host.reboot(wait=False) 122 host.test_wait_for_shutdown(self.REBOOT_TIMEOUT) 123 124 path = os.path.join(self.bindir, 'test_data', 'edids', 125 test_name) 126 logging.info('Use EDID: %s', test_name) 127 with chameleon_port.use_edid_file(path): 128 if test_lid_close_open: 129 logging.info('Open lid...') 130 host.servo.lid_open() 131 time.sleep(self.WAIT_TIME_LID_TRANSITION) 132 133 if test_reboot: 134 host.test_wait_for_boot(boot_id) 135 chameleon_port.plug() 136 137 utils.wait_for_value_changed( 138 display_facade.get_external_connector_name, 139 old_value=False) 140 141 logging.info('Set mirrored: %s', test_mirrored) 142 display_facade.set_mirrored(test_mirrored) 143 if test_suspend_resume: 144 if test_mirrored: 145 # magic sleep to wake up nyan_big in mirrored mode 146 # TODO: find root cause 147 time.sleep(6) 148 logging.info('Going to suspend...') 149 display_facade.suspend_resume() 150 logging.info('Resumed back') 151 152 screen_test.test_screen_with_image(test_resolution, 153 test_mirrored, errors, chameleon_supported) 154 155 if errors: 156 raise error.TestFail('; '.join(set(errors))) 157 158 def cleanup(self): 159 """Test cleanup""" 160 # Keep device in lid open sate. 161 if self.host.servo: 162 logging.info('Open lid...') 163 self.host.servo.lid_open() 164 time.sleep(self.WAIT_TIME_LID_TRANSITION) 165