• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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