1 // Copyright 2014 The Chromium 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
5 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
6
7 #include <memory>
8
9 #include "ash/wm/window_state.h"
10 #include "base/bind.h"
11 #include "base/macros.h"
12 #include "base/run_loop.h"
13 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
14 #include "chrome/browser/chromeos/login/lock/screen_locker_tester.h"
15 #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h"
16 #include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
17 #include "chrome/browser/profiles/profile_manager.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_window.h"
20 #include "chrome/browser/ui/exclusive_access/exclusive_access_test.h"
21 #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/in_process_browser_test.h"
24 #include "chromeos/dbus/biod/fake_biod_client.h"
25 #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
26 #include "components/prefs/pref_service.h"
27 #include "components/session_manager/core/session_manager.h"
28 #include "components/user_manager/user_names.h"
29 #include "content/public/test/browser_test.h"
30 #include "content/public/test/test_utils.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
33
34 namespace chromeos {
35 namespace {
36
37 constexpr char kFingerprint[] = "pinky";
38
39 class ScreenLockerTest : public InProcessBrowserTest {
40 public:
41 ScreenLockerTest() = default;
42 ~ScreenLockerTest() override = default;
43
session_manager_client()44 FakeSessionManagerClient* session_manager_client() {
45 return FakeSessionManagerClient::Get();
46 }
47
48 // InProcessBrowserTest:
SetUpInProcessBrowserTestFixture()49 void SetUpInProcessBrowserTestFixture() override {
50 zero_duration_mode_ =
51 std::make_unique<ui::ScopedAnimationDurationScaleMode>(
52 ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
53 }
54
TearDown()55 void TearDown() override { quick_unlock::EnabledForTesting(false); }
56
EnrollFingerprint()57 void EnrollFingerprint() {
58 quick_unlock::EnabledForTesting(true);
59
60 FakeBiodClient::Get()->StartEnrollSession(
61 "test-user", std::string(),
62 base::BindOnce(&ScreenLockerTest::OnStartSession,
63 base::Unretained(this)));
64 base::RunLoop().RunUntilIdle();
65
66 FakeBiodClient::Get()->SendEnrollScanDone(
67 kFingerprint, biod::SCAN_RESULT_SUCCESS, true /* is_complete */,
68 -1 /* percent_complete */);
69 base::RunLoop().RunUntilIdle();
70
71 ProfileManager::GetActiveUserProfile()->GetPrefs()->SetInteger(
72 prefs::kQuickUnlockFingerprintRecord, 1);
73 }
74
AuthenticateWithFingerprint()75 void AuthenticateWithFingerprint() {
76 FakeBiodClient::Get()->SendAuthScanDone(kFingerprint,
77 biod::SCAN_RESULT_SUCCESS);
78 base::RunLoop().RunUntilIdle();
79 }
80
81 private:
OnStartSession(const dbus::ObjectPath & path)82 void OnStartSession(const dbus::ObjectPath& path) {}
83
84 std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_;
85
86 DISALLOW_COPY_AND_ASSIGN(ScreenLockerTest);
87 };
88
89 } // namespace
90
IN_PROC_BROWSER_TEST_F(ScreenLockerTest,TestBadThenGoodPassword)91 IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestBadThenGoodPassword) {
92 ScreenLockerTester tester;
93 tester.Lock();
94
95 tester.SetUnlockPassword(user_manager::StubAccountId(), "pass");
96
97 // Submit a bad password.
98 tester.UnlockWithPassword(user_manager::StubAccountId(), "fail");
99 EXPECT_TRUE(tester.IsLocked());
100
101 // Submit the correct password. Successful authentication clears the lock
102 // screen and tells the SessionManager to announce this over DBus.
103 tester.UnlockWithPassword(user_manager::StubAccountId(), "pass");
104 EXPECT_FALSE(tester.IsLocked());
105 EXPECT_EQ(1, session_manager_client()->notify_lock_screen_shown_call_count());
106 EXPECT_EQ(session_manager::SessionState::ACTIVE,
107 session_manager::SessionManager::Get()->session_state());
108 EXPECT_EQ(
109 1, session_manager_client()->notify_lock_screen_dismissed_call_count());
110 }
111
112 // Test how locking the screen affects an active fullscreen window.
IN_PROC_BROWSER_TEST_F(ScreenLockerTest,TestFullscreenExit)113 IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestFullscreenExit) {
114 // 1) If the active browser window is in fullscreen and the fullscreen window
115 // does not have all the pixels (e.g. the shelf is auto hidden instead of
116 // hidden), locking the screen should exit fullscreen. The shelf is
117 // auto hidden when in immersive fullscreen.
118 ScreenLockerTester tester;
119 BrowserWindow* browser_window = browser()->window();
120 ash::WindowState* window_state =
121 ash::WindowState::Get(browser_window->GetNativeWindow());
122 {
123 FullscreenNotificationObserver fullscreen_waiter(browser());
124 browser()
125 ->exclusive_access_manager()
126 ->fullscreen_controller()
127 ->ToggleBrowserFullscreenMode();
128 fullscreen_waiter.Wait();
129 EXPECT_TRUE(browser_window->IsFullscreen());
130 EXPECT_FALSE(window_state->GetHideShelfWhenFullscreen());
131 EXPECT_FALSE(tester.IsLocked());
132 }
133 {
134 tester.Lock();
135 EXPECT_FALSE(browser_window->IsFullscreen());
136 EXPECT_TRUE(window_state->GetHideShelfWhenFullscreen());
137 EXPECT_TRUE(tester.IsLocked());
138 }
139 tester.SetUnlockPassword(user_manager::StubAccountId(), "pass");
140 tester.UnlockWithPassword(user_manager::StubAccountId(), "pass");
141 EXPECT_FALSE(tester.IsLocked());
142 EXPECT_FALSE(browser_window->IsFullscreen());
143
144 // Browser window should be activated after screen locker is gone. Otherwise,
145 // the rest of the test would fail.
146 ASSERT_EQ(window_state, ash::WindowState::ForActiveWindow());
147
148 // 2) Similar to 1) if the active browser window is in fullscreen and the
149 // fullscreen window has all of the pixels, locking the screen should exit
150 // fullscreen. The fullscreen window has all of the pixels when in tab
151 // fullscreen.
152 {
153 FullscreenNotificationObserver fullscreen_waiter(browser());
154 content::WebContents* web_contents =
155 browser()->tab_strip_model()->GetActiveWebContents();
156 browser()
157 ->exclusive_access_manager()
158 ->fullscreen_controller()
159 ->EnterFullscreenModeForTab(web_contents->GetMainFrame());
160 fullscreen_waiter.Wait();
161 EXPECT_TRUE(browser_window->IsFullscreen());
162 EXPECT_TRUE(window_state->GetHideShelfWhenFullscreen());
163 EXPECT_FALSE(tester.IsLocked());
164 }
165 {
166 tester.Lock();
167 EXPECT_FALSE(browser_window->IsFullscreen());
168 EXPECT_TRUE(tester.IsLocked());
169 }
170
171 tester.SetUnlockPassword(user_manager::StubAccountId(), "pass");
172 tester.UnlockWithPassword(user_manager::StubAccountId(), "pass");
173 EXPECT_FALSE(tester.IsLocked());
174
175 EXPECT_EQ(2, session_manager_client()->notify_lock_screen_shown_call_count());
176 EXPECT_EQ(
177 2, session_manager_client()->notify_lock_screen_dismissed_call_count());
178 }
179
IN_PROC_BROWSER_TEST_F(ScreenLockerTest,TestShowTwice)180 IN_PROC_BROWSER_TEST_F(ScreenLockerTest, TestShowTwice) {
181 ScreenLockerTester tester;
182 tester.Lock();
183
184 // Calling Show again simply send LockCompleted signal.
185 ScreenLocker::Show();
186 EXPECT_TRUE(tester.IsLocked());
187 EXPECT_EQ(2, session_manager_client()->notify_lock_screen_shown_call_count());
188
189 // Close the locker to match expectations.
190 ScreenLocker::Hide();
191 base::RunLoop().RunUntilIdle();
192 EXPECT_FALSE(tester.IsLocked());
193 EXPECT_EQ(
194 1, session_manager_client()->notify_lock_screen_dismissed_call_count());
195 }
196
IN_PROC_BROWSER_TEST_F(ScreenLockerTest,PasswordAuthWhenAuthDisabled)197 IN_PROC_BROWSER_TEST_F(ScreenLockerTest, PasswordAuthWhenAuthDisabled) {
198 // Show lock screen and wait until it is shown.
199 ScreenLockerTester tester;
200 tester.Lock();
201
202 // Inject fake authentication credentials.
203 const std::string kPassword = "pass";
204 tester.SetUnlockPassword(user_manager::StubAccountId(), kPassword);
205 EXPECT_TRUE(tester.IsLocked());
206
207 // Disable authentication for user.
208 ScreenLocker::default_screen_locker()->DisableAuthForUser(
209 user_manager::StubAccountId(),
210 ash::AuthDisabledData(ash::AuthDisabledReason::kTimeWindowLimit,
211 base::Time::Now() + base::TimeDelta::FromHours(1),
212 base::TimeDelta::FromHours(1),
213 true /*disable_lock_screen_media*/));
214
215 // Try to authenticate with password.
216 tester.ForceSubmitPassword(user_manager::StubAccountId(), kPassword);
217 EXPECT_TRUE(tester.IsLocked());
218
219 // Re-enable authentication for user.
220 ScreenLocker::default_screen_locker()->EnableAuthForUser(
221 user_manager::StubAccountId());
222
223 // Try to authenticate with password.
224 tester.UnlockWithPassword(user_manager::StubAccountId(), kPassword);
225 base::RunLoop().RunUntilIdle();
226 EXPECT_FALSE(tester.IsLocked());
227 EXPECT_EQ(1, session_manager_client()->notify_lock_screen_shown_call_count());
228 EXPECT_EQ(session_manager::SessionState::ACTIVE,
229 session_manager::SessionManager::Get()->session_state());
230 EXPECT_EQ(
231 1, session_manager_client()->notify_lock_screen_dismissed_call_count());
232 }
233
IN_PROC_BROWSER_TEST_F(ScreenLockerTest,FingerprintAuthWhenAuthDisabled)234 IN_PROC_BROWSER_TEST_F(ScreenLockerTest, FingerprintAuthWhenAuthDisabled) {
235 EnrollFingerprint();
236
237 // Show lock screen and wait until it is shown.
238 ScreenLockerTester tester;
239 tester.Lock();
240
241 const std::string kPassword = "pass";
242 tester.SetUnlockPassword(user_manager::StubAccountId(), kPassword);
243 EXPECT_TRUE(tester.IsLocked());
244
245 // Disable authentication for user.
246 ScreenLocker::default_screen_locker()->DisableAuthForUser(
247 user_manager::StubAccountId(),
248 ash::AuthDisabledData(ash::AuthDisabledReason::kTimeUsageLimit,
249 base::Time::Now() + base::TimeDelta::FromHours(1),
250 base::TimeDelta::FromHours(3),
251 true /*disable_lock_screen_media*/));
252
253 // Try to authenticate with fingerprint.
254 AuthenticateWithFingerprint();
255 EXPECT_TRUE(tester.IsLocked());
256
257 // Re-enable authentication for user.
258 ScreenLocker::default_screen_locker()->EnableAuthForUser(
259 user_manager::StubAccountId());
260
261 // Try to authenticate with fingerprint.
262 AuthenticateWithFingerprint();
263 EXPECT_FALSE(tester.IsLocked());
264 EXPECT_EQ(1, session_manager_client()->notify_lock_screen_shown_call_count());
265 EXPECT_EQ(session_manager::SessionState::ACTIVE,
266 session_manager::SessionManager::Get()->session_state());
267 EXPECT_EQ(
268 1, session_manager_client()->notify_lock_screen_dismissed_call_count());
269 }
270
271 } // namespace chromeos
272