Extract LoginPerformer to chromeos/auth
[chromium-blink-merge.git] / chrome / browser / chromeos / app_mode / kiosk_profile_loader.cc
blob9450b6ab9bd35d53051fa95e873db51d5ef2e962
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/app_mode/kiosk_profile_loader.h"
7 #include "base/logging.h"
8 #include "base/memory/weak_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_util.h"
11 #include "base/sys_info.h"
12 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
13 #include "chrome/browser/chromeos/login/auth/chrome_login_performer.h"
14 #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
15 #include "chrome/browser/chromeos/login/login_utils.h"
16 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
17 #include "chrome/browser/chromeos/settings/cros_settings.h"
18 #include "chrome/browser/lifetime/application_lifetime.h"
19 #include "chromeos/cryptohome/async_method_caller.h"
20 #include "chromeos/dbus/cryptohome_client.h"
21 #include "chromeos/dbus/dbus_thread_manager.h"
22 #include "chromeos/login/auth/auth_status_consumer.h"
23 #include "chromeos/login/auth/user_context.h"
24 #include "chromeos/login/user_names.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "google_apis/gaia/gaia_auth_util.h"
28 using content::BrowserThread;
30 namespace chromeos {
32 namespace {
34 KioskAppLaunchError::Error LoginFailureToKioskAppLaunchError(
35 const AuthFailure& error) {
36 switch (error.reason()) {
37 case AuthFailure::COULD_NOT_MOUNT_TMPFS:
38 case AuthFailure::COULD_NOT_MOUNT_CRYPTOHOME:
39 return KioskAppLaunchError::UNABLE_TO_MOUNT;
40 case AuthFailure::DATA_REMOVAL_FAILED:
41 return KioskAppLaunchError::UNABLE_TO_REMOVE;
42 case AuthFailure::USERNAME_HASH_FAILED:
43 return KioskAppLaunchError::UNABLE_TO_RETRIEVE_HASH;
44 default:
45 NOTREACHED();
46 return KioskAppLaunchError::UNABLE_TO_MOUNT;
50 } // namespace
52 ////////////////////////////////////////////////////////////////////////////////
53 // KioskProfileLoader::CryptohomedChecker ensures cryptohome daemon is up
54 // and running by issuing an IsMounted call. If the call does not go through
55 // and chromeos::DBUS_METHOD_CALL_SUCCESS is not returned, it will retry after
56 // some time out and at the maximum five times before it gives up. Upon
57 // success, it resumes the launch by logging in as a kiosk mode account.
59 class KioskProfileLoader::CryptohomedChecker
60 : public base::SupportsWeakPtr<CryptohomedChecker> {
61 public:
62 explicit CryptohomedChecker(KioskProfileLoader* loader)
63 : loader_(loader),
64 retry_count_(0) {
66 ~CryptohomedChecker() {}
68 void StartCheck() {
69 chromeos::DBusThreadManager::Get()->GetCryptohomeClient()->IsMounted(
70 base::Bind(&CryptohomedChecker::OnCryptohomeIsMounted,
71 AsWeakPtr()));
74 private:
75 void OnCryptohomeIsMounted(chromeos::DBusMethodCallStatus call_status,
76 bool is_mounted) {
77 if (call_status != chromeos::DBUS_METHOD_CALL_SUCCESS) {
78 const int kMaxRetryTimes = 5;
79 ++retry_count_;
80 if (retry_count_ > kMaxRetryTimes) {
81 LOG(ERROR) << "Could not talk to cryptohomed for launching kiosk app.";
82 ReportCheckResult(KioskAppLaunchError::CRYPTOHOMED_NOT_RUNNING);
83 return;
86 const int retry_delay_in_milliseconds = 500 * (1 << retry_count_);
87 base::MessageLoop::current()->PostDelayedTask(
88 FROM_HERE,
89 base::Bind(&CryptohomedChecker::StartCheck, AsWeakPtr()),
90 base::TimeDelta::FromMilliseconds(retry_delay_in_milliseconds));
91 return;
94 if (is_mounted)
95 LOG(ERROR) << "Cryptohome is mounted before launching kiosk app.";
97 // Proceed only when cryptohome is not mounded or running on dev box.
98 if (!is_mounted || !base::SysInfo::IsRunningOnChromeOS())
99 ReportCheckResult(KioskAppLaunchError::NONE);
100 else
101 ReportCheckResult(KioskAppLaunchError::ALREADY_MOUNTED);
104 void ReportCheckResult(KioskAppLaunchError::Error error) {
105 if (error == KioskAppLaunchError::NONE)
106 loader_->LoginAsKioskAccount();
107 else
108 loader_->ReportLaunchResult(error);
111 KioskProfileLoader* loader_;
112 int retry_count_;
114 DISALLOW_COPY_AND_ASSIGN(CryptohomedChecker);
118 ////////////////////////////////////////////////////////////////////////////////
119 // KioskProfileLoader
121 KioskProfileLoader::KioskProfileLoader(const std::string& app_user_id,
122 bool use_guest_mount,
123 Delegate* delegate)
124 : user_id_(app_user_id),
125 use_guest_mount_(use_guest_mount),
126 delegate_(delegate) {}
128 KioskProfileLoader::~KioskProfileLoader() {}
130 void KioskProfileLoader::Start() {
131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
132 login_performer_.reset();
133 cryptohomed_checker_.reset(new CryptohomedChecker(this));
134 cryptohomed_checker_->StartCheck();
137 void KioskProfileLoader::LoginAsKioskAccount() {
138 login_performer_.reset(new ChromeLoginPerformer(this));
139 login_performer_->LoginAsKioskAccount(user_id_, use_guest_mount_);
142 void KioskProfileLoader::ReportLaunchResult(KioskAppLaunchError::Error error) {
143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
145 if (error != KioskAppLaunchError::NONE) {
146 delegate_->OnProfileLoadFailed(error);
150 void KioskProfileLoader::OnAuthSuccess(const UserContext& user_context) {
151 // LoginPerformer will delete itself.
152 login_performer_->set_delegate(NULL);
153 ignore_result(login_performer_.release());
155 // If we are launching a demo session, we need to start MountGuest with the
156 // guest username; this is because there are several places in the cros code
157 // which rely on the username sent to cryptohome to be $guest. Back in Chrome
158 // we switch this back to the demo user name to correctly identify this
159 // user as a demo user.
160 UserContext context = user_context;
161 if (context.GetUserID() == chromeos::login::kGuestUserName)
162 context.SetUserID(DemoAppLauncher::kDemoUserName);
163 LoginUtils::Get()->PrepareProfile(context,
164 false, // has_auth_cookies
165 false, // has_active_session
166 this);
169 void KioskProfileLoader::OnAuthFailure(const AuthFailure& error) {
170 ReportLaunchResult(LoginFailureToKioskAppLaunchError(error));
173 void KioskProfileLoader::WhiteListCheckFailed(const std::string& email) {
174 NOTREACHED();
177 void KioskProfileLoader::PolicyLoadFailed() {
178 ReportLaunchResult(KioskAppLaunchError::POLICY_LOAD_FAILED);
181 void KioskProfileLoader::OnOnlineChecked(
182 const std::string& email, bool success) {
183 NOTREACHED();
186 void KioskProfileLoader::OnProfilePrepared(Profile* profile) {
187 // This object could be deleted any time after successfully reporting
188 // a profile load, so invalidate the LoginUtils delegate now.
189 LoginUtils::Get()->DelegateDeleted(this);
191 delegate_->OnProfileLoaded(profile);
192 ReportLaunchResult(KioskAppLaunchError::NONE);
195 } // namespace chromeos