194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Copyright (c) 2012 The Chromium Authors. All rights reserved.
294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Use of this source code is governed by a BSD-style license that can be
394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// found in the LICENSE file.
494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/login/existing_user_controller.h"
694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <vector>
894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/bind.h"
1094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/bind_helpers.h"
1194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/callback.h"
1294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/command_line.h"
1394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/logging.h"
1494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/memory/scoped_ptr.h"
1594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/message_loop/message_loop.h"
1694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/metrics/histogram.h"
1794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/prefs/pref_service.h"
1894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/strings/string_util.h"
1994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/strings/stringprintf.h"
2094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/strings/utf_string_conversions.h"
2194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/values.h"
2294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "base/version.h"
2394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/accessibility/accessibility_events.h"
2494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/browser_process.h"
2594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/browser_process_platform_part.h"
2694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chrome_notification_types.h"
2794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
2894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/boot_times_loader.h"
2994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/customization_document.h"
3094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/first_run/first_run.h"
31a2d838a542c34d2887a0ec1fafa5f47566d595e9Nick Kralevich#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
3294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/login/helper.h"
3394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/login/login_utils.h"
3494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/login/startup_utils.h"
3594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/login/ui/login_display_host.h"
3694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/login/user_flow.h"
3794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
3894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/login/wizard_controller.h"
3994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
4094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/policy/device_local_account.h"
4194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
4294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/profiles/profile_helper.h"
4394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/chromeos/settings/cros_settings.h"
4494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/prefs/session_startup_pref.h"
4594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/signin/easy_unlock_service.h"
4694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
4794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/common/chrome_switches.h"
4894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/common/chrome_version_info.h"
4994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/common/pref_names.h"
5094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/common/url_constants.h"
5194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chrome/grit/generated_resources.h"
5294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chromeos/chromeos_switches.h"
5394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chromeos/dbus/dbus_thread_manager.h"
5494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chromeos/dbus/power_manager_client.h"
5594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chromeos/dbus/session_manager_client.h"
5694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chromeos/login/user_names.h"
5794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "chromeos/settings/cros_settings_names.h"
58a2d838a542c34d2887a0ec1fafa5f47566d595e9Nick Kralevich#include "components/google/core/browser/google_util.h"
5994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "components/policy/core/common/cloud/cloud_policy_core.h"
6094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "components/policy/core/common/cloud/cloud_policy_store.h"
6194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "components/policy/core/common/policy_map.h"
62a2d838a542c34d2887a0ec1fafa5f47566d595e9Nick Kralevich#include "components/policy/core/common/policy_service.h"
6394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "components/policy/core/common/policy_types.h"
6494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "components/user_manager/user_manager.h"
6594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "components/user_manager/user_type.h"
6694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "content/public/browser/browser_thread.h"
6794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "content/public/browser/notification_service.h"
6894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "content/public/browser/notification_types.h"
6994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "content/public/browser/user_metrics.h"
7094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "google_apis/gaia/gaia_auth_util.h"
7194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "google_apis/gaia/google_service_auth_error.h"
7294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "net/http/http_auth_cache.h"
7394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "net/http/http_network_session.h"
7494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "net/http/http_transaction_factory.h"
7594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "net/url_request/url_request_context.h"
7694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "net/url_request/url_request_context_getter.h"
7794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "policy/policy_constants.h"
7894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "ui/accessibility/ax_enums.h"
7994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "ui/base/l10n/l10n_util.h"
8094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include "ui/views/widget/widget.h"
8194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
8294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodnamespace chromeos {
8394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
8494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodnamespace {
8594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
8694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// URL for account creation.
8794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodconst char kCreateAccountURL[] =
8894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    "https://accounts.google.com/NewAccount?service=mail";
8994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
9094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// ChromeVox tutorial URL (used in place of "getting started" url when
9194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// accessibility is enabled).
9294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodconst char kChromeVoxTutorialURLPattern[] =
9394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    "http://www.chromevox.com/tutorial/index.html?lang=%s";
9494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
9594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Delay for transferring the auth cache to the system profile.
9694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodconst long int kAuthCacheTransferDelayMs = 2000;
9794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
9894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Delay for restarting the ui if safe-mode login has failed.
9994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodconst long int kSafeModeRestartUiDelayMs = 30000;
10094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
10194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Makes a call to the policy subsystem to reload the policy when we detect
10294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// authentication change.
10394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid RefreshPoliciesOnUIThread() {
10494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (g_browser_process->policy_service())
10594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    g_browser_process->policy_service()->RefreshPolicies(base::Closure());
10694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
10794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
10894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Copies any authentication details that were entered in the login profile in
10994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// the mail profile to make sure all subsystems of Chrome can access the network
11094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// with the provided authentication which are possibly for a proxy server.
11194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid TransferContextAuthenticationsOnIOThread(
11294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    net::URLRequestContextGetter* default_profile_context_getter,
11394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    net::URLRequestContextGetter* browser_process_context_getter) {
11494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  net::HttpAuthCache* new_cache =
11594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      browser_process_context_getter->GetURLRequestContext()->
11694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      http_transaction_factory()->GetSession()->http_auth_cache();
11794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  net::HttpAuthCache* old_cache =
11894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      default_profile_context_getter->GetURLRequestContext()->
11994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      http_transaction_factory()->GetSession()->http_auth_cache();
12094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  new_cache->UpdateAllFrom(*old_cache);
12194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  VLOG(1) << "Main request context populated with authentication data.";
12294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Last but not least tell the policy subsystem to refresh now as it might
12394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // have been stuck until now too.
12494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
12594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                   base::Bind(&RefreshPoliciesOnUIThread));
12694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
12794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
12894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Record UMA for Easy sign-in outcome.
12994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid RecordEasySignInOutcome(const std::string& user_id, bool success) {
13094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  EasyUnlockService* easy_unlock_service =
13194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      EasyUnlockService::Get(ProfileHelper::GetSigninProfile());
13294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (!easy_unlock_service)
13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
13494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  easy_unlock_service->RecordEasySignInOutcome(user_id, success);
13594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
13794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// Record UMA for password login of regular user when Easy sign-in is enabled.
13894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid RecordPasswordLoginEvent(const UserContext& user_context) {
13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  EasyUnlockService* easy_unlock_service =
14094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      EasyUnlockService::Get(ProfileHelper::GetSigninProfile());
14194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (user_context.GetUserType() == user_manager::USER_TYPE_REGULAR &&
14294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      user_context.GetAuthFlow() == UserContext::AUTH_FLOW_OFFLINE &&
14394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      easy_unlock_service) {
14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    easy_unlock_service->RecordPasswordLoginEvent(user_context.GetUserID());
14594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
14694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
14794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
14894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}  // namespace
14994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
15094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// static
15194afecf4b6f437b3ee9a076242402e421c6c07a6Mike LockwoodExistingUserController* ExistingUserController::current_controller_ = NULL;
15294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
15394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood////////////////////////////////////////////////////////////////////////////////
15494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// ExistingUserController, public:
15594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
15694afecf4b6f437b3ee9a076242402e421c6c07a6Mike LockwoodExistingUserController::ExistingUserController(LoginDisplayHost* host)
15794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    : auth_status_consumer_(NULL),
15894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      last_login_attempt_auth_flow_(UserContext::AUTH_FLOW_OFFLINE),
15994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      host_(host),
16094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      login_display_(host_->CreateLoginDisplay(this)),
16194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      num_login_attempts_(0),
16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      cros_settings_(CrosSettings::Get()),
16394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      offline_failed_(false),
16494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      is_login_in_progress_(false),
16594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      password_changed_(false),
16694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      auth_mode_(LoginPerformer::AUTH_MODE_EXTENSION),
16794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      do_auto_enrollment_(false),
16894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      signin_screen_ready_(false),
16994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      network_state_helper_(new login::NetworkStateHelper),
17094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      weak_factory_(this) {
17194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  DCHECK(current_controller_ == NULL);
17294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  current_controller_ = this;
17394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
17494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  registrar_.Add(this,
17594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
17694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 content::NotificationService::AllSources());
17794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  registrar_.Add(this,
17894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 chrome::NOTIFICATION_USER_LIST_CHANGED,
17994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 content::NotificationService::AllSources());
18094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  registrar_.Add(this,
18194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 chrome::NOTIFICATION_AUTH_SUPPLIED,
18294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 content::NotificationService::AllSources());
18394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  registrar_.Add(this,
18494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 chrome::NOTIFICATION_SESSION_STARTED,
18594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 content::NotificationService::AllSources());
18694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  show_user_names_subscription_ = cros_settings_->AddSettingsObserver(
187a2d838a542c34d2887a0ec1fafa5f47566d595e9Nick Kralevich      kAccountsPrefShowUserNamesOnSignIn,
18894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      base::Bind(&ExistingUserController::DeviceSettingsChanged,
18994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 base::Unretained(this)));
19094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  allow_new_user_subscription_ = cros_settings_->AddSettingsObserver(
19194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      kAccountsPrefAllowNewUser,
19294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      base::Bind(&ExistingUserController::DeviceSettingsChanged,
19394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 base::Unretained(this)));
19494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  allow_guest_subscription_ = cros_settings_->AddSettingsObserver(
19594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      kAccountsPrefAllowGuest,
19694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      base::Bind(&ExistingUserController::DeviceSettingsChanged,
19794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 base::Unretained(this)));
19894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  allow_supervised_user_subscription_ = cros_settings_->AddSettingsObserver(
19994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      kAccountsPrefSupervisedUsersEnabled,
20094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      base::Bind(&ExistingUserController::DeviceSettingsChanged,
20194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 base::Unretained(this)));
20294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  users_subscription_ = cros_settings_->AddSettingsObserver(
20394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      kAccountsPrefUsers,
20494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      base::Bind(&ExistingUserController::DeviceSettingsChanged,
20594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 base::Unretained(this)));
20694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  local_account_auto_login_id_subscription_ =
207a2d838a542c34d2887a0ec1fafa5f47566d595e9Nick Kralevich      cros_settings_->AddSettingsObserver(
20894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          kAccountsPrefDeviceLocalAccountAutoLoginId,
20994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          base::Bind(&ExistingUserController::ConfigurePublicSessionAutoLogin,
21094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     base::Unretained(this)));
211a2d838a542c34d2887a0ec1fafa5f47566d595e9Nick Kralevich  local_account_auto_login_delay_subscription_ =
21294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      cros_settings_->AddSettingsObserver(
21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          kAccountsPrefDeviceLocalAccountAutoLoginDelay,
21494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          base::Bind(&ExistingUserController::ConfigurePublicSessionAutoLogin,
21594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     base::Unretained(this)));
21694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::Init(const user_manager::UserList& users) {
21994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  time_init_ = base::Time::Now();
22094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  UpdateLoginDisplay(users);
22194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  ConfigurePublicSessionAutoLogin();
22294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
22394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
22494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::UpdateLoginDisplay(
22594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    const user_manager::UserList& users) {
22694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  bool show_users_on_signin;
22794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  user_manager::UserList filtered_users;
22894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
22994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  cros_settings_->GetBoolean(kAccountsPrefShowUserNamesOnSignIn,
23094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                             &show_users_on_signin);
23194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  for (user_manager::UserList::const_iterator it = users.begin();
23294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood       it != users.end();
23394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood       ++it) {
23494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // TODO(xiyuan): Clean user profile whose email is not in whitelist.
23594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    bool meets_supervised_requirements =
23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        (*it)->GetType() != user_manager::USER_TYPE_SUPERVISED ||
23794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        user_manager::UserManager::Get()->AreSupervisedUsersAllowed();
23894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    bool meets_whitelist_requirements =
23994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        LoginUtils::IsWhitelisted((*it)->email(), NULL) ||
24094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        (*it)->GetType() != user_manager::USER_TYPE_REGULAR;
24194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
24294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Public session accounts are always shown on login screen.
24394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    bool meets_show_users_requirements =
24494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        show_users_on_signin ||
24594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        (*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT;
24694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (meets_supervised_requirements &&
24794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        meets_whitelist_requirements &&
24894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        meets_show_users_requirements) {
24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      filtered_users.push_back(*it);
25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
25194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
25294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // If no user pods are visible, fallback to single new user pod which will
25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // have guest session link.
25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  bool show_guest;
25694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  cros_settings_->GetBoolean(kAccountsPrefAllowGuest, &show_guest);
25794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  show_users_on_signin |= !filtered_users.empty();
25894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  show_guest &= !filtered_users.empty();
25994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  bool show_new_user = true;
26094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->set_parent_window(GetNativeWindow());
26194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->Init(
26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      filtered_users, show_guest, show_users_on_signin, show_new_user);
26394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  host_->OnPreferencesChanged();
26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
26694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::DoAutoEnrollment() {
26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  do_auto_enrollment_ = true;
26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::ResumeLogin() {
27194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // This means the user signed-in, then auto-enrollment used his credentials
27294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // to enroll and succeeded.
27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  resume_login_callback_.Run();
27494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  resume_login_callback_.Reset();
27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
27794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood////////////////////////////////////////////////////////////////////////////////
27894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// ExistingUserController, content::NotificationObserver implementation:
27994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood//
28094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
28194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::Observe(
28294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    int type,
28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    const content::NotificationSource& source,
28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    const content::NotificationDetails& details) {
28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (type == chrome::NOTIFICATION_SESSION_STARTED) {
28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Stop listening to any notification once session has started.
28794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Sign in screen objects are marked for deletion with DeleteSoon so
28894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // make sure no object would be used after session has started.
28994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // http://crbug.com/125276
29094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    registrar_.RemoveAll();
29194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
29294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
29394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (type == chrome::NOTIFICATION_USER_LIST_CHANGED) {
29494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    DeviceSettingsChanged();
29594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
29694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
29794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (type == chrome::NOTIFICATION_AUTH_SUPPLIED) {
29894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Possibly the user has authenticated against a proxy server and we might
29994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // need the credentials for enrollment and other system requests from the
30094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // main |g_browser_process| request context (see bug
30194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // http://crosbug.com/24861). So we transfer any credentials to the global
30294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // request context here.
30394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // The issue we have here is that the NOTIFICATION_AUTH_SUPPLIED is sent
30494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // just after the UI is closed but before the new credentials were stored
30594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // in the profile. Therefore we have to give it some time to make sure it
30694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // has been updated before we copy it.
30794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    VLOG(1) << "Authentication was entered manually, possibly for proxyauth.";
30894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    scoped_refptr<net::URLRequestContextGetter> browser_process_context_getter =
30994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        g_browser_process->system_request_context();
31094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    Profile* signin_profile = ProfileHelper::GetSigninProfile();
31194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    scoped_refptr<net::URLRequestContextGetter> signin_profile_context_getter =
31294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        signin_profile->GetRequestContext();
31394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    DCHECK(browser_process_context_getter.get());
31494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    DCHECK(signin_profile_context_getter.get());
31594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    content::BrowserThread::PostDelayedTask(
31694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        content::BrowserThread::IO, FROM_HERE,
31794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        base::Bind(&TransferContextAuthenticationsOnIOThread,
31894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                   signin_profile_context_getter,
31994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                   browser_process_context_getter),
32094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        base::TimeDelta::FromMilliseconds(kAuthCacheTransferDelayMs));
32194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
32294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (type != chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED)
32394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
32494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->OnUserImageChanged(
32594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      *content::Details<user_manager::User>(details).ptr());
32694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
32794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
32894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood////////////////////////////////////////////////////////////////////////////////
32994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// ExistingUserController, private:
33094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
33194afecf4b6f437b3ee9a076242402e421c6c07a6Mike LockwoodExistingUserController::~ExistingUserController() {
33294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  LoginUtils::Get()->DelegateDeleted(this);
33394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
33494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (current_controller_ == this) {
33594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    current_controller_ = NULL;
33694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else {
33794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    NOTREACHED() << "More than one controller are alive.";
33894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
33994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  DCHECK(login_display_.get());
34094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
34194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
34294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood////////////////////////////////////////////////////////////////////////////////
34394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// ExistingUserController, LoginDisplay::Delegate implementation:
34494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood//
34594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
34694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::CancelPasswordChangedFlow() {
34794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_performer_.reset(NULL);
34894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(true);
34994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  StartPublicSessionAutoLoginTimer();
35094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
35194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
35294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::CreateAccount() {
35394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  content::RecordAction(base::UserMetricsAction("Login.CreateAccount"));
35494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  guest_mode_url_ = google_util::AppendGoogleLocaleParam(
35594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      GURL(kCreateAccountURL), g_browser_process->GetApplicationLocale());
35694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  LoginAsGuest();
35794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
35894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
35994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::CompleteLogin(const UserContext& user_context) {
36094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->set_signin_completed(true);
36194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (!host_) {
36294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Complete login event was generated already from UI. Ignore notification.
36394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
36494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
36594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
36694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Stop the auto-login timer when attempting login.
36794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  StopPublicSessionAutoLoginTimer();
36894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
36994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Disable UI while loading user profile.
37094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(false);
37194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
37294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (!time_init_.is_null()) {
37394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    base::TimeDelta delta = base::Time::Now() - time_init_;
37494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    UMA_HISTOGRAM_MEDIUM_TIMES("Login.PromptToCompleteLoginTime", delta);
37594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    time_init_ = base::Time();  // Reset to null.
37694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
37794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
37894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  host_->OnCompleteLogin();
37994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
38094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Do an ownership check now to avoid auto-enrolling if the device has
38194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // already been owned.
38294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  DeviceSettingsService::Get()->GetOwnershipStatusAsync(
38394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      base::Bind(&ExistingUserController::CompleteLoginInternal,
38494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 weak_factory_.GetWeakPtr(),
38594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 user_context));
38694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
38794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
38894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::CompleteLoginInternal(
38994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    const UserContext& user_context,
39094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    DeviceSettingsService::OwnershipStatus ownership_status) {
39194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Auto-enrollment must have made a decision by now. It's too late to enroll
39294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // if the protocol isn't done at this point.
39394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (do_auto_enrollment_ &&
39494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      ownership_status == DeviceSettingsService::OWNERSHIP_NONE) {
39594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    VLOG(1) << "Forcing auto-enrollment before completing login";
39694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // The only way to get out of the enrollment screen from now on is to either
39794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // complete enrollment, or opt-out of it. So this controller shouldn't force
39894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // enrollment again if it is reused for another sign-in.
39994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    do_auto_enrollment_ = false;
40094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    auto_enrollment_username_ = user_context.GetUserID();
40194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    resume_login_callback_ = base::Bind(
40294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        &ExistingUserController::PerformLogin,
40394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        weak_factory_.GetWeakPtr(),
40494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        user_context, LoginPerformer::AUTH_MODE_EXTENSION);
40594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    ShowEnrollmentScreen(true, user_context.GetUserID());
40694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Enable UI for the enrollment screen. SetUIEnabled(true) will post a
40794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // request to show the sign-in screen again when invoked at the sign-in
40894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // screen; invoke SetUIEnabled() after navigating to the enrollment screen.
40994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->SetUIEnabled(true);
41094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else {
41194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
41294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
41394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
41494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
41594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodbase::string16 ExistingUserController::GetConnectedNetworkName() {
41694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  return network_state_helper_->GetCurrentNetworkName();
41794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
41894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
41994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodbool ExistingUserController::IsSigninInProgress() const {
42094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  return is_login_in_progress_;
42194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
42294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
42394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::Login(const UserContext& user_context,
42494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                   const SigninSpecifics& specifics) {
42594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (user_context.GetUserType() == user_manager::USER_TYPE_GUEST) {
42694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (!specifics.guest_mode_url.empty()) {
42794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      guest_mode_url_ = GURL(specifics.guest_mode_url);
42894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      if (specifics.guest_mode_url_append_locale)
42994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        guest_mode_url_ = google_util::AppendGoogleLocaleParam(
43094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            guest_mode_url_, g_browser_process->GetApplicationLocale());
43194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
43294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    LoginAsGuest();
43394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
43494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else if (user_context.GetUserType() ==
43594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood             user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
43694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    LoginAsPublicSession(user_context);
43794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
43894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else if (user_context.GetUserType() ==
43994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood             user_manager::USER_TYPE_RETAIL_MODE) {
44094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    LoginAsRetailModeUser();
44194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
44294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else if (user_context.GetUserType() == user_manager::USER_TYPE_KIOSK_APP) {
44394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    LoginAsKioskApp(user_context.GetUserID(), specifics.kiosk_diagnostic_mode);
44494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
44594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
44694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
44794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (!user_context.HasCredentials())
44894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
44994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
45094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Stop the auto-login timer when attempting login.
45194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  StopPublicSessionAutoLoginTimer();
45294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
45394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Disable clicking on other windows.
45494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(false);
45594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
45694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (last_login_attempt_username_ != user_context.GetUserID()) {
45794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    last_login_attempt_username_ = user_context.GetUserID();
45894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    num_login_attempts_ = 0;
45994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Also reset state variables, which are used to determine password change.
46094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    offline_failed_ = false;
46194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    online_succeeded_for_.clear();
46294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
46394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  num_login_attempts_++;
46494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  PerformLogin(user_context, LoginPerformer::AUTH_MODE_INTERNAL);
46594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
46694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
46794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::PerformLogin(
46894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    const UserContext& user_context,
46994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    LoginPerformer::AuthorizationMode auth_mode) {
47094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  ChromeUserManager::Get()->GetUserFlow(last_login_attempt_username_)->set_host(
47194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      host_);
47294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
47394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  BootTimesLoader::Get()->RecordLoginAttempted();
47494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
47594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Disable UI while loading user profile.
47694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(false);
47794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
47894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  last_login_attempt_auth_flow_ = user_context.GetAuthFlow();
47994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
48094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Use the same LoginPerformer for subsequent login as it has state
48194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // such as Authenticator instance.
48294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (!login_performer_.get() || num_login_attempts_ <= 1) {
48394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Only one instance of LoginPerformer should exist at a time.
48494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_performer_.reset(NULL);
48594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_performer_.reset(new LoginPerformer(this));
48694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
48794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
48894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  is_login_in_progress_ = true;
48994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (gaia::ExtractDomainName(user_context.GetUserID()) ==
49094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      chromeos::login::kSupervisedUserDomain) {
49194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_performer_->LoginAsSupervisedUser(user_context);
49294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else {
49394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_performer_->PerformLogin(user_context, auth_mode);
49494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    RecordPasswordLoginEvent(user_context);
49594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
49694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  SendAccessibilityAlert(
49794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNING_IN));
49894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
49994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
50094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::LoginAsRetailModeUser() {
50194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Stop the auto-login timer when attempting login.
50294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  StopPublicSessionAutoLoginTimer();
50394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
50494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Disable clicking on other windows.
50594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(false);
50694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // TODO(rkc): Add a CHECK to make sure retail mode logins are allowed once
50794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // the enterprise policy wiring is done for retail mode.
50894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
50994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Only one instance of LoginPerformer should exist at a time.
51094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_performer_.reset(NULL);
51194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_performer_.reset(new LoginPerformer(this));
51294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  is_login_in_progress_ = true;
51394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_performer_->LoginRetailMode();
51494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  SendAccessibilityAlert(
51594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_DEMOUSER));
51694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
51794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
51894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::LoginAsGuest() {
51994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (is_login_in_progress_ ||
52094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      user_manager::UserManager::Get()->IsUserLoggedIn()) {
52194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
52294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
52394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
52494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Stop the auto-login timer when attempting login.
52594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  StopPublicSessionAutoLoginTimer();
52694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
52794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Disable clicking on other windows.
52894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(false);
52994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
53094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  CrosSettingsProvider::TrustedStatus status =
53194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      cros_settings_->PrepareTrustedValues(
53294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          base::Bind(&ExistingUserController::LoginAsGuest,
53394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     weak_factory_.GetWeakPtr()));
53494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Must not proceed without signature verification.
53594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
53694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, 1,
53794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                              HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
53894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Reenable clicking on other windows and status area.
53994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->SetUIEnabled(true);
54094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    StartPublicSessionAutoLoginTimer();
54194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    display_email_.clear();
54294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
54394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else if (status != CrosSettingsProvider::TRUSTED) {
54494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Value of AllowNewUser setting is still not verified.
54594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Another attempt will be invoked after verification completion.
54694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
54794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
54894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
54994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  bool allow_guest;
55094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  cros_settings_->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
55194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (!allow_guest) {
55294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Disallowed. The UI should normally not show the guest pod but if for some
55394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // reason this has been made available to the user here is the time to tell
55494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // this nicely.
55594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->ShowError(IDS_LOGIN_ERROR_WHITELIST, 1,
55694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                              HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
55794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Reenable clicking on other windows and status area.
55894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->SetUIEnabled(true);
55994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    StartPublicSessionAutoLoginTimer();
56094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    display_email_.clear();
56194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
56294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
56394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
56494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Only one instance of LoginPerformer should exist at a time.
56594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_performer_.reset(NULL);
56694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_performer_.reset(new LoginPerformer(this));
56794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  is_login_in_progress_ = true;
56894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_performer_->LoginOffTheRecord();
56994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  SendAccessibilityAlert(
57094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_OFFRECORD));
57194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
57294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
57394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::MigrateUserData(const std::string& old_password) {
57494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // LoginPerformer instance has state of the user so it should exist.
57594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (login_performer_.get())
57694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_performer_->RecoverEncryptedData(old_password);
57794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
57894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
57994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::LoginAsPublicSession(
58094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    const UserContext& user_context) {
58194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (is_login_in_progress_ ||
58294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      user_manager::UserManager::Get()->IsUserLoggedIn()) {
58394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
58494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
58594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
58694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Stop the auto-login timer when attempting login.
58794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  StopPublicSessionAutoLoginTimer();
58894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
58994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Disable clicking on other windows.
59094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(false);
59194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
59294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  CrosSettingsProvider::TrustedStatus status =
59394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      cros_settings_->PrepareTrustedValues(
59494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          base::Bind(&ExistingUserController::LoginAsPublicSession,
59594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     weak_factory_.GetWeakPtr(),
59694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     user_context));
59794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // If device policy is permanently unavailable, logging into public accounts
59894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // is not possible.
59994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
60094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, 1,
60194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                              HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
60294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Re-enable clicking on other windows.
60394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->SetUIEnabled(true);
60494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
60594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
60694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
60794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // If device policy is not verified yet, this function will be called again
60894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // when verification finishes.
60994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (status != CrosSettingsProvider::TRUSTED)
61094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
61194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
61294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // If there is no public account with the given user ID, logging in is not
61394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // possible.
61494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  const user_manager::User* user =
61594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      user_manager::UserManager::Get()->FindUser(user_context.GetUserID());
61694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
61794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Re-enable clicking on other windows.
61894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->SetUIEnabled(true);
61994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    StartPublicSessionAutoLoginTimer();
62094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
62194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
62294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
62394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  UserContext new_user_context = user_context;
62494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  std::string locale = user_context.GetPublicSessionLocale();
62594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (locale.empty()) {
62694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // When performing auto-login, no locale is chosen by the user. Check
62794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // whether a list of recommended locales was set by policy. If so, use its
62894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // first entry. Otherwise, |locale| will remain blank, indicating that the
62994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // public session should use the current UI locale.
63094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    const policy::PolicyMap::Entry* entry = g_browser_process->platform_part()->
63194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        browser_policy_connector_chromeos()->
63294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            GetDeviceLocalAccountPolicyService()->
63394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                GetBrokerForUser(user_context.GetUserID())->core()->store()->
63494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    policy_map().Get(policy::key::kSessionLocales);
63594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    base::ListValue const* list = NULL;
63694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (entry &&
63794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        entry->level == policy::POLICY_LEVEL_RECOMMENDED &&
63894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        entry->value &&
63994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        entry->value->GetAsList(&list)) {
64094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      if (list->GetString(0, &locale))
64194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        new_user_context.SetPublicSessionLocale(locale);
64294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
64394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
64494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
64594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (!locale.empty() &&
64694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      new_user_context.GetPublicSessionInputMethod().empty()) {
64794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // When |locale| is set, a suitable keyboard layout should be chosen. In
64894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // most cases, this will already be the case because the UI shows a list of
64994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // keyboard layouts suitable for the |locale| and ensures that one of them
65094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // us selected. However, it is still possible that |locale| is set but no
65194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // keyboard layout was chosen:
65294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // * The list of keyboard layouts is updated asynchronously. If the user
65394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    //   enters the public session before the list of keyboard layouts for the
65494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    //   |locale| has been retrieved, the UI will indicate that no keyboard
65594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    //   layout was chosen.
65694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // * During auto-login, the |locale| is set in this method and a suitable
65794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    //   keyboard layout must be chosen next.
65894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    //
65994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // The list of suitable keyboard layouts is constructed asynchronously. Once
66094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // it has been retrieved, |SetPublicSessionKeyboardLayoutAndLogin| will
66194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // select the first layout from the list and continue login.
66294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    GetKeyboardLayoutsForLocale(
66394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        base::Bind(
66494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            &ExistingUserController::SetPublicSessionKeyboardLayoutAndLogin,
66594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            weak_factory_.GetWeakPtr(),
66694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            new_user_context),
66794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        locale);
66894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
66994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
67094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
67194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // The user chose a locale and a suitable keyboard layout or left both unset.
67294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Login can continue immediately.
67394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  LoginAsPublicSessionInternal(new_user_context);
67494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
67594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
67694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::LoginAsKioskApp(const std::string& app_id,
67794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                             bool diagnostic_mode) {
67894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  host_->StartAppLaunch(app_id, diagnostic_mode);
67994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
68094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
68194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnSigninScreenReady() {
68294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  signin_screen_ready_ = true;
68394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  StartPublicSessionAutoLoginTimer();
68494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
68594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
68694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnStartEnterpriseEnrollment() {
68794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (KioskAppManager::Get()->IsConsumerKioskDeviceWithAutoLaunch()) {
68894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    LOG(WARNING) << "Enterprise enrollment is not available after kiosk auto "
68994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    "launch is set.";
69094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
69194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
69294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
69394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  DeviceSettingsService::Get()->GetOwnershipStatusAsync(
69494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      base::Bind(&ExistingUserController::OnEnrollmentOwnershipCheckCompleted,
69594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 weak_factory_.GetWeakPtr()));
69694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
69794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
69894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnStartKioskEnableScreen() {
69994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  KioskAppManager::Get()->GetConsumerKioskAutoLaunchStatus(
70094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      base::Bind(
70194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          &ExistingUserController::OnConsumerKioskAutoLaunchCheckCompleted,
70294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          weak_factory_.GetWeakPtr()));
70394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
70494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
70594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnStartKioskAutolaunchScreen() {
70694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  ShowKioskAutolaunchScreen();
70794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
70894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
70994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::ResyncUserData() {
71094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // LoginPerformer instance has state of the user so it should exist.
71194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (login_performer_.get())
71294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_performer_->ResyncEncryptedData();
71394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
71494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
71594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::SetDisplayEmail(const std::string& email) {
71694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  display_email_ = email;
71794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
71894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
71994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::ShowWrongHWIDScreen() {
72094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  scoped_ptr<base::DictionaryValue> params;
72194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  host_->StartWizard(WizardController::kWrongHWIDScreenName, params.Pass());
72294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
72394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
72494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::Signout() {
72594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  NOTREACHED();
72694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
72794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
72894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnConsumerKioskAutoLaunchCheckCompleted(
72994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    KioskAppManager::ConsumerKioskAutoLaunchStatus status) {
73094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (status == KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE)
73194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    ShowKioskEnableScreen();
73294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
73394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
73494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnEnrollmentOwnershipCheckCompleted(
73594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    DeviceSettingsService::OwnershipStatus status) {
73694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (status == DeviceSettingsService::OWNERSHIP_NONE) {
73794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    ShowEnrollmentScreen(false, std::string());
73894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else if (status == DeviceSettingsService::OWNERSHIP_TAKEN) {
73994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // On a device that is already owned we might want to allow users to
74094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // re-enroll if the policy information is invalid.
74194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    CrosSettingsProvider::TrustedStatus trusted_status =
74294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        CrosSettings::Get()->PrepareTrustedValues(
74394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            base::Bind(
74494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                &ExistingUserController::OnEnrollmentOwnershipCheckCompleted,
74594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                weak_factory_.GetWeakPtr(), status));
74694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (trusted_status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
74794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      ShowEnrollmentScreen(false, std::string());
74894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
74994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else {
75094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // OwnershipService::GetStatusAsync is supposed to return either
75194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // OWNERSHIP_NONE or OWNERSHIP_TAKEN.
75294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    NOTREACHED();
75394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
75494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
75594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
75694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::ShowEnrollmentScreen(bool is_auto_enrollment,
75794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                                  const std::string& user) {
75894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  scoped_ptr<base::DictionaryValue> params;
75994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (is_auto_enrollment) {
76094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    params.reset(new base::DictionaryValue());
76194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    params->SetBoolean("is_auto_enrollment", true);
76294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    params->SetString("user", user);
76394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
76494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  host_->StartWizard(WizardController::kEnrollmentScreenName,
76594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     params.Pass());
76694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
76794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
76894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::ShowResetScreen() {
76994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  scoped_ptr<base::DictionaryValue> params;
77094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  host_->StartWizard(WizardController::kResetScreenName, params.Pass());
77194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
77294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
77394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::ShowKioskEnableScreen() {
77494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  scoped_ptr<base::DictionaryValue> params;
77594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  host_->StartWizard(WizardController::kKioskEnableScreenName, params.Pass());
77694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
77794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
77894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::ShowKioskAutolaunchScreen() {
77994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  scoped_ptr<base::DictionaryValue> params;
78094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  host_->StartWizard(WizardController::kKioskAutolaunchScreenName,
78194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     params.Pass());
78294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
78394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
78494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::ShowTPMError() {
78594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(false);
78694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->ShowErrorScreen(LoginDisplay::TPM_ERROR);
78794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
78894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
78994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood////////////////////////////////////////////////////////////////////////////////
79094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// ExistingUserController, LoginPerformer::Delegate implementation:
79194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood//
79294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
79394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnAuthFailure(const AuthFailure& failure) {
79494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  is_login_in_progress_ = false;
79594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  offline_failed_ = true;
79694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
79794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  guest_mode_url_ = GURL::EmptyGURL();
79894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  std::string error = failure.GetErrorString();
79994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
80094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // TODO(xiyuan): Move into EasyUnlockUserLoginFlow.
80194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (last_login_attempt_auth_flow_ == UserContext::AUTH_FLOW_EASY_UNLOCK)
80294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    RecordEasySignInOutcome(last_login_attempt_username_, false);
80394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
80494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (ChromeUserManager::Get()
80594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          ->GetUserFlow(last_login_attempt_username_)
80694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          ->HandleLoginFailure(failure)) {
80794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->SetUIEnabled(true);
80894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
80994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
81094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
81194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (failure.reason() == AuthFailure::OWNER_REQUIRED) {
81294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    ShowError(IDS_LOGIN_ERROR_OWNER_REQUIRED, error);
81394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    content::BrowserThread::PostDelayedTask(
81494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        content::BrowserThread::UI, FROM_HERE,
81594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        base::Bind(&SessionManagerClient::StopSession,
81694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                   base::Unretained(DBusThreadManager::Get()->
81794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                    GetSessionManagerClient())),
81894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        base::TimeDelta::FromMilliseconds(kSafeModeRestartUiDelayMs));
81994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else if (failure.reason() == AuthFailure::TPM_ERROR) {
82094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    ShowTPMError();
82194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else if (!online_succeeded_for_.empty()) {
82294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    ShowGaiaPasswordChanged(online_succeeded_for_);
82394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else {
82494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Check networking after trying to login in case user is
82594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // cached locally or the local admin account.
82694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    bool is_known_user = user_manager::UserManager::Get()->IsKnownUser(
82794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        last_login_attempt_username_);
82894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (!network_state_helper_->IsConnected()) {
82994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      if (is_known_user)
83094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
83194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      else
83294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        ShowError(IDS_LOGIN_ERROR_OFFLINE_FAILED_NETWORK_NOT_CONNECTED, error);
83394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    } else {
83494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      // TODO(nkostylev): Cleanup rest of ClientLogin related code.
83594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      if (failure.reason() == AuthFailure::NETWORK_AUTH_FAILED &&
83694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          failure.error().state() ==
83794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood              GoogleServiceAuthError::HOSTED_NOT_ALLOWED) {
83894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        ShowError(IDS_LOGIN_ERROR_AUTHENTICATING_HOSTED, error);
83994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      } else {
84094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (!is_known_user)
84194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          ShowError(IDS_LOGIN_ERROR_AUTHENTICATING_NEW, error);
84294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        else
84394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
84494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      }
84594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
84694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Reenable clicking on other windows and status area.
84794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->SetUIEnabled(true);
84894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    login_display_->ClearAndEnablePassword();
84994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    StartPublicSessionAutoLoginTimer();
85094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
85194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
85294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Reset user flow to default, so that special flow will not affect next
85394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // attempt.
85494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  ChromeUserManager::Get()->ResetUserFlow(last_login_attempt_username_);
85594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
85694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (auth_status_consumer_)
85794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    auth_status_consumer_->OnAuthFailure(failure);
85894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
85994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Clear the recorded displayed email so it won't affect any future attempts.
86094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  display_email_.clear();
86194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
86294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
86394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnAuthSuccess(const UserContext& user_context) {
86494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  is_login_in_progress_ = false;
86594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  offline_failed_ = false;
86694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->set_signin_completed(true);
86794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
86894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Login performer will be gone so cache this value to use
86994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // once profile is loaded.
87094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  password_changed_ = login_performer_->password_changed();
87194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  auth_mode_ = login_performer_->auth_mode();
87294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
87394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  ChromeUserManager::Get()
87494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      ->GetUserFlow(user_context.GetUserID())
87594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      ->HandleLoginSuccess(user_context);
87694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
87794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // TODO(xiyuan): Move into EasyUnlockUserLoginFlow.
87894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (last_login_attempt_auth_flow_ == UserContext::AUTH_FLOW_EASY_UNLOCK) {
87994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    DCHECK_EQ(last_login_attempt_username_, user_context.GetUserID());
88094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    DCHECK_EQ(last_login_attempt_auth_flow_, user_context.GetAuthFlow());
88194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    RecordEasySignInOutcome(last_login_attempt_username_, true);
88294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
88394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
88494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  StopPublicSessionAutoLoginTimer();
88594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
88694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  const bool has_auth_cookies =
88794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      login_performer_->auth_mode() == LoginPerformer::AUTH_MODE_EXTENSION &&
88894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      user_context.GetAuthCode().empty();
88994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
89094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // LoginPerformer instance will delete itself once online auth result is OK.
89194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // In case of failure it'll bring up ScreenLock and ask for
89294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // correct password/display error message.
89394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Even in case when following online,offline protocol and returning
89494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // requests_pending = false, let LoginPerformer delete itself.
89594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_performer_->set_delegate(NULL);
89694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  ignore_result(login_performer_.release());
89794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
89894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Will call OnProfilePrepared() in the end.
89994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  LoginUtils::Get()->PrepareProfile(user_context,
90094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                    has_auth_cookies,
90194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                    false,          // Start session for user.
90294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                    this);
90394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
90494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Update user's displayed email.
90594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (!display_email_.empty()) {
90694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    user_manager::UserManager::Get()->SaveUserDisplayEmail(
90794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        user_context.GetUserID(), display_email_);
90894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    display_email_.clear();
90994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
91094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
91194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
91294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnProfilePrepared(Profile* profile) {
91394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Reenable clicking on other windows and status area.
91494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(true);
91594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
91694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
91794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (user_manager->IsCurrentUserNew() &&
91894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      user_manager->IsLoggedInAsSupervisedUser()) {
91994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Supervised users should launch into empty desktop on first run.
92094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
92194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
92294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
92394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (user_manager->IsCurrentUserNew() &&
92494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      !ChromeUserManager::Get()
92594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood           ->GetCurrentUserFlow()
92694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood           ->ShouldSkipPostLoginScreens() &&
92794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      !WizardController::default_controller()->skip_post_login_screens()) {
92894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Don't specify start URLs if the administrator has configured the start
92994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // URLs via policy.
93094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (!SessionStartupPref::TypeIsManaged(profile->GetPrefs()))
93194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      InitializeStartUrls();
93294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
93394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Mark the device as registered., i.e. the second part of OOBE as
93494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // completed.
93594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (!StartupUtils::IsDeviceRegistered())
93694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      StartupUtils::MarkDeviceRegistered(base::Closure());
93794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
93894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (CommandLine::ForCurrentProcess()->HasSwitch(
93994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          chromeos::switches::kOobeSkipPostLogin)) {
94094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      LoginUtils::Get()->DoBrowserLaunch(profile, host_);
94194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      host_ = NULL;
94294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    } else {
94394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      ActivateWizard(WizardController::kTermsOfServiceScreenName);
94494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
94594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  } else {
94694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    LoginUtils::Get()->DoBrowserLaunch(profile, host_);
94794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    host_ = NULL;
94894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
94994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Inform |auth_status_consumer_| about successful login.
95094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (auth_status_consumer_)
95194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    auth_status_consumer_->OnAuthSuccess(UserContext());
95294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
95394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
95494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnOffTheRecordAuthSuccess() {
95594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  is_login_in_progress_ = false;
95694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  offline_failed_ = false;
95794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
95894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Mark the device as registered., i.e. the second part of OOBE as completed.
95994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (!StartupUtils::IsDeviceRegistered())
96094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    StartupUtils::MarkDeviceRegistered(base::Closure());
96194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
96294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  LoginUtils::Get()->CompleteOffTheRecordLogin(guest_mode_url_);
96394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
96494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (auth_status_consumer_)
96594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    auth_status_consumer_->OnOffTheRecordAuthSuccess();
96694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
96794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
96894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnPasswordChangeDetected() {
96994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  is_login_in_progress_ = false;
97094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  offline_failed_ = false;
97194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
97294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Must not proceed without signature verification.
97394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
97494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      base::Bind(&ExistingUserController::OnPasswordChangeDetected,
97594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                 weak_factory_.GetWeakPtr()))) {
97694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Value of owner email is still not verified.
97794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Another attempt will be invoked after verification completion.
97894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
97994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
98094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
98194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (ChromeUserManager::Get()
98294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          ->GetUserFlow(last_login_attempt_username_)
98394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood          ->HandlePasswordChangeDetected()) {
98494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
98594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
98694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
98794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // True if user has already made an attempt to enter old password and failed.
98894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  bool show_invalid_old_password_error =
98994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      login_performer_->password_changed_callback_count() > 1;
99094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
99194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Note: We allow owner using "full sync" mode which will recreate
99294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // cryptohome and deal with owner private key being lost. This also allows
99394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // us to recover from a lost owner password/homedir.
99494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // TODO(gspencer): We shouldn't have to erase stateful data when
99594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // doing this.  See http://crosbug.com/9115 http://crosbug.com/7792
99694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->ShowPasswordChangedDialog(show_invalid_old_password_error);
99794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
99894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (auth_status_consumer_)
99994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    auth_status_consumer_->OnPasswordChangeDetected();
100094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
100194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  display_email_.clear();
100294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
100394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
100494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::WhiteListCheckFailed(const std::string& email) {
100594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  is_login_in_progress_ = false;
100694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  offline_failed_ = false;
100794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
100894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  ShowError(IDS_LOGIN_ERROR_WHITELIST, email);
100994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
101094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Reenable clicking on other windows and status area.
101194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(true);
101294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->ShowSigninUI(email);
101394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
101494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (auth_status_consumer_) {
101594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    auth_status_consumer_->OnAuthFailure(
101694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        AuthFailure(AuthFailure::WHITELIST_CHECK_FAILED));
101794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
101894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
101994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  display_email_.clear();
102094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
102194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  StartPublicSessionAutoLoginTimer();
102294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
102394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
102494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::PolicyLoadFailed() {
102594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, "");
102694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
102794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Reenable clicking on other windows and status area.
102894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  is_login_in_progress_ = false;
102994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  offline_failed_ = false;
103094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  login_display_->SetUIEnabled(true);
103194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
103294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  display_email_.clear();
103394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
103494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  // Policy load failure stops login attempts -- restart the timer.
103594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  StartPublicSessionAutoLoginTimer();
103694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
103794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
103894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::OnOnlineChecked(const std::string& username,
103994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                             bool success) {
104094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (success && last_login_attempt_username_ == username) {
104194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    online_succeeded_for_ = username;
104294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Wait for login attempt to end, if it hasn't yet.
104394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (offline_failed_ && !is_login_in_progress_)
104494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood      ShowGaiaPasswordChanged(username);
104594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
104694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
104794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
104894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood////////////////////////////////////////////////////////////////////////////////
104994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// ExistingUserController, private:
105094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
105194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::DeviceSettingsChanged() {
105294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (host_ != NULL) {
105394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    // Signed settings or user list changed. Notify views and update them.
105494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    UpdateLoginDisplay(user_manager::UserManager::Get()->GetUsers());
105594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    ConfigurePublicSessionAutoLogin();
105694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return;
105794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  }
105894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
105994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
106094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid ExistingUserController::ActivateWizard(const std::string& screen_name) {
106194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  scoped_ptr<base::DictionaryValue> params;
106294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  host_->StartWizard(screen_name, params.Pass());
106394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
106494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
106594afecf4b6f437b3ee9a076242402e421c6c07a6Mike LockwoodLoginPerformer::AuthorizationMode ExistingUserController::auth_mode() const {
106694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (login_performer_)
106794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return login_performer_->auth_mode();
106894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
106994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  return auth_mode_;
107094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
107194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
107294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodbool ExistingUserController::password_changed() const {
107394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood  if (login_performer_)
107494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return login_performer_->password_changed();
107594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
1076  return password_changed_;
1077}
1078
1079void ExistingUserController::ConfigurePublicSessionAutoLogin() {
1080  std::string auto_login_account_id;
1081  cros_settings_->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
1082                            &auto_login_account_id);
1083  const std::vector<policy::DeviceLocalAccount> device_local_accounts =
1084      policy::GetDeviceLocalAccounts(cros_settings_);
1085
1086  public_session_auto_login_username_.clear();
1087  for (std::vector<policy::DeviceLocalAccount>::const_iterator
1088           it = device_local_accounts.begin();
1089       it != device_local_accounts.end(); ++it) {
1090    if (it->account_id == auto_login_account_id) {
1091      public_session_auto_login_username_ = it->user_id;
1092      break;
1093    }
1094  }
1095
1096  const user_manager::User* user = user_manager::UserManager::Get()->FindUser(
1097      public_session_auto_login_username_);
1098  if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
1099    public_session_auto_login_username_.clear();
1100
1101  if (!cros_settings_->GetInteger(
1102          kAccountsPrefDeviceLocalAccountAutoLoginDelay,
1103          &public_session_auto_login_delay_)) {
1104    public_session_auto_login_delay_ = 0;
1105  }
1106
1107  if (!public_session_auto_login_username_.empty())
1108    StartPublicSessionAutoLoginTimer();
1109  else
1110    StopPublicSessionAutoLoginTimer();
1111}
1112
1113void ExistingUserController::ResetPublicSessionAutoLoginTimer() {
1114  // Only restart the auto-login timer if it's already running.
1115  if (auto_login_timer_ && auto_login_timer_->IsRunning()) {
1116    StopPublicSessionAutoLoginTimer();
1117    StartPublicSessionAutoLoginTimer();
1118  }
1119}
1120
1121void ExistingUserController::OnPublicSessionAutoLoginTimerFire() {
1122  CHECK(signin_screen_ready_ &&
1123        !is_login_in_progress_ &&
1124        !public_session_auto_login_username_.empty());
1125  // TODO(bartfab): Set the UI language and initial locale.
1126  LoginAsPublicSession(UserContext(user_manager::USER_TYPE_PUBLIC_ACCOUNT,
1127                                   public_session_auto_login_username_));
1128}
1129
1130void ExistingUserController::StopPublicSessionAutoLoginTimer() {
1131  if (auto_login_timer_)
1132    auto_login_timer_->Stop();
1133}
1134
1135void ExistingUserController::StartPublicSessionAutoLoginTimer() {
1136  if (!signin_screen_ready_ ||
1137      is_login_in_progress_ ||
1138      public_session_auto_login_username_.empty()) {
1139    return;
1140  }
1141
1142  // Start the auto-login timer.
1143  if (!auto_login_timer_)
1144    auto_login_timer_.reset(new base::OneShotTimer<ExistingUserController>);
1145
1146  auto_login_timer_->Start(
1147      FROM_HERE,
1148      base::TimeDelta::FromMilliseconds(
1149          public_session_auto_login_delay_),
1150      base::Bind(
1151          &ExistingUserController::OnPublicSessionAutoLoginTimerFire,
1152          weak_factory_.GetWeakPtr()));
1153}
1154
1155gfx::NativeWindow ExistingUserController::GetNativeWindow() const {
1156  return host_->GetNativeWindow();
1157}
1158
1159void ExistingUserController::InitializeStartUrls() const {
1160  std::vector<std::string> start_urls;
1161
1162  const base::ListValue *urls;
1163  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
1164  bool can_show_getstarted_guide =
1165      user_manager->GetActiveUser()->GetType() ==
1166          user_manager::USER_TYPE_REGULAR &&
1167      !user_manager->IsCurrentUserNonCryptohomeDataEphemeral();
1168  if (user_manager->IsLoggedInAsDemoUser()) {
1169    if (CrosSettings::Get()->GetList(kStartUpUrls, &urls)) {
1170      // The retail mode user will get start URLs from a special policy if it is
1171      // set.
1172      for (base::ListValue::const_iterator it = urls->begin();
1173           it != urls->end(); ++it) {
1174        std::string url;
1175        if ((*it)->GetAsString(&url))
1176          start_urls.push_back(url);
1177      }
1178    }
1179    can_show_getstarted_guide = false;
1180  // Skip the default first-run behavior for public accounts.
1181  } else if (!user_manager->IsLoggedInAsPublicAccount()) {
1182    if (AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
1183      const char* url = kChromeVoxTutorialURLPattern;
1184      PrefService* prefs = g_browser_process->local_state();
1185      const std::string current_locale =
1186          base::StringToLowerASCII(prefs->GetString(prefs::kApplicationLocale));
1187      std::string vox_url = base::StringPrintf(url, current_locale.c_str());
1188      start_urls.push_back(vox_url);
1189      can_show_getstarted_guide = false;
1190    }
1191  }
1192
1193  // Only show getting started guide for a new user.
1194  const bool should_show_getstarted_guide = user_manager->IsCurrentUserNew();
1195
1196  if (can_show_getstarted_guide && should_show_getstarted_guide) {
1197    // Don't open default Chrome window if we're going to launch the first-run
1198    // app. Because we dont' want the first-run app to be hidden in the
1199    // background.
1200    CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
1201    first_run::MaybeLaunchDialogAfterSessionStart();
1202  } else {
1203    for (size_t i = 0; i < start_urls.size(); ++i) {
1204      CommandLine::ForCurrentProcess()->AppendArg(start_urls[i]);
1205    }
1206  }
1207}
1208
1209void ExistingUserController::ShowError(int error_id,
1210                                       const std::string& details) {
1211  // TODO(dpolukhin): show detailed error info. |details| string contains
1212  // low level error info that is not localized and even is not user friendly.
1213  // For now just ignore it because error_text contains all required information
1214  // for end users, developers can see details string in Chrome logs.
1215  VLOG(1) << details;
1216  HelpAppLauncher::HelpTopic help_topic_id;
1217  bool is_offline = !network_state_helper_->IsConnected();
1218  switch (login_performer_->error().state()) {
1219    case GoogleServiceAuthError::CONNECTION_FAILED:
1220      help_topic_id = HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT_OFFLINE;
1221      break;
1222    case GoogleServiceAuthError::ACCOUNT_DISABLED:
1223      help_topic_id = HelpAppLauncher::HELP_ACCOUNT_DISABLED;
1224      break;
1225    case GoogleServiceAuthError::HOSTED_NOT_ALLOWED:
1226      help_topic_id = HelpAppLauncher::HELP_HOSTED_ACCOUNT;
1227      break;
1228    default:
1229      help_topic_id = is_offline ?
1230          HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT_OFFLINE :
1231          HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT;
1232      break;
1233  }
1234
1235  if (error_id == IDS_LOGIN_ERROR_AUTHENTICATING) {
1236    if (num_login_attempts_ > 1) {
1237      const user_manager::User* user =
1238          user_manager::UserManager::Get()->FindUser(
1239              last_login_attempt_username_);
1240      if (user && (user->GetType() == user_manager::USER_TYPE_SUPERVISED))
1241        error_id = IDS_LOGIN_ERROR_AUTHENTICATING_2ND_TIME_SUPERVISED;
1242    }
1243  }
1244
1245  login_display_->ShowError(error_id, num_login_attempts_, help_topic_id);
1246}
1247
1248void ExistingUserController::ShowGaiaPasswordChanged(
1249    const std::string& username) {
1250  // Invalidate OAuth token, since it can't be correct after password is
1251  // changed.
1252  user_manager::UserManager::Get()->SaveUserOAuthStatus(
1253      username, user_manager::User::OAUTH2_TOKEN_STATUS_INVALID);
1254
1255  login_display_->SetUIEnabled(true);
1256  login_display_->ShowGaiaPasswordChanged(username);
1257}
1258
1259void ExistingUserController::SendAccessibilityAlert(
1260    const std::string& alert_text) {
1261  AccessibilityAlertInfo event(ProfileHelper::GetSigninProfile(), alert_text);
1262  SendControlAccessibilityNotification(
1263      ui::AX_EVENT_VALUE_CHANGED, &event);
1264}
1265
1266void ExistingUserController::SetPublicSessionKeyboardLayoutAndLogin(
1267    const UserContext& user_context,
1268    scoped_ptr<base::ListValue> keyboard_layouts) {
1269  UserContext new_user_context = user_context;
1270  std::string keyboard_layout;
1271  for (size_t i = 0; i < keyboard_layouts->GetSize(); ++i) {
1272    base::DictionaryValue* entry = NULL;
1273    keyboard_layouts->GetDictionary(i, &entry);
1274    bool selected = false;
1275    entry->GetBoolean("selected", &selected);
1276    if (selected) {
1277      entry->GetString("value", &keyboard_layout);
1278      break;
1279    }
1280  }
1281  DCHECK(!keyboard_layout.empty());
1282  new_user_context.SetPublicSessionInputMethod(keyboard_layout);
1283
1284  LoginAsPublicSessionInternal(new_user_context);
1285}
1286
1287void ExistingUserController::LoginAsPublicSessionInternal(
1288    const UserContext& user_context) {
1289  // Only one instance of LoginPerformer should exist at a time.
1290  login_performer_.reset(NULL);
1291  login_performer_.reset(new LoginPerformer(this));
1292  is_login_in_progress_ = true;
1293  login_performer_->LoginAsPublicSession(user_context);
1294  SendAccessibilityAlert(
1295      l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_PUBLIC_ACCOUNT));
1296}
1297
1298}  // namespace chromeos
1299