• 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 display lid close and open test using the Chameleon board."""
6
7import logging, time
8
9from autotest_lib.client.common_lib import error
10from autotest_lib.client.cros.chameleon import chameleon_port_finder
11from autotest_lib.client.cros.chameleon import chameleon_screen_test
12from autotest_lib.server import test
13from autotest_lib.server.cros.multimedia import remote_facade_factory
14
15class display_LidCloseOpen(test.test):
16    """External Display Lid Close/Open test. """
17    version = 1
18
19    # Time to check if device is suspended
20    TIMEOUT_SUSPEND_CHECK = 5
21    # Allowed timeout for the transition of suspend.
22    TIMEOUT_SUSPEND_TRANSITION = 30
23    # Allowed timeout for the transition of resume.
24    TIMEOUT_RESUME_TRANSITION = 60
25    # Time to allow for table video input
26    WAIT_TIME_STABLE_VIDEO_INPUT = 10
27    # Time to allow lid transition to take effect
28    WAIT_TIME_LID_TRANSITION = 5
29    # Time to allow display port plug transition to take effect
30    WAIT_TIME_PLUG_TRANSITION = 5
31
32
33    def close_lid(self):
34        """Close lid through servo"""
35        logging.info('CLOSING LID...')
36        self.host.servo.lid_close()
37        time.sleep(self.WAIT_TIME_LID_TRANSITION)
38
39
40    def open_lid(self):
41        """Open lid through servo"""
42        logging.info('OPENING LID...')
43        self.host.servo.lid_open()
44        time.sleep(self.WAIT_TIME_LID_TRANSITION)
45
46
47    def check_primary_display_on_internal_screen(self):
48        """Checks primary display is on onboard/internal screen"""
49        if not self.display_facade.is_display_primary(internal=True):
50            raise error.TestFail('Primary display is not on internal screen')
51
52
53    def check_primary_display_on_external_screen(self):
54        """Checks primary display is on external screen"""
55        if not self.display_facade.is_display_primary(internal=False):
56            raise error.TestFail('Primary display is not on external screen')
57
58
59    def check_mode(self):
60        """Checks the display mode is as expected"""
61        if self.display_facade.is_mirrored_enabled() is not self.test_mirrored:
62            raise error.TestFail('Display mode %s is not preserved!' %
63                                 ('mirrored' if self.test_mirrored
64                                     else 'extended'))
65
66
67    def check_docked(self):
68        """Checks DUT is docked"""
69        # Device does not suspend
70        if self.host.ping_wait_down(timeout=self.TIMEOUT_SUSPEND_TRANSITION):
71            raise error.TestFail('Device suspends when docked!')
72        # Verify Chameleon displays main screen
73        self.check_primary_display_on_external_screen()
74        logging.info('DUT IS DOCKED!')
75        return self.chameleon_port.wait_video_input_stable(
76            timeout=self.WAIT_TIME_STABLE_VIDEO_INPUT)
77
78
79    def check_still_suspended(self):
80        """Checks DUT is (still) suspended"""
81        if not self.host.ping_wait_down(timeout=self.TIMEOUT_SUSPEND_CHECK):
82            raise error.TestFail('Device does not stay suspended!')
83        logging.info('DUT STILL SUSPENDED')
84
85
86    def check_external_display(self):
87        """Display status check"""
88        # Check connector
89        if self.screen_test.check_external_display_connected(
90                self.connector_used, self.errors) is None:
91            # Check mode is same as beginning of the test
92            self.check_mode()
93            # Check test image
94            resolution = self.chameleon_port.get_resolution()
95            self.screen_test.test_screen_with_image(
96                    resolution, self.test_mirrored, self.errors)
97
98
99    def run_once(self, host, plug_status, test_mirrored=False):
100
101        # Check for chromebook type devices
102        if not host.get_board_type() == 'CHROMEBOOK':
103            raise error.TestNAError('DUT is not Chromebook. Test Skipped')
104        self.host = host
105        self.test_mirrored = test_mirrored
106        self.errors = list()
107
108        # Check the servo object
109        if self.host.servo is None:
110            raise error.TestError('Invalid servo object found on the host.')
111
112        factory = remote_facade_factory.RemoteFacadeFactory(host)
113        display_facade = factory.create_display_facade()
114        chameleon_board = host.chameleon
115
116        chameleon_board.reset()
117        finder = chameleon_port_finder.ChameleonVideoInputFinder(
118                chameleon_board, display_facade)
119        for chameleon_port in finder.iterate_all_ports():
120            self.run_test_on_port(chameleon_port, display_facade, plug_status)
121
122
123    def run_test_on_port(self, chameleon_port, display_facade, plug_status):
124        """Run the test on the given Chameleon port.
125
126        @param chameleon_port: a ChameleonPorts object.
127        @param display_facade: a display facade object.
128        @param plug_status: the plugged status before_close, after_close,
129           and before_open
130        """
131        self.chameleon_port = chameleon_port
132        self.display_facade = display_facade
133        self.screen_test = chameleon_screen_test.ChameleonScreenTest(
134                chameleon_port, display_facade, self.outputdir)
135
136        # Get connector type used (HDMI,DP,...)
137        self.connector_used = self.display_facade.get_external_connector_name()
138        # Set main display mode for the test
139        self.display_facade.set_mirrored(self.test_mirrored)
140
141        for (plugged_before_close,
142             plugged_after_close,
143             plugged_before_open) in plug_status:
144            logging.info('TEST CASE: %s > CLOSE_LID > %s > %s > OPEN_LID',
145                'PLUG' if plugged_before_close else 'UNPLUG',
146                'PLUG' if plugged_after_close else 'UNPLUG',
147                'PLUG' if plugged_before_open else 'UNPLUG')
148
149            is_suspended = False
150            boot_id = self.host.get_boot_id()
151
152            # Plug before close
153            self.chameleon_port.set_plug(plugged_before_close)
154            self.chameleon_port.wait_video_input_stable(
155                    timeout=self.WAIT_TIME_STABLE_VIDEO_INPUT)
156
157            # Close lid and check
158            self.close_lid()
159            if plugged_before_close:
160                self.check_docked()
161            else:
162                self.host.test_wait_for_sleep(self.TIMEOUT_SUSPEND_TRANSITION)
163                is_suspended = True
164
165            # Plug after close and check
166            if plugged_after_close is not plugged_before_close:
167                self.chameleon_port.set_plug(plugged_after_close)
168                self.chameleon_port.wait_video_input_stable(
169                        timeout=self.WAIT_TIME_STABLE_VIDEO_INPUT)
170                if not plugged_before_close:
171                    self.check_still_suspended()
172                else:
173                    self.host.test_wait_for_sleep(
174                        self.TIMEOUT_SUSPEND_TRANSITION)
175                    is_suspended = True
176
177            # Plug before open and check
178            if plugged_before_open is not plugged_after_close:
179                self.chameleon_port.set_plug(plugged_before_open)
180                self.chameleon_port.wait_video_input_stable(
181                        timeout=self.WAIT_TIME_STABLE_VIDEO_INPUT)
182                if not plugged_before_close or not plugged_after_close:
183                    self.check_still_suspended()
184                else:
185                    self.host.test_wait_for_sleep(
186                        self.TIMEOUT_SUSPEND_TRANSITION)
187                    is_suspended = True
188
189            # Open lid and check
190            self.open_lid()
191            if is_suspended:
192                self.host.test_wait_for_resume(boot_id,
193                                               self.TIMEOUT_RESUME_TRANSITION)
194                is_suspended = False
195
196            # Check internal screen switch to primary display
197            self.check_primary_display_on_internal_screen()
198
199            # Plug monitor if not plugged, such that we can test the screen.
200            if not plugged_before_open:
201                self.chameleon_port.set_plug(True)
202                self.chameleon_port.wait_video_input_stable(
203                        timeout=self.WAIT_TIME_STABLE_VIDEO_INPUT)
204
205            # Check status
206            self.check_external_display()
207
208            if self.errors:
209                raise error.TestFail('; '.join(set(self.errors)))
210