Chromium Code Reviews| 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..d1bc7ec2229fd69f0b0cb89f3c58199dc26f23dc |
| --- /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."; |
| + return false; |
| + } |
| + |
| + // Only primary profile's can set up Easy Unlock right now. |
|
tbarzic
2014/11/01 23:21:45
nit: I'd remove the comment; this is explained in
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) { |
| + LOG(WARNING) << "Only primary users in non-multiprofile sessions are " |
| + << "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) |
|
tbarzic
2014/11/01 23:21:45
since you have DCHECK just before this, I'd remove
Tim Song
2014/11/03 19:10:43
Done.
|
| + 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 |