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 5import gobject 6import logging 7 8from autotest_lib.client.bin import test, utils 9from autotest_lib.client.common_lib import error 10from autotest_lib.client.common_lib.cros import chrome, session_manager 11from autotest_lib.client.cros import asan 12from autotest_lib.client.cros.input_playback import input_playback 13 14from datetime import datetime 15from dbus.mainloop.glib import DBusGMainLoop 16 17class 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