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