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