Home | History | Annotate | Download | only in desktopui_ScreenLocker
      1 # Copyright (c) 2013 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 import gobject
      6 import logging
      7 
      8 from autotest_lib.client.bin import test, utils
      9 from autotest_lib.client.common_lib import error
     10 from autotest_lib.client.common_lib.cros import chrome, session_manager
     11 from autotest_lib.client.cros import asan
     12 from autotest_lib.client.cros.input_playback import input_playback
     13 
     14 from datetime import datetime
     15 from dbus.mainloop.glib import DBusGMainLoop
     16 
     17 class desktopui_ScreenLocker(test.test):
     18     """This is a client side test that exercises the screenlocker."""
     19     version = 1
     20 
     21     _SCREEN_IS_LOCKED_TIMEOUT = 30
     22     # TODO(jdufault): Remove this timeout increase for asan bots once we figure
     23     # out what's taking so long to lock the screen. See crbug.com/452599.
     24     if asan.running_on_asan():
     25       _SCREEN_IS_LOCKED_TIMEOUT *= 2
     26 
     27     """Timeout for password authentication."""
     28     _AUTHENTICATION_TIMEOUT = 30
     29 
     30 
     31     def initialize(self):
     32         """Init method"""
     33         super(desktopui_ScreenLocker, self).initialize()
     34         DBusGMainLoop(set_as_default=True)
     35         self.player = input_playback.InputPlayback()
     36         self.player.emulate(input_type='keyboard')
     37         self.player.find_connected_inputs()
     38 
     39 
     40     def cleanup(self):
     41         """Test cleanup."""
     42         self.player.close()
     43 
     44 
     45     @property
     46     def screen_locked(self):
     47         """True if the screen is locked."""
     48         return self._chrome.login_status['isScreenLocked']
     49 
     50 
     51     @property
     52     def screen_ready_for_password(self):
     53         """True if the screen is ready for password."""
     54         return self._chrome.login_status['isReadyForPassword']
     55 
     56 
     57     def lock_screen(self, perf_values):
     58         """Lock the screen.
     59 
     60         @param perf_values: Performance data will be stored inside of this dict.
     61 
     62         @raises: error.TestFail when screen already locked.
     63         @raises: error.TestFail when screen not locked.
     64 
     65         """
     66         logging.debug('lock_screen')
     67         if self.screen_locked:
     68             raise error.TestFail('Screen already locked')
     69         signal_listener = session_manager.ScreenIsLockedSignalListener(
     70                 gobject.MainLoop())
     71         ext = self._chrome.autotest_ext
     72 
     73         start = datetime.now()
     74         ext.EvaluateJavaScript('chrome.autotestPrivate.lockScreen();')
     75         signal_listener.wait_for_signals(desc='Screen is locked.',
     76                                          timeout=self._SCREEN_IS_LOCKED_TIMEOUT)
     77         perf_values['lock_seconds'] = (datetime.now() - start).total_seconds()
     78 
     79         utils.poll_for_condition(
     80                 lambda: self.screen_locked,
     81                 exception=error.TestFail('Screen not locked'))
     82 
     83 
     84     def lock_screen_through_keyboard(self):
     85         """Lock the screen with keyboard(search+L) .
     86 
     87          @raises: error.TestFail when screen already locked.
     88          @raises: error.TestFail if screen not locked after using keyboard
     89                   shortcut.
     90 
     91          """
     92         logging.debug('Locking screen through the keyboard shortcut')
     93         if self.screen_locked:
     94             raise error.TestFail('Screen already locked')
     95         self.player.blocking_playback_of_default_file(
     96             input_type='keyboard', filename='keyboard_search+L')
     97         utils.poll_for_condition(
     98                 lambda: self.screen_locked,
     99                 exception=error.TestFail(
    100                         'Screen not locked after using keyboard shortcut'))
    101 
    102 
    103     def attempt_unlock_bad_password(self):
    104         """Attempt unlock with a bad password.
    105 
    106          @raises: error.TestFail when successfully unlock with bad password.
    107 
    108          """
    109         logging.debug('attempt_unlock_bad_password')
    110         self.player.blocking_playback_of_default_file(
    111                 input_type='keyboard', filename='keyboard_b+a+d+enter')
    112 
    113         # Wait for the authentication to complete.
    114         utils.poll_for_condition(
    115                 lambda: self.screen_ready_for_password,
    116                 exception=error.TestFail(
    117                         'Authentication is not completed after %d seconds',
    118                         self._AUTHENTICATION_TIMEOUT),
    119                 timeout=self._AUTHENTICATION_TIMEOUT)
    120         if not self.screen_locked:
    121             raise error.TestFail('Screen unlocked with bad password')
    122 
    123 
    124     def unlock_screen(self):
    125         """Unlock the screen with the right password. The correct password is
    126            the empty string.
    127            TODO(crbug.com/792251): Use non-empty password.
    128 
    129          @raises: error.TestFail if failed to unlock screen.
    130 
    131         """
    132         logging.debug('unlock_screen')
    133         self.player.blocking_playback_of_default_file(
    134                 input_type='keyboard', filename='keyboard_enter')
    135         utils.poll_for_condition(
    136                 lambda: not self.screen_locked,
    137                 exception=error.TestFail('Failed to unlock screen'),
    138                 timeout=self._AUTHENTICATION_TIMEOUT)
    139 
    140 
    141     def run_once(self):
    142         """
    143         This test locks the screen, tries to unlock with a bad password,
    144         then unlocks with the right password.
    145 
    146         """
    147         with chrome.Chrome(autotest_ext=True) as self._chrome:
    148             try:
    149                 # Give performance data some initial state that will be reported
    150                 # if the test times out.
    151                 perf_values = { 'lock_seconds': self._SCREEN_IS_LOCKED_TIMEOUT }
    152 
    153                 self.lock_screen(perf_values)
    154                 self.attempt_unlock_bad_password()
    155                 self.unlock_screen()
    156                 self.lock_screen_through_keyboard()
    157                 self.unlock_screen()
    158             finally:
    159                 self.output_perf_value(
    160                         description='time_to_lock_screen',
    161                         value=perf_values['lock_seconds'],
    162                         units='s',
    163                         higher_is_better=False)
    164