[go: nahoru, domu]

blob: 016c0d276683d293103dab931085c1992613d9e0 [file] [log] [blame]
xiaoyinh2bbdd102017-05-18 23:29:421// Copyright 2017 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
Jacob Dufaultffd9b0d2017-11-15 23:07:165#include "ash/login/login_screen_controller.h"
xiaoyinh2bbdd102017-05-18 23:29:426
jdufaulteb4c9f1e2017-06-08 23:08:307#include "ash/login/ui/lock_screen.h"
Jacob Dufault40623d52017-09-15 17:22:538#include "ash/login/ui/login_data_dispatcher.h"
Sarah Hu069eea12017-09-08 01:28:409#include "ash/public/cpp/ash_pref_names.h"
Aga Wronska16abb432018-01-11 23:49:5910#include "ash/root_window_controller.h"
Sarah Hu069eea12017-09-08 01:28:4011#include "ash/session/session_controller.h"
12#include "ash/shell.h"
Aga Wronska16abb432018-01-11 23:49:5913#include "ash/system/status_area_widget.h"
Jacob Dufaultc06d6ca2018-04-24 23:49:1714#include "base/debug/alias.h"
Sarah Hu069eea12017-09-08 01:28:4015#include "base/strings/string_number_conversions.h"
Jialiu Linf99b788b2018-01-17 23:01:2116#include "base/strings/utf_string_conversions.h"
xiaoyinh2bbdd102017-05-18 23:29:4217#include "chromeos/cryptohome/system_salt_getter.h"
Roman Sorokinc5590012017-09-28 00:48:2918#include "chromeos/login/auth/authpolicy_login_helper.h"
xiaoyinh2bbdd102017-05-18 23:29:4219#include "chromeos/login/auth/user_context.h"
Jialiu Linf99b788b2018-01-17 23:01:2120#include "components/password_manager/core/browser/hash_password_manager.h"
Sarah Hu069eea12017-09-08 01:28:4021#include "components/prefs/pref_registry_simple.h"
22#include "components/prefs/pref_service.h"
Jacob Dufault957e0922017-12-06 19:16:0923#include "components/session_manager/session_manager_types.h"
xiaoyinh2bbdd102017-05-18 23:29:4224
25namespace ash {
26
Sarah Hu069eea12017-09-08 01:28:4027namespace {
xiaoyinh2bbdd102017-05-18 23:29:4228
Sarah Hu069eea12017-09-08 01:28:4029std::string CalculateHash(const std::string& password,
30 const std::string& salt,
31 chromeos::Key::KeyType key_type) {
32 chromeos::Key key(password);
33 key.Transform(key_type, salt);
34 return key.GetSecret();
35}
36
Aga Wronskaa844cdcd12018-01-29 16:06:4437enum class SystemTrayVisibility {
38 kNone, // Tray not visible anywhere.
39 kPrimary, // Tray visible only on primary display.
40 kAll, // Tray visible on all displays.
41};
42
43void SetSystemTrayVisibility(SystemTrayVisibility visibility) {
44 RootWindowController* primary_window_controller =
45 Shell::GetPrimaryRootWindowController();
46 for (RootWindowController* window_controller :
47 Shell::GetAllRootWindowControllers()) {
48 StatusAreaWidget* status_area = window_controller->GetStatusAreaWidget();
49 if (!status_area)
50 continue;
51 if (window_controller == primary_window_controller) {
52 status_area->SetSystemTrayVisibility(
53 visibility == SystemTrayVisibility::kPrimary ||
54 visibility == SystemTrayVisibility::kAll);
55 } else {
56 status_area->SetSystemTrayVisibility(visibility ==
57 SystemTrayVisibility::kAll);
58 }
59 }
Aga Wronska16abb432018-01-11 23:49:5960}
61
Sarah Hu069eea12017-09-08 01:28:4062} // namespace
63
James Cookede316a2017-12-14 22:38:4364LoginScreenController::LoginScreenController() : weak_factory_(this) {}
James Cook8f1e6062017-11-13 23:40:5965
Jacob Dufaultffd9b0d2017-11-15 23:07:1666LoginScreenController::~LoginScreenController() = default;
xiaoyinh2bbdd102017-05-18 23:29:4267
Sarah Hu069eea12017-09-08 01:28:4068// static
Jacob Dufaultffd9b0d2017-11-15 23:07:1669void LoginScreenController::RegisterProfilePrefs(PrefRegistrySimple* registry,
70 bool for_test) {
Sarah Hu069eea12017-09-08 01:28:4071 if (for_test) {
72 // There is no remote pref service, so pretend that ash owns the pref.
73 registry->RegisterStringPref(prefs::kQuickUnlockPinSalt, "");
74 return;
75 }
76
77 // Pref is owned by chrome and flagged as PUBLIC.
78 registry->RegisterForeignPref(prefs::kQuickUnlockPinSalt);
79}
80
Jacob Dufaultffd9b0d2017-11-15 23:07:1681void LoginScreenController::BindRequest(mojom::LoginScreenRequest request) {
James Cookede316a2017-12-14 22:38:4382 bindings_.AddBinding(this, std::move(request));
xiaoyinh2bbdd102017-05-18 23:29:4283}
84
Jacob Dufaultb7a2d842017-12-01 23:21:1585void LoginScreenController::AuthenticateUser(const AccountId& account_id,
86 const std::string& password,
87 bool authenticated_by_pin,
88 OnAuthenticateCallback callback) {
Jacob Dufault8876ba82018-03-27 22:55:4389 // It is an error to call this function while an authentication is in
90 // progress.
Jacob Dufaultc06d6ca2018-04-24 23:49:1791 LOG_IF(ERROR, authentication_stage_ != AuthenticationStage::kIdle)
Jacob Dufault8876ba82018-03-27 22:55:4392 << "Authentication stage is " << static_cast<int>(authentication_stage_);
93 CHECK_EQ(authentication_stage_, AuthenticationStage::kIdle);
94
95 if (!login_screen_client_) {
Jacob Dufaultb7a2d842017-12-01 23:21:1596 std::move(callback).Run(base::nullopt);
xiaoyinh9f6fa0e2017-06-07 19:22:3297 return;
Jacob Dufaultb7a2d842017-12-01 23:21:1598 }
xiaoyinh9f6fa0e2017-06-07 19:22:3299
Jacob Dufaulteafc6fe2017-10-11 21:16:52100 // If auth is disabled by the debug overlay bypass the mojo call entirely, as
101 // it will dismiss the lock screen if the password is correct.
Jacob Dufault0fbed9c02017-11-14 19:22:24102 switch (force_fail_auth_for_debug_overlay_) {
103 case ForceFailAuth::kOff:
104 break;
105 case ForceFailAuth::kImmediate:
Jacob Dufaultb7a2d842017-12-01 23:21:15106 OnAuthenticateComplete(std::move(callback), false /*success*/);
Jacob Dufault0fbed9c02017-11-14 19:22:24107 return;
108 case ForceFailAuth::kDelayed:
109 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
Jacob Dufaultb7a2d842017-12-01 23:21:15110 FROM_HERE,
111 base::BindOnce(&LoginScreenController::OnAuthenticateComplete,
112 weak_factory_.GetWeakPtr(), base::Passed(&callback),
113 false),
Jacob Dufault0fbed9c02017-11-14 19:22:24114 base::TimeDelta::FromSeconds(1));
115 return;
Jacob Dufaulteafc6fe2017-10-11 21:16:52116 }
117
Jacob Dufault8876ba82018-03-27 22:55:43118 // |DoAuthenticateUser| requires the system salt.
119 authentication_stage_ = AuthenticationStage::kGetSystemSalt;
120 chromeos::SystemSaltGetter::Get()->GetSystemSalt(
121 base::AdaptCallbackForRepeating(
122 base::BindOnce(&LoginScreenController::DoAuthenticateUser,
123 weak_factory_.GetWeakPtr(), account_id, password,
124 authenticated_by_pin, std::move(callback))));
xiaoyinh9f6fa0e2017-06-07 19:22:32125}
126
Jacob Dufaultffd9b0d2017-11-15 23:07:16127void LoginScreenController::AttemptUnlock(const AccountId& account_id) {
128 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32129 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16130 login_screen_client_->AttemptUnlock(account_id);
Sarah Hue0e01a52017-10-25 20:29:30131
132 Shell::Get()->metrics()->login_metrics_recorder()->SetAuthMethod(
133 LoginMetricsRecorder::AuthMethod::kSmartlock);
xiaoyinh9f6fa0e2017-06-07 19:22:32134}
135
Jacob Dufaultffd9b0d2017-11-15 23:07:16136void LoginScreenController::HardlockPod(const AccountId& account_id) {
137 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32138 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16139 login_screen_client_->HardlockPod(account_id);
xiaoyinh9f6fa0e2017-06-07 19:22:32140}
141
Jacob Dufaultffd9b0d2017-11-15 23:07:16142void LoginScreenController::RecordClickOnLockIcon(const AccountId& account_id) {
143 if (!login_screen_client_)
xiaoyinh9f6fa0e2017-06-07 19:22:32144 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16145 login_screen_client_->RecordClickOnLockIcon(account_id);
xiaoyinh9f6fa0e2017-06-07 19:22:32146}
147
Jacob Dufaultffd9b0d2017-11-15 23:07:16148void LoginScreenController::OnFocusPod(const AccountId& account_id) {
149 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27150 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16151 login_screen_client_->OnFocusPod(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27152}
153
Jacob Dufaultffd9b0d2017-11-15 23:07:16154void LoginScreenController::OnNoPodFocused() {
155 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27156 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16157 login_screen_client_->OnNoPodFocused();
xiaoyinhf534c4f2017-06-13 20:50:27158}
159
Jacob Dufaultffd9b0d2017-11-15 23:07:16160void LoginScreenController::LoadWallpaper(const AccountId& account_id) {
161 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27162 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16163 login_screen_client_->LoadWallpaper(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27164}
165
Jacob Dufaultffd9b0d2017-11-15 23:07:16166void LoginScreenController::SignOutUser() {
167 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27168 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16169 login_screen_client_->SignOutUser();
xiaoyinhf534c4f2017-06-13 20:50:27170}
171
Jacob Dufaultffd9b0d2017-11-15 23:07:16172void LoginScreenController::CancelAddUser() {
173 if (!login_screen_client_)
Wenzhao Zang16e7ea722017-09-16 01:27:30174 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16175 login_screen_client_->CancelAddUser();
Wenzhao Zang16e7ea722017-09-16 01:27:30176}
177
Aga Wronska6a32f9872018-01-06 00:16:10178void LoginScreenController::LoginAsGuest() {
179 if (!login_screen_client_)
180 return;
181 login_screen_client_->LoginAsGuest();
182}
183
Jacob Dufaultffd9b0d2017-11-15 23:07:16184void LoginScreenController::OnMaxIncorrectPasswordAttempted(
xiaoyinhf534c4f2017-06-13 20:50:27185 const AccountId& account_id) {
Jacob Dufaultffd9b0d2017-11-15 23:07:16186 if (!login_screen_client_)
xiaoyinhf534c4f2017-06-13 20:50:27187 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16188 login_screen_client_->OnMaxIncorrectPasswordAttempted(account_id);
xiaoyinhf534c4f2017-06-13 20:50:27189}
190
Jacob Dufaultffd9b0d2017-11-15 23:07:16191void LoginScreenController::FocusLockScreenApps(bool reverse) {
192 if (!login_screen_client_)
Toni Barzicf61c4452017-10-05 03:57:48193 return;
Jacob Dufaultffd9b0d2017-11-15 23:07:16194 login_screen_client_->FocusLockScreenApps(reverse);
Toni Barzicf61c4452017-10-05 03:57:48195}
196
Sarah Hu9fba0e752018-02-07 01:41:09197void LoginScreenController::ShowGaiaSignin() {
198 if (!login_screen_client_)
199 return;
200 login_screen_client_->ShowGaiaSignin();
201}
202
Jacob Dufaultfc31c742018-03-20 17:32:19203void LoginScreenController::OnRemoveUserWarningShown() {
204 if (!login_screen_client_)
205 return;
206 login_screen_client_->OnRemoveUserWarningShown();
207}
208
209void LoginScreenController::RemoveUser(const AccountId& account_id) {
210 if (!login_screen_client_)
211 return;
212 login_screen_client_->RemoveUser(account_id);
213}
214
Sarah Hu3fcf9f82018-03-22 20:32:54215void LoginScreenController::LaunchPublicSession(
216 const AccountId& account_id,
217 const std::string& locale,
218 const std::string& input_method) {
219 if (!login_screen_client_)
220 return;
221 login_screen_client_->LaunchPublicSession(account_id, locale, input_method);
222}
223
Sarah Huf9affb122018-04-27 21:36:36224void LoginScreenController::RequestPublicSessionKeyboardLayouts(
225 const AccountId& account_id,
226 const std::string& locale) {
227 if (!login_screen_client_)
228 return;
229 login_screen_client_->RequestPublicSessionKeyboardLayouts(account_id, locale);
230}
231
Jacob Dufault589d9942018-03-27 20:28:47232void LoginScreenController::AddObserver(
233 LoginScreenControllerObserver* observer) {
234 observers_.AddObserver(observer);
Toni Barzicf61c4452017-10-05 03:57:48235}
236
Jacob Dufault589d9942018-03-27 20:28:47237void LoginScreenController::RemoveObserver(
238 LoginScreenControllerObserver* observer) {
239 observers_.RemoveObserver(observer);
Toni Barzicf61c4452017-10-05 03:57:48240}
241
Jacob Dufaultffd9b0d2017-11-15 23:07:16242void LoginScreenController::FlushForTesting() {
243 login_screen_client_.FlushForTesting();
Toni Barzicf61c4452017-10-05 03:57:48244}
245
Jacob Dufault589d9942018-03-27 20:28:47246void LoginScreenController::SetClient(mojom::LoginScreenClientPtr client) {
247 login_screen_client_ = std::move(client);
248}
249
250void LoginScreenController::ShowLockScreen(ShowLockScreenCallback on_shown) {
251 OnShow();
252 ash::LockScreen::Show(ash::LockScreen::ScreenType::kLock);
253 std::move(on_shown).Run(true);
254}
255
256void LoginScreenController::ShowLoginScreen(ShowLoginScreenCallback on_shown) {
257 // Login screen can only be used during login.
258 if (Shell::Get()->session_controller()->GetSessionState() !=
259 session_manager::SessionState::LOGIN_PRIMARY) {
260 LOG(ERROR) << "Not showing login screen since session state is "
261 << static_cast<int>(
262 Shell::Get()->session_controller()->GetSessionState());
263 std::move(on_shown).Run(false);
264 return;
265 }
266
267 OnShow();
268 // TODO(jdufault): rename ash::LockScreen to ash::LoginScreen.
269 ash::LockScreen::Show(ash::LockScreen::ScreenType::kLogin);
270 std::move(on_shown).Run(true);
271}
272
273void LoginScreenController::ShowErrorMessage(int32_t login_attempts,
274 const std::string& error_text,
275 const std::string& help_link_text,
276 int32_t help_topic_id) {
277 NOTIMPLEMENTED();
278}
279
280void LoginScreenController::ClearErrors() {
281 NOTIMPLEMENTED();
282}
283
284void LoginScreenController::ShowUserPodCustomIcon(
285 const AccountId& account_id,
286 mojom::EasyUnlockIconOptionsPtr icon) {
287 DataDispatcher()->ShowEasyUnlockIcon(account_id, icon);
288}
289
290void LoginScreenController::HideUserPodCustomIcon(const AccountId& account_id) {
291 auto icon_options = mojom::EasyUnlockIconOptions::New();
292 icon_options->icon = mojom::EasyUnlockIconId::NONE;
293 DataDispatcher()->ShowEasyUnlockIcon(account_id, icon_options);
294}
295
296void LoginScreenController::SetAuthType(
297 const AccountId& account_id,
298 proximity_auth::mojom::AuthType auth_type,
299 const base::string16& initial_value) {
300 if (auth_type == proximity_auth::mojom::AuthType::USER_CLICK) {
301 DataDispatcher()->SetClickToUnlockEnabledForUser(account_id,
302 true /*enabled*/);
303 } else {
304 NOTIMPLEMENTED();
305 }
306}
307
308void LoginScreenController::LoadUsers(
309 std::vector<mojom::LoginUserInfoPtr> users,
310 bool show_guest) {
311 DCHECK(DataDispatcher());
312
313 DataDispatcher()->NotifyUsers(users);
314}
315
316void LoginScreenController::SetPinEnabledForUser(const AccountId& account_id,
317 bool is_enabled) {
318 // Chrome will update pin pod state every time user tries to authenticate.
319 // LockScreen is destroyed in the case of authentication success.
320 if (DataDispatcher())
321 DataDispatcher()->SetPinEnabledForUser(account_id, is_enabled);
322}
323
Jacob Dufault77d75ce92018-04-13 18:20:09324void LoginScreenController::SetAvatarForUser(const AccountId& account_id,
325 mojom::UserAvatarPtr avatar) {
326 for (auto& observer : observers_)
327 observer.SetAvatarForUser(account_id, avatar);
328}
329
Jacob Dufault589d9942018-03-27 20:28:47330void LoginScreenController::HandleFocusLeavingLockScreenApps(bool reverse) {
331 for (auto& observer : observers_)
332 observer.OnFocusLeavingLockScreenApps(reverse);
333}
334
335void LoginScreenController::SetDevChannelInfo(
336 const std::string& os_version_label_text,
337 const std::string& enterprise_info_text,
338 const std::string& bluetooth_name) {
339 if (DataDispatcher()) {
340 DataDispatcher()->SetDevChannelInfo(os_version_label_text,
341 enterprise_info_text, bluetooth_name);
342 }
343}
344
345void LoginScreenController::IsReadyForPassword(
346 IsReadyForPasswordCallback callback) {
Jacob Dufault8876ba82018-03-27 22:55:43347 std::move(callback).Run(LockScreen::IsShown() &&
348 authentication_stage_ == AuthenticationStage::kIdle);
Jacob Dufault589d9942018-03-27 20:28:47349}
350
351void LoginScreenController::SetPublicSessionDisplayName(
352 const AccountId& account_id,
353 const std::string& display_name) {
354 if (DataDispatcher())
355 DataDispatcher()->SetPublicSessionDisplayName(account_id, display_name);
356}
357
358void LoginScreenController::SetPublicSessionLocales(
359 const AccountId& account_id,
Oksana Zhuravlovac950e1d12018-04-17 15:46:29360 base::Value locales,
Jacob Dufault589d9942018-03-27 20:28:47361 const std::string& default_locale,
362 bool show_advanced_view) {
363 if (DataDispatcher()) {
364 DataDispatcher()->SetPublicSessionLocales(
Oksana Zhuravlovac950e1d12018-04-17 15:46:29365 account_id,
366 base::ListValue::From(
367 base::Value::ToUniquePtrValue(std::move(locales))),
368 default_locale, show_advanced_view);
Jacob Dufault589d9942018-03-27 20:28:47369 }
370}
371
Sarah Huf9affb122018-04-27 21:36:36372void LoginScreenController::SetPublicSessionKeyboardLayouts(
373 const AccountId& account_id,
374 const std::string& locale,
375 std::vector<mojom::InputMethodItemPtr> keyboard_layouts) {
376 if (DataDispatcher()) {
377 DataDispatcher()->SetPublicSessionKeyboardLayouts(account_id, locale,
378 keyboard_layouts);
379 }
380}
381
Jacob Dufaultb7a2d842017-12-01 23:21:15382void LoginScreenController::DoAuthenticateUser(const AccountId& account_id,
383 const std::string& password,
384 bool authenticated_by_pin,
385 OnAuthenticateCallback callback,
386 const std::string& system_salt) {
Jacob Dufault8876ba82018-03-27 22:55:43387 authentication_stage_ = AuthenticationStage::kDoAuthenticate;
388
Sarah Hu069eea12017-09-08 01:28:40389 int dummy_value;
390 bool is_pin =
391 authenticated_by_pin && base::StringToInt(password, &dummy_value);
392 std::string hashed_password = CalculateHash(
393 password, system_salt, chromeos::Key::KEY_TYPE_SALTED_SHA256_TOP_HALF);
394
Jialiu Linf99b788b2018-01-17 23:01:21395 // Used for GAIA password reuse detection.
396 password_manager::SyncPasswordData sync_password_data(
Jacob Dufault8876ba82018-03-27 22:55:43397 base::UTF8ToUTF16(password), false /*force_update*/);
Jialiu Linf99b788b2018-01-17 23:01:21398
Sarah Hu069eea12017-09-08 01:28:40399 PrefService* prefs =
400 Shell::Get()->session_controller()->GetLastActiveUserPrefService();
401 if (is_pin && prefs) {
402 hashed_password =
403 CalculateHash(password, prefs->GetString(prefs::kQuickUnlockPinSalt),
404 chromeos::Key::KEY_TYPE_SALTED_PBKDF2_AES256_1234);
405 }
406
Roman Sorokinc5590012017-09-28 00:48:29407 if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY && !is_pin) {
408 // Try to get kerberos TGT while we have user's password typed on the lock
409 // screen. Using invalid/bad password is fine. Failure to get TGT here is OK
410 // - that could mean e.g. Active Directory server is not reachable.
411 // AuthPolicyCredentialsManager regularly checks TGT status inside the user
412 // session.
413 chromeos::AuthPolicyLoginHelper::TryAuthenticateUser(
414 account_id.GetUserEmail(), account_id.GetObjGuid(), password);
415 }
416
Sarah Hue0e01a52017-10-25 20:29:30417 Shell::Get()->metrics()->login_metrics_recorder()->SetAuthMethod(
418 is_pin ? LoginMetricsRecorder::AuthMethod::kPin
419 : LoginMetricsRecorder::AuthMethod::kPassword);
Jacob Dufaultb7a2d842017-12-01 23:21:15420 login_screen_client_->AuthenticateUser(
Jialiu Linf99b788b2018-01-17 23:01:21421 account_id, hashed_password, sync_password_data, is_pin,
Jacob Dufaultb7a2d842017-12-01 23:21:15422 base::BindOnce(&LoginScreenController::OnAuthenticateComplete,
423 weak_factory_.GetWeakPtr(), base::Passed(&callback)));
jdufaulteb4c9f1e2017-06-08 23:08:30424}
425
Jacob Dufaultb7a2d842017-12-01 23:21:15426void LoginScreenController::OnAuthenticateComplete(
427 OnAuthenticateCallback callback,
428 bool success) {
Jacob Dufault8876ba82018-03-27 22:55:43429 authentication_stage_ = AuthenticationStage::kUserCallback;
Jacob Dufaultb7a2d842017-12-01 23:21:15430 std::move(callback).Run(success);
Jacob Dufault8876ba82018-03-27 22:55:43431 authentication_stage_ = AuthenticationStage::kIdle;
xiaoyinh2bbdd102017-05-18 23:29:42432}
433
Jacob Dufaultffd9b0d2017-11-15 23:07:16434LoginDataDispatcher* LoginScreenController::DataDispatcher() const {
Jacob Dufault40623d52017-09-15 17:22:53435 if (!ash::LockScreen::IsShown())
436 return nullptr;
437 return ash::LockScreen::Get()->data_dispatcher();
438}
439
Jacob Dufaultcbc1ee02018-02-28 18:38:54440void LoginScreenController::OnShow() {
441 SetSystemTrayVisibility(SystemTrayVisibility::kPrimary);
Jacob Dufaultc06d6ca2018-04-24 23:49:17442 if (authentication_stage_ != AuthenticationStage::kIdle) {
443 AuthenticationStage authentication_stage = authentication_stage_;
444 base::debug::Alias(&authentication_stage);
445 LOG(FATAL) << "Unexpected authentication stage "
446 << static_cast<int>(authentication_stage_);
447 }
Jacob Dufaultcbc1ee02018-02-28 18:38:54448}
449
xiaoyinh2bbdd102017-05-18 23:29:42450} // namespace ash