summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortengs <tengs@chromium.org>2014-11-03 17:42:32 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-04 01:42:52 +0000
commit174ab92a101d02bce1301d8fdc8ec15ec5557137 (patch)
treee993504239c95c5d2b7fb214ca7a6c61b0e03030
parent72641dc61a1966ccc9e63cee95aec1e6136044a2 (diff)
downloadchromium_src-174ab92a101d02bce1301d8fdc8ec15ec5557137.zip
chromium_src-174ab92a101d02bce1301d8fdc8ec15ec5557137.tar.gz
chromium_src-174ab92a101d02bce1301d8fdc8ec15ec5557137.tar.bz2
Reauthenticate the user before launching Smart Lock setup app.
The reauth is needed to acquire the user's password to add a new cryptohome key for sign-in. BUG=409427 Review URL: https://codereview.chromium.org/668213003 Cr-Commit-Position: refs/heads/master@{#302541}
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.cc130
-rw-r--r--chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.h31
-rw-r--r--chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.cc55
-rw-r--r--chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.h53
-rw-r--r--chrome/browser/signin/easy_unlock_service.cc4
-rw-r--r--chrome/browser/signin/easy_unlock_service.h12
-rw-r--r--chrome/browser/signin/easy_unlock_service_regular.cc81
-rw-r--r--chrome/browser/signin/easy_unlock_service_regular.h16
-rw-r--r--chrome/browser/signin/screenlock_bridge.cc3
-rw-r--r--chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc2
-rw-r--r--chrome/chrome_browser_chromeos.gypi4
-rw-r--r--ui/login/account_picker/user_pod_row.js17
13 files changed, 395 insertions, 16 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 07f06be..3a3bc47 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -14889,6 +14889,9 @@ Do you accept?
<message name="IDS_EASY_UNLOCK_SCREENLOCK_TOOLTIP_LOGIN_FAILURE" desc="Tooltip text shown on a user's lock screen when Smart Lock signin attempt fails.">
Smart Lock couldn't verify your account. Type your password to enter.
</message>
+ <message name="IDS_SMART_LOCK_SCREENLOCK_TOOLTIP_HARDLOCK_REAUTH_USER" desc="Tooltip text shown on a user's lock screen pod to reauthenticate the user before setting up Smart Lock. A password has to be entered to unlock the device.">
+ To set up Chrome Smart Lock, Google needs to make sure it's you--type your password to get started.
+ </message>
<message name="IDS_EASY_UNLOCK_SCREENLOCK_USER_POD_AUTH_VALUE" desc="Message on lock screen user pod shown in place of password field when Easy Unlock is enabled and a phone that can unlock the Chromebook is detected in proximity.">
Click to enter
</message>
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 0000000..a19360d
--- /dev/null
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.cc
@@ -0,0 +1,130 @@
+// 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()) {
+ NOTREACHED();
+ return false;
+ }
+
+ 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) override {
+ 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);
+ 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
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.h b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.h
new file mode 100644
index 0000000..041dc87
--- /dev/null
+++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.h
@@ -0,0 +1,31 @@
+// 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_REAUTH_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_REAUTH_H_
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "base/memory/scoped_ptr.h"
+
+namespace chromeos {
+
+class UserContext;
+
+// Responsible for locking the screen and reauthenticating the user so we can
+// create new cryptohome keys for passwordless sign-in.
+class EasyUnlockReauth {
+ public:
+ typedef base::Callback<void(const UserContext&)> UserContextCallback;
+
+ // Launches the reauth screen to get the user context. If the screen fails
+ // for some reason, then this function will return false.
+ static bool ReauthForUserContext(UserContextCallback callback);
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(EasyUnlockReauth);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_REAUTH_H_
diff --git a/chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.cc b/chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.cc
new file mode 100644
index 0000000..41283cc
--- /dev/null
+++ b/chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.cc
@@ -0,0 +1,55 @@
+// 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 "chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/task_runner.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "chromeos/login/auth/user_context.h"
+
+namespace chromeos {
+
+namespace {
+
+// The number of minutes that the user context will be stored.
+const int64 kUserContextTimeToLiveMinutes = 10;
+
+} // namespace
+
+ShortLivedUserContext::ShortLivedUserContext(
+ const UserContext& user_context,
+ apps::AppLifetimeMonitor* app_lifetime_monitor,
+ base::TaskRunner* task_runner)
+ : user_context_(new UserContext(user_context)),
+ app_lifetime_monitor_(app_lifetime_monitor),
+ weak_ptr_factory_(this) {
+ app_lifetime_monitor_->AddObserver(this);
+
+ task_runner->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&ShortLivedUserContext::Reset, weak_ptr_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMinutes(kUserContextTimeToLiveMinutes));
+}
+
+ShortLivedUserContext::~ShortLivedUserContext() {
+ Reset();
+}
+
+void ShortLivedUserContext::Reset() {
+ if (user_context_.get()) {
+ user_context_->ClearSecrets();
+ user_context_.reset();
+ app_lifetime_monitor_->RemoveObserver(this);
+ }
+}
+
+void ShortLivedUserContext::OnAppDeactivated(Profile* profile,
+ const std::string& app_id) {
+ if (app_id == extension_misc::kEasyUnlockAppId)
+ Reset();
+}
+
+} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.h b/chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.h
new file mode 100644
index 0000000..7e4bdabc
--- /dev/null
+++ b/chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.h
@@ -0,0 +1,53 @@
+// 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_SHORT_LIVED_USER_CONTEXT_H_
+#define CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_SHORT_LIVED_USER_CONTEXT_H_
+
+#include "apps/app_lifetime_monitor.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+
+namespace base {
+class TaskRunner;
+}
+
+namespace chromeos {
+
+class UserContext;
+
+// Stores the UserContext of an authentication operation on the sign-in/lock
+// screen, which is used to generate the keys for Easy Sign-in.
+// The lifetime of the user context is bound the the setup app window. As a
+// fail-safe, the user context will also be deleted after a set period of time
+// in case the app is left open indefintely.
+class ShortLivedUserContext : public apps::AppLifetimeMonitor::Observer {
+ public:
+ ShortLivedUserContext(const UserContext& user_context,
+ apps::AppLifetimeMonitor* app_lifetime_monitor,
+ base::TaskRunner* task_runner);
+ virtual ~ShortLivedUserContext();
+
+ // The UserContext returned here can be NULL if its time-to-live has expired.
+ UserContext* user_context() { return user_context_.get(); }
+
+ private:
+ void Reset();
+
+ // apps::AppLifetimeMonitor::Observer:
+ virtual void OnAppDeactivated(Profile* profile,
+ const std::string& app_id) override;
+
+ scoped_ptr<UserContext> user_context_;
+
+ apps::AppLifetimeMonitor* app_lifetime_monitor_;
+
+ base::WeakPtrFactory<ShortLivedUserContext> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ShortLivedUserContext);
+};
+
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_SHORT_LIVED_USER_CONTEXT_H_
diff --git a/chrome/browser/signin/easy_unlock_service.cc b/chrome/browser/signin/easy_unlock_service.cc
index cb498dd..6144119 100644
--- a/chrome/browser/signin/easy_unlock_service.cc
+++ b/chrome/browser/signin/easy_unlock_service.cc
@@ -383,7 +383,7 @@ void EasyUnlockService::CheckCryptohomeKeysAndMaybeHardlock() {
chromeos::EasyUnlockKeyManager::RemoteDeviceListToDeviceDataList(
*device_list, &parsed_paired);
for (const auto& device_key_data : parsed_paired)
- paired_devices.insert(device_key_data.public_key);
+ paired_devices.insert(device_key_data.psk);
}
if (paired_devices.empty()) {
SetHardlockState(EasyUnlockScreenlockStateHandler::NO_PAIRING);
@@ -618,7 +618,7 @@ void EasyUnlockService::OnCryptohomeKeysFetchedForChecking(
std::set<std::string> devices_in_cryptohome;
for (const auto& device_key_data : key_data_list)
- devices_in_cryptohome.insert(device_key_data.public_key);
+ devices_in_cryptohome.insert(device_key_data.psk);
if (paired_devices != devices_in_cryptohome ||
GetHardlockState() == EasyUnlockScreenlockStateHandler::NO_PAIRING) {
diff --git a/chrome/browser/signin/easy_unlock_service.h b/chrome/browser/signin/easy_unlock_service.h
index 1f256a1..ade435b 100644
--- a/chrome/browser/signin/easy_unlock_service.h
+++ b/chrome/browser/signin/easy_unlock_service.h
@@ -215,6 +215,12 @@ class EasyUnlockService : public KeyedService {
return screenlock_state_handler_.get();
}
+ // Saves hardlock state for the given user. Update UI if the currently
+ // associated user is the same.
+ void SetHardlockStateForUser(
+ const std::string& user_id,
+ EasyUnlockScreenlockStateHandler::HardlockState state);
+
private:
// A class to detect whether a bluetooth adapter is present.
class BluetoothDetector;
@@ -231,12 +237,6 @@ class EasyUnlockService : public KeyedService {
// Callback when Bluetooth adapter present state changes.
void OnBluetoothAdapterPresentChanged();
- // Saves hardlock state for the given user. Update UI if the currently
- // associated user is the same.
- void SetHardlockStateForUser(
- const std::string& user_id,
- EasyUnlockScreenlockStateHandler::HardlockState state);
-
#if defined(OS_CHROMEOS)
// Callback for get key operation from CheckCryptohomeKeysAndMaybeHardlock.
void OnCryptohomeKeysFetchedForChecking(
diff --git a/chrome/browser/signin/easy_unlock_service_regular.cc b/chrome/browser/signin/easy_unlock_service_regular.cc
index 870d663..fb027f3 100644
--- a/chrome/browser/signin/easy_unlock_service_regular.cc
+++ b/chrome/browser/signin/easy_unlock_service_regular.cc
@@ -18,9 +18,15 @@
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
+#include "content/public/browser/browser_thread.h"
#include "extensions/browser/extension_system.h"
#if defined(OS_CHROMEOS)
+#include "apps/app_lifetime_monitor_factory.h"
+#include "base/thread_task_runner_handle.h"
+#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h"
+#include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_reauth.h"
+#include "chrome/browser/chromeos/login/session/user_session_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "components/user_manager/user_manager.h"
#endif
@@ -40,7 +46,8 @@ const char kKeyPhoneId[] = "permitRecord.id";
EasyUnlockServiceRegular::EasyUnlockServiceRegular(Profile* profile)
: EasyUnlockService(profile),
- turn_off_flow_status_(EasyUnlockService::IDLE) {
+ turn_off_flow_status_(EasyUnlockService::IDLE),
+ weak_ptr_factory_(this) {
}
EasyUnlockServiceRegular::~EasyUnlockServiceRegular() {
@@ -55,6 +62,52 @@ std::string EasyUnlockServiceRegular::GetUserEmail() const {
}
void EasyUnlockServiceRegular::LaunchSetup() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+#if defined(OS_CHROMEOS)
+ // Force the user to reauthenticate by showing a modal overlay (similar to the
+ // lock screen). The password obtained from the reauth is cached for a short
+ // period of time and used to create the cryptohome keys for sign-in.
+ if (short_lived_user_context_ && short_lived_user_context_->user_context()) {
+ OpenSetupApp();
+ } else {
+ bool reauth_success = chromeos::EasyUnlockReauth::ReauthForUserContext(
+ base::Bind(&EasyUnlockServiceRegular::OnUserContextFromReauth,
+ weak_ptr_factory_.GetWeakPtr()));
+ if (!reauth_success)
+ OpenSetupApp();
+ }
+#else
+ OpenSetupApp();
+#endif
+}
+
+#if defined(OS_CHROMEOS)
+void EasyUnlockServiceRegular::OnUserContextFromReauth(
+ const chromeos::UserContext& user_context) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ short_lived_user_context_.reset(new chromeos::ShortLivedUserContext(
+ user_context, apps::AppLifetimeMonitorFactory::GetForProfile(profile()),
+ base::ThreadTaskRunnerHandle::Get().get()));
+
+ OpenSetupApp();
+}
+
+void EasyUnlockServiceRegular::OnKeysRefreshedForSetDevices(bool success) {
+ // If the keys were refreshed successfully, the hardlock state should be
+ // cleared, so Smart Lock can be used normally. Otherwise, we fall back to
+ // a hardlock state to force the user to type in their credentials again.
+ if (success) {
+ SetHardlockStateForUser(GetUserEmail(),
+ EasyUnlockScreenlockStateHandler::NO_HARDLOCK);
+ }
+
+ // Even if the keys refresh suceeded, we still fetch the cryptohome keys as a
+ // sanity check.
+ CheckCryptohomeKeysAndMaybeHardlock();
+}
+#endif
+
+void EasyUnlockServiceRegular::OpenSetupApp() {
ExtensionService* service =
extensions::ExtensionSystem::Get(profile())->extension_service();
const extensions::Extension* extension =
@@ -103,7 +156,29 @@ void EasyUnlockServiceRegular::SetRemoteDevices(
DictionaryPrefUpdate pairing_update(profile()->GetPrefs(),
prefs::kEasyUnlockPairing);
pairing_update->SetWithoutPathExpansion(kKeyDevices, devices.DeepCopy());
+
+#if defined(OS_CHROMEOS)
+ // TODO(tengs): Investigate if we can determine if the remote devices were set
+ // from sync or from the setup app.
+ if (short_lived_user_context_ && short_lived_user_context_->user_context() &&
+ !devices.empty()) {
+ // We may already have the password cached, so proceed to create the
+ // cryptohome keys for sign-in or the system will be hardlocked.
+ chromeos::UserContext* user_context =
+ short_lived_user_context_->user_context();
+ chromeos::EasyUnlockKeyManager* key_manager =
+ chromeos::UserSessionManager::GetInstance()->GetEasyUnlockKeyManager();
+
+ key_manager->RefreshKeys(
+ *user_context, devices,
+ base::Bind(&EasyUnlockServiceRegular::OnKeysRefreshedForSetDevices,
+ weak_ptr_factory_.GetWeakPtr()));
+ } else {
+ CheckCryptohomeKeysAndMaybeHardlock();
+ }
+#else
CheckCryptohomeKeysAndMaybeHardlock();
+#endif
}
void EasyUnlockServiceRegular::ClearRemoteDevices() {
@@ -184,6 +259,10 @@ void EasyUnlockServiceRegular::InitializeInternal() {
}
void EasyUnlockServiceRegular::ShutdownInternal() {
+#if defined(OS_CHROMEOS)
+ short_lived_user_context_.reset();
+#endif
+
turn_off_flow_.reset();
turn_off_flow_status_ = EasyUnlockService::IDLE;
registrar_.RemoveAll();
diff --git a/chrome/browser/signin/easy_unlock_service_regular.h b/chrome/browser/signin/easy_unlock_service_regular.h
index 749b583..3a48585 100644
--- a/chrome/browser/signin/easy_unlock_service_regular.h
+++ b/chrome/browser/signin/easy_unlock_service_regular.h
@@ -12,6 +12,10 @@
#include "base/prefs/pref_change_registrar.h"
#include "chrome/browser/signin/easy_unlock_service.h"
+#if defined(OS_CHROMEOS)
+#include "chrome/browser/chromeos/login/easy_unlock/short_lived_user_context.h"
+#endif
+
namespace base {
class DictionaryValue;
class ListValue;
@@ -50,6 +54,9 @@ class EasyUnlockServiceRegular : public EasyUnlockService {
void ShutdownInternal() override;
bool IsAllowedInternal() override;
+ // Opens the component packaged app responsible for setting up Smart Lock.
+ void OpenSetupApp();
+
// Callback when the controlling pref changes.
void OnPrefsChanged();
@@ -59,11 +66,20 @@ class EasyUnlockServiceRegular : public EasyUnlockService {
// Callback invoked when turn off flow has finished.
void OnTurnOffFlowFinished(bool success);
+#if defined(OS_CHROMEOS)
+ void OnUserContextFromReauth(const chromeos::UserContext& user_context);
+ void OnKeysRefreshedForSetDevices(bool success);
+
+ scoped_ptr<chromeos::ShortLivedUserContext> short_lived_user_context_;
+#endif
+
PrefChangeRegistrar registrar_;
TurnOffFlowStatus turn_off_flow_status_;
scoped_ptr<EasyUnlockToggleFlow> turn_off_flow_;
+ base::WeakPtrFactory<EasyUnlockServiceRegular> weak_ptr_factory_;
+
DISALLOW_COPY_AND_ASSIGN(EasyUnlockServiceRegular);
};
diff --git a/chrome/browser/signin/screenlock_bridge.cc b/chrome/browser/signin/screenlock_bridge.cc
index 5fb5192..c2d7224 100644
--- a/chrome/browser/signin/screenlock_bridge.cc
+++ b/chrome/browser/signin/screenlock_bridge.cc
@@ -62,9 +62,6 @@ scoped_ptr<base::DictionaryValue>
ScreenlockBridge::UserPodCustomIconOptions::ToDictionaryValue() const {
scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue());
std::string icon_id = GetIdForIcon(icon_);
- if (icon_id.empty())
- return result.Pass();
-
result->SetString("id", icon_id);
if (!tooltip_.empty()) {
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 6c5f84b..2cfb24d 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -1242,10 +1242,10 @@ void SigninScreenHandler::HandleAccountPickerReady() {
is_account_picker_showing_first_time_ = true;
gaia_screen_handler_->MaybePreloadAuthExtension();
+ ScreenlockBridge::Get()->SetLockHandler(this);
if (ScreenLocker::default_screen_locker()) {
ScreenLocker::default_screen_locker()->delegate()->OnLockWebUIReady();
}
- ScreenlockBridge::Get()->SetLockHandler(this);
if (delegate_)
delegate_->OnSigninScreenReady();
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi
index b7bbae8..65b6ee1 100644
--- a/chrome/chrome_browser_chromeos.gypi
+++ b/chrome/chrome_browser_chromeos.gypi
@@ -429,10 +429,14 @@
'browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h',
'browser/chromeos/login/easy_unlock/easy_unlock_metrics.cc',
'browser/chromeos/login/easy_unlock/easy_unlock_metrics.h',
+ 'browser/chromeos/login/easy_unlock/easy_unlock_reauth.cc',
+ 'browser/chromeos/login/easy_unlock/easy_unlock_reauth.h',
'browser/chromeos/login/easy_unlock/easy_unlock_remove_keys_operation.cc',
'browser/chromeos/login/easy_unlock/easy_unlock_remove_keys_operation.h',
'browser/chromeos/login/easy_unlock/easy_unlock_types.cc',
'browser/chromeos/login/easy_unlock/easy_unlock_types.h',
+ 'browser/chromeos/login/easy_unlock/short_lived_user_context.cc',
+ 'browser/chromeos/login/easy_unlock/short_lived_user_context.h',
'browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.cc',
'browser/chromeos/login/easy_unlock/easy_unlock_user_login_flow.h',
'browser/chromeos/login/enrollment/auto_enrollment_check_screen.cc',
diff --git a/ui/login/account_picker/user_pod_row.js b/ui/login/account_picker/user_pod_row.js
index 5526f91..fd3778d 100644
--- a/ui/login/account_picker/user_pod_row.js
+++ b/ui/login/account_picker/user_pod_row.js
@@ -200,6 +200,13 @@ cr.define('login', function() {
__proto__: HTMLDivElement.prototype,
/**
+ * The id of the icon being shown.
+ * @type {string}
+ * @private
+ */
+ iconId_: '',
+
+ /**
* Tooltip to be shown when the user hovers over the icon. The icon
* properties may be set so the tooltip is shown automatically when the icon
* is updated. The tooltip is shown in a bubble attached to the icon
@@ -286,6 +293,7 @@ cr.define('login', function() {
* one of the ids listed in {@code UserPodCustomIcon.ICONS}.
*/
setIcon: function(id) {
+ this.iconId_ = id;
UserPodCustomIcon.ICONS.forEach(function(icon) {
this.iconElement.classList.toggle(icon.class, id == icon.id);
}, this);
@@ -477,7 +485,9 @@ cr.define('login', function() {
bubbleContent.textContent = this.tooltip_;
/** @const */ var BUBBLE_OFFSET = CUSTOM_ICON_CONTAINER_SIZE / 2;
- /** @const */ var BUBBLE_PADDING = 8;
+ // TODO(tengs): Introduce a special reauth state for the account picker,
+ // instead of showing the tooltip bubble here (crbug.com/409427).
+ /** @const */ var BUBBLE_PADDING = 8 + (this.iconId_ ? 0 : 23);
$('bubble').showContentForElement(this,
cr.ui.Bubble.Attachment.RIGHT,
bubbleContent,
@@ -2265,10 +2275,11 @@ cr.define('login', function() {
return;
}
- if (!icon.id)
+ if (!icon.id && !icon.tooltip)
return;
- pod.customIconElement.setIcon(icon.id);
+ if (icon.id)
+ pod.customIconElement.setIcon(icon.id);
if (icon.hardlockOnClick) {
pod.customIconElement.setInteractive(