• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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