Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / enrollment / enrollment_screen.cc
blob78c373ad360a8cb51699a4bdadd4d7647900516a
1 // Copyright (c) 2012 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/login/enrollment/enrollment_screen.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/metrics/histogram.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/chromeos/login/login_utils.h"
14 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
15 #include "chrome/browser/chromeos/login/startup_utils.h"
16 #include "chrome/browser/chromeos/login/wizard_controller.h"
17 #include "chrome/browser/chromeos/policy/auto_enrollment_client.h"
18 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
19 #include "chrome/browser/policy/browser_policy_connector.h"
20 #include "chromeos/dbus/cryptohome_client.h"
21 #include "chromeos/dbus/dbus_method_call_status.h"
22 #include "chromeos/dbus/dbus_thread_manager.h"
23 #include "chromeos/dbus/session_manager_client.h"
24 #include "components/policy/core/common/cloud/enterprise_metrics.h"
25 #include "google_apis/gaia/gaia_auth_util.h"
26 #include "google_apis/gaia/google_service_auth_error.h"
28 namespace chromeos {
30 namespace {
32 void UMA(int sample) {
33 UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment,
34 sample,
35 policy::kMetricEnrollmentSize);
38 } // namespace
40 EnrollmentScreen::EnrollmentScreen(
41 ScreenObserver* observer,
42 EnrollmentScreenActor* actor)
43 : WizardScreen(observer),
44 actor_(actor),
45 is_auto_enrollment_(false),
46 can_exit_enrollment_(true),
47 enrollment_failed_once_(false),
48 lockbox_init_duration_(0),
49 weak_ptr_factory_(this) {
50 // Init the TPM if it has not been done until now (in debug build we might
51 // have not done that yet).
52 DBusThreadManager::Get()->GetCryptohomeClient()->TpmCanAttemptOwnership(
53 EmptyVoidDBusMethodCallback());
56 EnrollmentScreen::~EnrollmentScreen() {}
58 void EnrollmentScreen::SetParameters(bool is_auto_enrollment,
59 bool can_exit_enrollment,
60 const std::string& user) {
61 is_auto_enrollment_ = is_auto_enrollment;
62 can_exit_enrollment_ = can_exit_enrollment;
63 user_ = user.empty() ? user : gaia::CanonicalizeEmail(user);
64 actor_->SetParameters(this, is_auto_enrollment_, can_exit_enrollment, user_);
67 void EnrollmentScreen::PrepareToShow() {
68 actor_->PrepareToShow();
71 void EnrollmentScreen::Show() {
72 if (is_auto_enrollment_ && !enrollment_failed_once_) {
73 actor_->Show();
74 UMA(policy::kMetricEnrollmentAutoStarted);
75 actor_->ShowEnrollmentSpinnerScreen();
76 actor_->FetchOAuthToken();
77 } else {
78 actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen,
79 weak_ptr_factory_.GetWeakPtr()));
83 void EnrollmentScreen::Hide() {
84 actor_->Hide();
85 weak_ptr_factory_.InvalidateWeakPtrs();
88 std::string EnrollmentScreen::GetName() const {
89 return WizardController::kEnrollmentScreenName;
92 void EnrollmentScreen::OnLoginDone(const std::string& user) {
93 user_ = gaia::CanonicalizeEmail(user);
95 UMA(is_auto_enrollment_ ? policy::kMetricEnrollmentAutoRetried
96 : policy::kMetricEnrollmentStarted);
98 actor_->ShowEnrollmentSpinnerScreen();
99 actor_->FetchOAuthToken();
102 void EnrollmentScreen::OnAuthError(
103 const GoogleServiceAuthError& error) {
104 enrollment_failed_once_ = true;
105 actor_->ShowAuthError(error);
107 switch (error.state()) {
108 case GoogleServiceAuthError::NONE:
109 case GoogleServiceAuthError::CAPTCHA_REQUIRED:
110 case GoogleServiceAuthError::TWO_FACTOR:
111 case GoogleServiceAuthError::HOSTED_NOT_ALLOWED:
112 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
113 case GoogleServiceAuthError::REQUEST_CANCELED:
114 case GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE:
115 case GoogleServiceAuthError::SERVICE_ERROR:
116 UMAFailure(policy::kMetricEnrollmentLoginFailed);
117 LOG(ERROR) << "Auth error " << error.state();
118 return;
119 case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
120 case GoogleServiceAuthError::ACCOUNT_DELETED:
121 case GoogleServiceAuthError::ACCOUNT_DISABLED:
122 UMAFailure(policy::kMetricEnrollmentNotSupported);
123 LOG(ERROR) << "Account error " << error.state();
124 return;
125 case GoogleServiceAuthError::CONNECTION_FAILED:
126 case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
127 UMAFailure(policy::kMetricEnrollmentNetworkFailed);
128 LOG(WARNING) << "Network error " << error.state();
129 return;
130 case GoogleServiceAuthError::NUM_STATES:
131 break;
134 NOTREACHED();
135 UMAFailure(policy::kMetricEnrollmentOtherFailed);
138 void EnrollmentScreen::OnOAuthTokenAvailable(
139 const std::string& token) {
140 RegisterForDevicePolicy(token);
143 void EnrollmentScreen::OnRetry() {
144 actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen,
145 weak_ptr_factory_.GetWeakPtr()));
148 void EnrollmentScreen::OnCancel() {
149 if (!can_exit_enrollment_) {
150 actor_->ResetAuth(
151 base::Bind(&ScreenObserver::OnExit,
152 base::Unretained(get_screen_observer()),
153 ScreenObserver::ENTERPRISE_ENROLLMENT_BACK));
154 return;
157 if (is_auto_enrollment_)
158 policy::AutoEnrollmentClient::CancelAutoEnrollment();
159 UMA(is_auto_enrollment_ ? policy::kMetricEnrollmentAutoCancelled
160 : policy::kMetricEnrollmentCancelled);
161 actor_->ResetAuth(
162 base::Bind(&ScreenObserver::OnExit,
163 base::Unretained(get_screen_observer()),
164 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
167 void EnrollmentScreen::OnConfirmationClosed() {
168 // If the machine has been put in KIOSK mode we have to restart the session
169 // here to go in the proper KIOSK mode login screen.
170 if (g_browser_process->browser_policy_connector()->GetDeviceMode() ==
171 policy::DEVICE_MODE_RETAIL_KIOSK) {
172 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
173 return;
176 if (is_auto_enrollment_ &&
177 !enrollment_failed_once_ &&
178 !user_.empty() &&
179 LoginUtils::IsWhitelisted(user_)) {
180 actor_->ShowLoginSpinnerScreen();
181 get_screen_observer()->OnExit(
182 ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED);
183 } else {
184 actor_->ResetAuth(
185 base::Bind(&ScreenObserver::OnExit,
186 base::Unretained(get_screen_observer()),
187 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
191 void EnrollmentScreen::RegisterForDevicePolicy(
192 const std::string& token) {
193 policy::BrowserPolicyConnector* connector =
194 g_browser_process->browser_policy_connector();
195 if (connector->IsEnterpriseManaged() &&
196 connector->GetEnterpriseDomain() != gaia::ExtractDomainName(user_)) {
197 LOG(ERROR) << "Trying to re-enroll to a different domain than "
198 << connector->GetEnterpriseDomain();
199 UMAFailure(policy::kMetricEnrollmentWrongUserError);
200 actor_->ShowUIError(
201 EnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH);
202 return;
205 policy::DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes modes;
206 modes[policy::DEVICE_MODE_ENTERPRISE] = true;
207 modes[policy::DEVICE_MODE_RETAIL_KIOSK] = !is_auto_enrollment_;
208 connector->ScheduleServiceInitialization(0);
209 connector->GetDeviceCloudPolicyManager()->StartEnrollment(
210 token, is_auto_enrollment_, modes,
211 base::Bind(&EnrollmentScreen::ReportEnrollmentStatus,
212 weak_ptr_factory_.GetWeakPtr()));
215 void EnrollmentScreen::ReportEnrollmentStatus(
216 policy::EnrollmentStatus status) {
217 bool success = status.status() == policy::EnrollmentStatus::STATUS_SUCCESS;
218 enrollment_failed_once_ |= !success;
219 actor_->ShowEnrollmentStatus(status);
221 switch (status.status()) {
222 case policy::EnrollmentStatus::STATUS_SUCCESS:
223 StartupUtils::MarkDeviceRegistered();
224 UMA(is_auto_enrollment_ ? policy::kMetricEnrollmentAutoOK
225 : policy::kMetricEnrollmentOK);
226 return;
227 case policy::EnrollmentStatus::STATUS_REGISTRATION_FAILED:
228 case policy::EnrollmentStatus::STATUS_POLICY_FETCH_FAILED:
229 switch (status.client_status()) {
230 case policy::DM_STATUS_SUCCESS:
231 case policy::DM_STATUS_REQUEST_INVALID:
232 case policy::DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
233 case policy::DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
234 case policy::DM_STATUS_SERVICE_ACTIVATION_PENDING:
235 case policy::DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
236 case policy::DM_STATUS_SERVICE_POLICY_NOT_FOUND:
237 UMAFailure(policy::kMetricEnrollmentOtherFailed);
238 return;
239 case policy::DM_STATUS_REQUEST_FAILED:
240 case policy::DM_STATUS_TEMPORARY_UNAVAILABLE:
241 case policy::DM_STATUS_HTTP_STATUS_ERROR:
242 case policy::DM_STATUS_RESPONSE_DECODING_ERROR:
243 UMAFailure(policy::kMetricEnrollmentNetworkFailed);
244 return;
245 case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
246 UMAFailure(policy::kMetricEnrollmentNotSupported);
247 return;
248 case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
249 UMAFailure(policy::kMetricEnrollmentInvalidSerialNumber);
250 return;
251 case policy::DM_STATUS_SERVICE_MISSING_LICENSES:
252 UMAFailure(policy::kMetricMissingLicensesError);
253 return;
254 case policy::DM_STATUS_SERVICE_DEPROVISIONED:
255 UMAFailure(policy::kMetricEnrollmentDeprovisioned);
256 return;
258 break;
259 case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE:
260 UMAFailure(policy::kMetricEnrollmentInvalidEnrollmentMode);
261 return;
262 case policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT:
263 UMAFailure(policy::kMetricLockboxTimeoutError);
264 return;
265 case policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER:
266 UMAFailure(policy::kMetricEnrollmentWrongUserError);
267 return;
268 case policy::EnrollmentStatus::STATUS_VALIDATION_FAILED:
269 case policy::EnrollmentStatus::STATUS_STORE_ERROR:
270 case policy::EnrollmentStatus::STATUS_LOCK_ERROR:
271 UMAFailure(policy::kMetricEnrollmentOtherFailed);
272 return;
273 case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED:
274 UMAFailure(policy::kMetricEnrollmentRobotAuthCodeFetchFailed);
275 return;
276 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED:
277 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenFetchFailed);
278 return;
279 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED:
280 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenStoreFailed);
281 return;
284 NOTREACHED();
285 UMAFailure(policy::kMetricEnrollmentOtherFailed);
288 void EnrollmentScreen::UMAFailure(int sample) {
289 if (is_auto_enrollment_)
290 sample = policy::kMetricEnrollmentAutoFailed;
291 UMA(sample);
294 void EnrollmentScreen::ShowSigninScreen() {
295 actor_->Show();
296 actor_->ShowSigninScreen();
299 } // namespace chromeos