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