Index: chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.cc |
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.cc b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..161651fd9ad8688e6eceb23dc9a79932d9f4d7b5 |
--- /dev/null |
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.cc |
@@ -0,0 +1,132 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/bind.h" |
+#include "base/message_loop/message_loop.h" |
+#include "chrome/browser/chrome_notification_types.h" |
+#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.h" |
+#include "chrome/browser/chromeos/login/lock/screen_locker.h" |
+#include "chrome/browser/signin/screenlock_bridge.h" |
+#include "chrome/grit/generated_resources.h" |
+#include "chromeos/dbus/dbus_thread_manager.h" |
+#include "chromeos/dbus/session_manager_client.h" |
+#include "chromeos/login/auth/auth_status_consumer.h" |
+#include "chromeos/login/auth/user_context.h" |
+#include "content/public/browser/notification_details.h" |
+#include "content/public/browser/notification_observer.h" |
+#include "content/public/browser/notification_registrar.h" |
+#include "content/public/browser/notification_service.h" |
+#include "ui/base/l10n/l10n_util.h" |
+ |
+namespace chromeos { |
+ |
+namespace { |
+ |
+void EndReauthAttempt(); |
+ |
+// Performs the actual reauth flow and returns the user context it obtains. |
+class ReauthHandler : public content::NotificationObserver, |
+ public chromeos::AuthStatusConsumer { |
+ public: |
+ explicit ReauthHandler(EasyUnlockReauth::UserContextCallback callback) |
+ : callback_(callback) {} |
+ |
+ virtual ~ReauthHandler() {} |
+ |
+ bool Start() { |
+ ScreenLocker* screen_locker = ScreenLocker::default_screen_locker(); |
+ if (screen_locker && screen_locker->locked()) { |
+ DCHECK(false) << "Screen should not be locked when attempting reauth."; |
tbarzic
2014/11/01 23:21:44
notreached instead of DCHECK(false)
Tim Song
2014/11/03 19:10:43
Done.
|
+ return false; |
+ } |
+ |
+ // Only primary profile's can set up Easy Unlock right now. |
tbarzic
2014/11/01 23:21:44
s/profile's/user
Tim Song
2014/11/03 19:10:43
Done.
|
+ user_manager::UserManager* user_manager = user_manager::UserManager::Get(); |
+ if (user_manager->GetPrimaryUser() != user_manager->GetActiveUser() || |
+ user_manager->GetUnlockUsers().size() != 1) { |
+ DCHECK(false) << "Only primary users in non-multiprofile sessions are " |
tbarzic
2014/10/31 18:24:09
no DCHECK; afaik this is realistic possibility.
Tim Song
2014/11/01 03:16:52
This should be rare, so let's fall back to the har
xiyuan
2014/11/01 03:51:37
I think Toni meant to replace the DCHECK with a LO
Tim Song
2014/11/01 04:57:39
Done. Sorry, I misread this comment.
|
+ << "currently supported for reauth."; |
+ return false; |
+ } |
+ |
+ notification_registrar_.Add(this, |
+ chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED, |
+ content::NotificationService::AllSources()); |
+ |
+ SessionManagerClient* session_manager = |
+ chromeos::DBusThreadManager::Get()->GetSessionManagerClient(); |
+ session_manager->RequestLockScreen(); |
+ return true; |
+ } |
+ |
+ // content::NotificationObserver |
+ void Observe(int type, |
+ const content::NotificationSource& source, |
+ const content::NotificationDetails& details) { |
+ CHECK(type == chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED); |
+ bool is_screen_locked = *content::Details<bool>(details).ptr(); |
+ DCHECK(is_screen_locked); |
+ notification_registrar_.RemoveAll(); |
+ |
+ // TODO(tengs): Add an explicit reauth state to the locker and account |
+ // picker, so we can customize the UI. |
+ ScreenLocker* screen_locker = ScreenLocker::default_screen_locker(); |
+ screen_locker->SetLoginStatusConsumer(this); |
+ |
+ // Show tooltip explaining reauth. |
+ ScreenlockBridge::UserPodCustomIconOptions icon_options; |
+ icon_options.SetIcon(ScreenlockBridge::USER_POD_CUSTOM_ICON_NONE); |
+ icon_options.SetTooltip( |
+ l10n_util::GetStringUTF16( |
+ IDS_SMART_LOCK_SCREENLOCK_TOOLTIP_HARDLOCK_REAUTH_USER), |
+ true); |
+ |
+ const user_manager::UserList& lock_users = screen_locker->users(); |
+ DCHECK(lock_users.size() == 1); |
+ ScreenlockBridge::Get()->lock_handler()->ShowUserPodCustomIcon( |
+ lock_users[0]->email(), icon_options); |
+ } |
+ |
+ // chromeos::AuthStatusConsumer: |
+ virtual void OnAuthSuccess( |
+ const chromeos::UserContext& user_context) override { |
+ callback_.Run(user_context); |
+ // Schedule deletion. |
+ base::MessageLoopForUI::current()->PostTask(FROM_HERE, |
+ base::Bind(&EndReauthAttempt)); |
+ } |
+ |
+ virtual void OnAuthFailure(const chromeos::AuthFailure& error) override {} |
+ |
+ private: |
+ content::NotificationRegistrar notification_registrar_; |
+ EasyUnlockReauth::UserContextCallback callback_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ReauthHandler); |
+}; |
+ |
+ReauthHandler* g_reauth_handler = NULL; |
+ |
+void EndReauthAttempt() { |
+ DCHECK(base::MessageLoopForUI::IsCurrent()); |
+ DCHECK(g_reauth_handler); |
+ if (g_reauth_handler) |
+ delete g_reauth_handler; |
+ g_reauth_handler = NULL; |
+} |
+ |
+} // namespace |
+ |
+// static. |
+bool EasyUnlockReauth::ReauthForUserContext( |
+ base::Callback<void(const UserContext&)> callback) { |
+ DCHECK(base::MessageLoopForUI::IsCurrent()); |
+ if (g_reauth_handler) |
+ return false; |
+ |
+ g_reauth_handler = new ReauthHandler(callback); |
+ return g_reauth_handler->Start(); |
+} |
+ |
+} // namespace chromeos |