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 6from datetime import datetime 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 14import gobject 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 28 def initialize(self): 29 super(desktopui_ScreenLocker, self).initialize() 30 DBusGMainLoop(set_as_default=True) 31 self.player = input_playback.InputPlayback() 32 self.player.emulate(input_type='keyboard') 33 self.player.find_connected_inputs() 34 35 36 def cleanup(self): 37 """Test cleanup.""" 38 self.player.close() 39 40 41 @property 42 def screen_locked(self): 43 """True if the screen is locked.""" 44 return self._chrome.login_status['isScreenLocked'] 45 46 47 @property 48 def screenlocker_visible(self): 49 """True if the screenlocker screen is visible.""" 50 oobe = self._chrome.browser.oobe 51 return (oobe and 52 oobe.EvaluateJavaScript( 53 "(typeof Oobe == 'function') && " 54 "(typeof Oobe.authenticateForTesting == 'function') && " 55 "($('account-picker') != null)")) 56 57 @property 58 def error_bubble_visible(self): 59 """True if the error bubble for bad password is visible.""" 60 return self._chrome.browser.oobe.EvaluateJavaScript( 61 "cr.ui.login.DisplayManager.errorMessageWasShownForTesting_;") 62 63 64 def attempt_unlock(self, password=''): 65 """Attempt to unlock a locked screen. The correct password is the empty 66 string. 67 68 @param password: password to use to attempt the unlock. 69 70 """ 71 self._chrome.browser.oobe.ExecuteJavaScript( 72 "Oobe.authenticateForTesting('%s', '%s');" 73 % (self._chrome.username, password)) 74 75 76 def lock_screen(self, perf_values): 77 """Lock the screen. 78 79 @param perf_values: Performance data will be stored inside of this dict. 80 81 @raises: error.TestFail when screen already locked. 82 @raises: error.TestFail if lockscreen screen not visible. 83 @raises: error.TestFail when screen not locked. 84 85 """ 86 logging.debug('lock_screen') 87 if self.screen_locked: 88 raise error.TestFail('Screen already locked') 89 signal_listener = session_manager.ScreenIsLockedSignalListener( 90 gobject.MainLoop()) 91 ext = self._chrome.autotest_ext 92 93 start = datetime.now() 94 ext.EvaluateJavaScript('chrome.autotestPrivate.lockScreen();') 95 signal_listener.wait_for_signals(desc='Screen is locked.', 96 timeout=self._SCREEN_IS_LOCKED_TIMEOUT) 97 perf_values['lock_seconds'] = (datetime.now() - start).total_seconds() 98 99 utils.poll_for_condition(lambda: self.screenlocker_visible, 100 exception=error.TestFail('Screenlock screen not visible')) 101 if not self.screen_locked: 102 raise error.TestFail('Screen not locked') 103 104 105 def lock_screen_through_keyboard(self): 106 """Lock the screen with keyboard(search+L) . 107 108 @raises: error.TestFail when screen already locked. 109 @raises: error.TestFail if lockscreen screen not visible. 110 @raises: error.TestFail when screen not locked after using keyboard shortcut. 111 112 """ 113 logging.debug('Locking screen through the keyboard shortcut') 114 if self.screen_locked: 115 raise error.TestFail('Screen already locked') 116 self.player.blocking_playback_of_default_file( 117 input_type='keyboard', filename='keyboard_search+L') 118 utils.poll_for_condition(lambda: self.screenlocker_visible, 119 exception=error.TestFail('Screenlock screen not visible')) 120 if not self.screen_locked: 121 raise error.TestFail('Screen not locked after using keyboard shortcut') 122 123 124 def attempt_unlock_bad_password(self): 125 """Attempt unlock with a bad password. 126 127 @raises: error.TestFail when try to unlock with bad password. 128 @raises: error.TestFail if bubble prematurely visible. 129 @raises: error.TestFail when Bad password bubble did not show. 130 131 """ 132 logging.debug('attempt_unlock_bad_password') 133 if self.error_bubble_visible: 134 raise error.TestFail('Error bubble prematurely visible') 135 self.attempt_unlock('bad') 136 utils.poll_for_condition(lambda: self.error_bubble_visible, 137 exception=error.TestFail('Bad password bubble did not show')) 138 if not self.screen_locked: 139 raise error.TestFail('Screen unlocked with bad password') 140 141 142 def unlock_screen(self): 143 """Unlock the screen with the right password. 144 145 @raises: error.TestFail if failed to unlock screen. 146 @raises: error.TestFail if screen unlocked. 147 148 """ 149 logging.debug('unlock_screen') 150 self.attempt_unlock() 151 utils.poll_for_condition( 152 lambda: not self._chrome.browser.oobe_exists, 153 exception=error.TestFail('Failed to unlock screen')) 154 if self.screen_locked: 155 raise error.TestFail('Screen should be unlocked') 156 157 158 def run_once(self): 159 """ 160 This test locks the screen, tries to unlock with a bad password, 161 then unlocks with the right password. 162 163 """ 164 with chrome.Chrome(autotest_ext=True) as self._chrome: 165 perf_values = {} 166 self.lock_screen(perf_values) 167 self.attempt_unlock_bad_password() 168 self.unlock_screen() 169 self.lock_screen_through_keyboard() 170 self.unlock_screen() 171 self.output_perf_value( 172 description='time_to_lock_screen', 173 value=perf_values['lock_seconds'], 174 units='s', 175 higher_is_better=False) 176