| # 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 |
| |
| |
| 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 screenlocker_visible(self): |
| """True if the screenlocker screen is visible.""" |
| oobe = self._chrome.browser.oobe |
| return (oobe and |
| oobe.EvaluateJavaScript( |
| "(typeof Oobe == 'function') && " |
| "(typeof Oobe.authenticateForTesting == 'function') && " |
| "($('account-picker') != null)")) |
| |
| @property |
| def error_bubble_visible(self): |
| """True if the error bubble for bad password is visible.""" |
| return self._chrome.browser.oobe.EvaluateJavaScript( |
| "cr.ui.login.DisplayManager.errorMessageWasShownForTesting_;") |
| |
| |
| def attempt_unlock(self, password=''): |
| """Attempt to unlock a locked screen. The correct password is the empty |
| string. |
| |
| @param password: password to use to attempt the unlock. |
| |
| """ |
| self._chrome.browser.oobe.ExecuteJavaScript( |
| "Oobe.authenticateForTesting('%s', '%s');" |
| % (self._chrome.username, password)) |
| |
| |
| 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 if lockscreen screen not visible. |
| @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.screenlocker_visible, |
| exception=error.TestFail('Screenlock screen not visible')) |
| if not self.screen_locked: |
| raise 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 lockscreen screen not visible. |
| @raises: error.TestFail when 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.screenlocker_visible, |
| exception=error.TestFail('Screenlock screen not visible')) |
| if not self.screen_locked: |
| raise 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 try to unlock with bad password. |
| @raises: error.TestFail if bubble prematurely visible. |
| @raises: error.TestFail when Bad password bubble did not show. |
| |
| """ |
| logging.debug('attempt_unlock_bad_password') |
| if self.error_bubble_visible: |
| raise error.TestFail('Error bubble prematurely visible') |
| self.attempt_unlock('bad') |
| utils.poll_for_condition(lambda: self.error_bubble_visible, |
| exception=error.TestFail('Bad password bubble did not show')) |
| if not self.screen_locked: |
| raise error.TestFail('Screen unlocked with bad password') |
| |
| |
| def unlock_screen(self): |
| """Unlock the screen with the right password. |
| |
| @raises: error.TestFail if failed to unlock screen. |
| @raises: error.TestFail if screen unlocked. |
| |
| """ |
| logging.debug('unlock_screen') |
| self.attempt_unlock() |
| utils.poll_for_condition( |
| lambda: not self._chrome.browser.oobe_exists, |
| exception=error.TestFail('Failed to unlock screen')) |
| if self.screen_locked: |
| raise error.TestFail('Screen should be unlocked') |
| |
| |
| def run_once(self): |
| """ |
| This test locks the screen, tries to unlock with a bad password, |
| then unlocks with the right password. |
| |
| """ |
| # TODO(crbug.com/781998): This test needs to support views-based lock |
| # (ie, remove --show-webui-lock). Doing this requires replacing the |
| # oobe.EvaluateJavaScript with autotestPrivate calls. |
| with chrome.Chrome( |
| autotest_ext=True, |
| extra_browser_args=['--show-webui-lock']) 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) |