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