• 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']
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