| # Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import gobject |
| import logging |
| |
| from autotest_lib.client.bin import test, utils |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.common_lib.cros import chrome, session_manager |
| from autotest_lib.client.cros import asan |
| from autotest_lib.client.cros.input_playback import input_playback |
| |
| from datetime import datetime |
| from dbus.mainloop.glib import DBusGMainLoop |
| |
| class desktopui_ScreenLocker(test.test): |
| """This is a client side test that exercises the screenlocker.""" |
| version = 1 |
| |
| _SCREEN_IS_LOCKED_TIMEOUT = 30 |
| # TODO(jdufault): Remove this timeout increase for asan bots once we figure |
| # out what's taking so long to lock the screen. See crbug.com/452599. |
| if asan.running_on_asan(): |
| _SCREEN_IS_LOCKED_TIMEOUT *= 2 |
| |
| """Timeout for password authentication.""" |
| _AUTHENTICATION_TIMEOUT = 30 |
| |
| |
| def initialize(self): |
| """Init method""" |
| super(desktopui_ScreenLocker, self).initialize() |
| DBusGMainLoop(set_as_default=True) |
| self.player = input_playback.InputPlayback() |
| self.player.emulate(input_type='keyboard') |
| self.player.find_connected_inputs() |
| |
| |
| def cleanup(self): |
| """Test cleanup.""" |
| self.player.close() |
| |
| |
| @property |
| def screen_locked(self): |
| """True if the screen is locked.""" |
| return self._chrome.login_status['isScreenLocked'] |
| |
| |
| @property |
| def screen_ready_for_password(self): |
| """True if the screen is ready for password.""" |
| return self._chrome.login_status['isReadyForPassword'] |
| |
| |
| def lock_screen(self, perf_values): |
| """Lock the screen. |
| |
| @param perf_values: Performance data will be stored inside of this dict. |
| |
| @raises: error.TestFail when screen already locked. |
| @raises: error.TestFail when screen not locked. |
| |
| """ |
| logging.debug('lock_screen') |
| if self.screen_locked: |
| raise error.TestFail('Screen already locked') |
| signal_listener = session_manager.ScreenIsLockedSignalListener( |
| gobject.MainLoop()) |
| ext = self._chrome.autotest_ext |
| |
| start = datetime.now() |
| ext.EvaluateJavaScript('chrome.autotestPrivate.lockScreen();') |
| signal_listener.wait_for_signals(desc='Screen is locked.', |
| timeout=self._SCREEN_IS_LOCKED_TIMEOUT) |
| perf_values['lock_seconds'] = (datetime.now() - start).total_seconds() |
| |
| utils.poll_for_condition( |
| lambda: self.screen_locked, |
| exception=error.TestFail('Screen not locked')) |
| |
| |
| def lock_screen_through_keyboard(self): |
| """Lock the screen with keyboard(search+L) . |
| |
| @raises: error.TestFail when screen already locked. |
| @raises: error.TestFail if screen not locked after using keyboard |
| shortcut. |
| |
| """ |
| logging.debug('Locking screen through the keyboard shortcut') |
| if self.screen_locked: |
| raise error.TestFail('Screen already locked') |
| self.player.blocking_playback_of_default_file( |
| input_type='keyboard', filename='keyboard_search+L') |
| utils.poll_for_condition( |
| lambda: self.screen_locked, |
| exception=error.TestFail( |
| 'Screen not locked after using keyboard shortcut')) |
| |
| |
| def attempt_unlock_bad_password(self): |
| """Attempt unlock with a bad password. |
| |
| @raises: error.TestFail when successfully unlock with bad password. |
| |
| """ |
| logging.debug('attempt_unlock_bad_password') |
| self.player.blocking_playback_of_default_file( |
| input_type='keyboard', filename='keyboard_b+a+d+enter') |
| |
| # Wait for the authentication to complete. |
| utils.poll_for_condition( |
| lambda: self.screen_ready_for_password, |
| exception=error.TestFail( |
| 'Authentication is not completed after %d seconds', |
| self._AUTHENTICATION_TIMEOUT), |
| timeout=self._AUTHENTICATION_TIMEOUT) |
| if not self.screen_locked: |
| raise error.TestFail('Screen unlocked with bad password') |
| |
| |
| def unlock_screen(self): |
| """Unlock the screen with the right password. The correct password is |
| the empty string. |
| TODO(crbug.com/792251): Use non-empty password. |
| |
| @raises: error.TestFail if failed to unlock screen. |
| |
| """ |
| logging.debug('unlock_screen') |
| self.player.blocking_playback_of_default_file( |
| input_type='keyboard', filename='keyboard_g+o+o+d+enter') |
| utils.poll_for_condition( |
| lambda: not self.screen_locked, |
| exception=error.TestFail('Failed to unlock screen'), |
| timeout=self._AUTHENTICATION_TIMEOUT) |
| |
| |
| def run_once(self): |
| """ |
| This test locks the screen, tries to unlock with a bad password, |
| then unlocks with the right password. |
| |
| """ |
| with chrome.Chrome(autotest_ext=True, password='good') as self._chrome: |
| try: |
| # Give performance data some initial state that will be reported |
| # if the test times out. |
| perf_values = { 'lock_seconds': self._SCREEN_IS_LOCKED_TIMEOUT } |
| |
| self.lock_screen(perf_values) |
| self.attempt_unlock_bad_password() |
| self.unlock_screen() |
| self.lock_screen_through_keyboard() |
| self.unlock_screen() |
| finally: |
| self.output_perf_value( |
| description='time_to_lock_screen', |
| value=perf_values['lock_seconds'], |
| units='s', |
| higher_is_better=False) |