Move all typecasting code to individual screens.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / enrollment / enrollment_screen.cc
blobc6e6d842ade14f37b9833776298be6bffe455d79
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/browser_process_platform_part.h"
14 #include "chrome/browser/chromeos/login/login_utils.h"
15 #include "chrome/browser/chromeos/login/screen_manager.h"
16 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
17 #include "chrome/browser/chromeos/login/startup_utils.h"
18 #include "chrome/browser/chromeos/login/wizard_controller.h"
19 #include "chrome/browser/chromeos/policy/auto_enrollment_client.h"
20 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
21 #include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h"
22 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h"
23 #include "chromeos/dbus/cryptohome_client.h"
24 #include "chromeos/dbus/dbus_method_call_status.h"
25 #include "chromeos/dbus/dbus_thread_manager.h"
26 #include "chromeos/dbus/session_manager_client.h"
27 #include "google_apis/gaia/gaia_auth_util.h"
28 #include "google_apis/gaia/google_service_auth_error.h"
29 #include "policy/proto/device_management_backend.pb.h"
31 namespace chromeos {
33 // static
34 EnrollmentScreen* EnrollmentScreen::Get(ScreenManager* manager) {
35 return static_cast<EnrollmentScreen*>(
36 manager->GetScreen(WizardController::kEnrollmentScreenName));
39 EnrollmentScreen::EnrollmentScreen(
40 ScreenObserver* observer,
41 EnrollmentScreenActor* actor)
42 : WizardScreen(observer),
43 actor_(actor),
44 enrollment_mode_(EnrollmentScreenActor::ENROLLMENT_MODE_MANUAL),
45 enrollment_failed_once_(false),
46 remora_token_sent_(false),
47 lockbox_init_duration_(0),
48 weak_ptr_factory_(this) {
49 // Init the TPM if it has not been done until now (in debug build we might
50 // have not done that yet).
51 DBusThreadManager::Get()->GetCryptohomeClient()->TpmCanAttemptOwnership(
52 EmptyVoidDBusMethodCallback());
55 EnrollmentScreen::~EnrollmentScreen() {}
57 void EnrollmentScreen::SetParameters(
58 EnrollmentScreenActor::EnrollmentMode enrollment_mode,
59 const std::string& management_domain,
60 const std::string& user,
61 const std::string& auth_token) {
62 enrollment_mode_ = enrollment_mode;
63 user_ = user.empty() ? user : gaia::CanonicalizeEmail(user);
64 auth_token_ = auth_token;
65 actor_->SetParameters(this, enrollment_mode_, management_domain);
68 void EnrollmentScreen::PrepareToShow() {
69 actor_->PrepareToShow();
72 void EnrollmentScreen::Show() {
73 if (is_auto_enrollment() && !enrollment_failed_once_) {
74 actor_->Show();
75 UMA(policy::kMetricEnrollmentAutoStarted);
76 actor_->ShowEnrollmentSpinnerScreen();
77 actor_->FetchOAuthToken();
78 } else if (auth_token_.empty()) {
79 UMA(policy::kMetricEnrollmentTriggered);
80 actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen,
81 weak_ptr_factory_.GetWeakPtr()));
82 } else {
83 actor_->Show();
84 actor_->ShowEnrollmentSpinnerScreen();
85 OnOAuthTokenAvailable(auth_token_);
89 void EnrollmentScreen::Hide() {
90 actor_->Hide();
91 weak_ptr_factory_.InvalidateWeakPtrs();
94 std::string EnrollmentScreen::GetName() const {
95 return WizardController::kEnrollmentScreenName;
98 void EnrollmentScreen::OnLoginDone(const std::string& user) {
99 user_ = gaia::CanonicalizeEmail(user);
101 if (is_auto_enrollment())
102 UMA(policy::kMetricEnrollmentAutoRetried);
103 else if (enrollment_failed_once_)
104 UMA(policy::kMetricEnrollmentRetried);
105 else
106 UMA(policy::kMetricEnrollmentStarted);
108 actor_->ShowEnrollmentSpinnerScreen();
109 actor_->FetchOAuthToken();
112 void EnrollmentScreen::OnAuthError(const GoogleServiceAuthError& error) {
113 enrollment_failed_once_ = true;
114 actor_->ShowAuthError(error);
116 switch (error.state()) {
117 case GoogleServiceAuthError::NONE:
118 case GoogleServiceAuthError::CAPTCHA_REQUIRED:
119 case GoogleServiceAuthError::TWO_FACTOR:
120 case GoogleServiceAuthError::HOSTED_NOT_ALLOWED:
121 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
122 case GoogleServiceAuthError::REQUEST_CANCELED:
123 case GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE:
124 case GoogleServiceAuthError::SERVICE_ERROR:
125 UMAFailure(policy::kMetricEnrollmentLoginFailed);
126 LOG(ERROR) << "Auth error " << error.state();
127 return;
128 case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
129 case GoogleServiceAuthError::ACCOUNT_DELETED:
130 case GoogleServiceAuthError::ACCOUNT_DISABLED:
131 UMAFailure(policy::kMetricEnrollmentNotSupported);
132 LOG(ERROR) << "Account error " << error.state();
133 return;
134 case GoogleServiceAuthError::CONNECTION_FAILED:
135 case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
136 UMAFailure(policy::kMetricEnrollmentNetworkFailed);
137 LOG(WARNING) << "Network error " << error.state();
138 return;
139 case GoogleServiceAuthError::NUM_STATES:
140 break;
143 NOTREACHED();
144 UMAFailure(policy::kMetricEnrollmentOtherFailed);
147 void EnrollmentScreen::OnOAuthTokenAvailable(const std::string& token) {
148 VLOG(1) << "OnOAuthTokenAvailable " << token;
149 const bool is_shark =
150 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
151 GetDeviceCloudPolicyManager()->IsSharkRequisition();
153 if (is_shark && !remora_token_sent_) {
154 // Fetch a second token for shark devices.
155 remora_token_sent_ = true;
156 SendEnrollmentAuthToken(token);
157 actor_->FetchOAuthToken();
158 } else {
159 RegisterForDevicePolicy(token);
163 void EnrollmentScreen::OnRetry() {
164 actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen,
165 weak_ptr_factory_.GetWeakPtr()));
168 void EnrollmentScreen::OnCancel() {
169 if (enrollment_mode_ == EnrollmentScreenActor::ENROLLMENT_MODE_FORCED ||
170 enrollment_mode_ == EnrollmentScreenActor::ENROLLMENT_MODE_RECOVERY) {
171 actor_->ResetAuth(
172 base::Bind(&ScreenObserver::OnExit,
173 base::Unretained(get_screen_observer()),
174 ScreenObserver::ENTERPRISE_ENROLLMENT_BACK));
175 return;
178 if (is_auto_enrollment())
179 policy::AutoEnrollmentClient::CancelAutoEnrollment();
180 UMA(is_auto_enrollment() ? policy::kMetricEnrollmentAutoCancelled
181 : policy::kMetricEnrollmentCancelled);
182 actor_->ResetAuth(
183 base::Bind(&ScreenObserver::OnExit,
184 base::Unretained(get_screen_observer()),
185 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
188 void EnrollmentScreen::OnConfirmationClosed() {
189 // If the machine has been put in KIOSK mode we have to restart the session
190 // here to go in the proper KIOSK mode login screen.
191 policy::BrowserPolicyConnectorChromeOS* connector =
192 g_browser_process->platform_part()->browser_policy_connector_chromeos();
193 if (connector->GetDeviceMode() == policy::DEVICE_MODE_RETAIL_KIOSK) {
194 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
195 return;
198 if (is_auto_enrollment() &&
199 !enrollment_failed_once_ &&
200 !user_.empty() &&
201 LoginUtils::IsWhitelisted(user_, NULL)) {
202 actor_->ShowLoginSpinnerScreen();
203 get_screen_observer()->OnExit(
204 ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED);
205 } else {
206 actor_->ResetAuth(
207 base::Bind(&ScreenObserver::OnExit,
208 base::Unretained(get_screen_observer()),
209 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
213 void EnrollmentScreen::RegisterForDevicePolicy(const std::string& token) {
214 policy::BrowserPolicyConnectorChromeOS* connector =
215 g_browser_process->platform_part()->browser_policy_connector_chromeos();
216 if (connector->IsEnterpriseManaged() &&
217 connector->GetEnterpriseDomain() != gaia::ExtractDomainName(user_)) {
218 LOG(ERROR) << "Trying to re-enroll to a different domain than "
219 << connector->GetEnterpriseDomain();
220 UMAFailure(policy::kMetricEnrollmentWrongUserError);
221 actor_->ShowUIError(
222 EnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH);
223 return;
226 policy::DeviceCloudPolicyInitializer::AllowedDeviceModes device_modes;
227 device_modes[policy::DEVICE_MODE_ENTERPRISE] = true;
228 device_modes[policy::DEVICE_MODE_RETAIL_KIOSK] =
229 enrollment_mode_ == EnrollmentScreenActor::ENROLLMENT_MODE_MANUAL;
230 connector->ScheduleServiceInitialization(0);
232 policy::DeviceCloudPolicyInitializer* dcp_initializer =
233 connector->GetDeviceCloudPolicyInitializer();
234 CHECK(dcp_initializer);
235 dcp_initializer->StartEnrollment(
236 enterprise_management::PolicyData::ENTERPRISE_MANAGED,
237 connector->device_management_service(),
238 token, is_auto_enrollment(), device_modes,
239 base::Bind(&EnrollmentScreen::ReportEnrollmentStatus,
240 weak_ptr_factory_.GetWeakPtr()));
243 void EnrollmentScreen::SendEnrollmentAuthToken(const std::string& token) {
244 // TODO(achuith, zork): Send token via Bluetooth to remote device.
247 void EnrollmentScreen::ShowEnrollmentStatusOnSuccess(
248 const policy::EnrollmentStatus& status) {
249 actor_->ShowEnrollmentStatus(status);
250 StartupUtils::MarkOobeCompleted();
253 void EnrollmentScreen::ReportEnrollmentStatus(policy::EnrollmentStatus status) {
254 if (status.status() == policy::EnrollmentStatus::STATUS_SUCCESS) {
255 StartupUtils::MarkDeviceRegistered(
256 base::Bind(&EnrollmentScreen::ShowEnrollmentStatusOnSuccess,
257 weak_ptr_factory_.GetWeakPtr(),
258 status));
259 UMA(is_auto_enrollment() ? policy::kMetricEnrollmentAutoOK
260 : policy::kMetricEnrollmentOK);
261 return;
262 } else {
263 enrollment_failed_once_ = true;
265 actor_->ShowEnrollmentStatus(status);
267 switch (status.status()) {
268 case policy::EnrollmentStatus::STATUS_REGISTRATION_FAILED:
269 case policy::EnrollmentStatus::STATUS_POLICY_FETCH_FAILED:
270 switch (status.client_status()) {
271 case policy::DM_STATUS_SUCCESS:
272 case policy::DM_STATUS_REQUEST_INVALID:
273 case policy::DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
274 case policy::DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
275 case policy::DM_STATUS_SERVICE_ACTIVATION_PENDING:
276 case policy::DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
277 case policy::DM_STATUS_SERVICE_POLICY_NOT_FOUND:
278 UMAFailure(policy::kMetricEnrollmentOtherFailed);
279 return;
280 case policy::DM_STATUS_REQUEST_FAILED:
281 case policy::DM_STATUS_TEMPORARY_UNAVAILABLE:
282 case policy::DM_STATUS_HTTP_STATUS_ERROR:
283 case policy::DM_STATUS_RESPONSE_DECODING_ERROR:
284 UMAFailure(policy::kMetricEnrollmentNetworkFailed);
285 return;
286 case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
287 UMAFailure(policy::kMetricEnrollmentNotSupported);
288 return;
289 case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
290 UMAFailure(policy::kMetricEnrollmentInvalidSerialNumber);
291 return;
292 case policy::DM_STATUS_SERVICE_MISSING_LICENSES:
293 UMAFailure(policy::kMetricMissingLicensesError);
294 return;
295 case policy::DM_STATUS_SERVICE_DEPROVISIONED:
296 UMAFailure(policy::kMetricEnrollmentDeprovisioned);
297 return;
298 case policy::DM_STATUS_SERVICE_DOMAIN_MISMATCH:
299 UMAFailure(policy::kMetricEnrollmentDomainMismatch);
300 return;
302 break;
303 case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE:
304 UMAFailure(policy::kMetricEnrollmentInvalidEnrollmentMode);
305 return;
306 case policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT:
307 UMAFailure(policy::kMetricLockboxTimeoutError);
308 return;
309 case policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER:
310 UMAFailure(policy::kMetricEnrollmentWrongUserError);
311 return;
312 case policy::EnrollmentStatus::STATUS_NO_STATE_KEYS:
313 UMAFailure(policy::kMetricEnrollmentNoStateKeys);
314 return;
315 case policy::EnrollmentStatus::STATUS_VALIDATION_FAILED:
316 UMAFailure(policy::kMetricEnrollmentPolicyValidationFailed);
317 return;
318 case policy::EnrollmentStatus::STATUS_STORE_ERROR:
319 UMAFailure(policy::kMetricEnrollmentCloudPolicyStoreError);
320 return;
321 case policy::EnrollmentStatus::STATUS_LOCK_ERROR:
322 UMAFailure(policy::kMetricEnrollmentLockBackendError);
323 return;
324 case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED:
325 UMAFailure(policy::kMetricEnrollmentRobotAuthCodeFetchFailed);
326 return;
327 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED:
328 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenFetchFailed);
329 return;
330 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED:
331 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenStoreFailed);
332 return;
333 case policy::EnrollmentStatus::STATUS_STORE_TOKEN_AND_ID_FAILED:
334 // This error should not happen for enterprise enrollment.
335 UMAFailure(policy::kMetricEnrollmentStoreTokenAndIdFailed);
336 NOTREACHED();
337 return;
338 case policy::EnrollmentStatus::STATUS_SUCCESS:
339 NOTREACHED();
340 return;
343 NOTREACHED();
344 UMAFailure(policy::kMetricEnrollmentOtherFailed);
347 void EnrollmentScreen::UMA(policy::MetricEnrollment sample) {
348 if (enrollment_mode_ == EnrollmentScreenActor::ENROLLMENT_MODE_RECOVERY) {
349 UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollmentRecovery, sample,
350 policy::kMetricEnrollmentSize);
351 } else {
352 UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment, sample,
353 policy::kMetricEnrollmentSize);
357 void EnrollmentScreen::UMAFailure(policy::MetricEnrollment sample) {
358 if (is_auto_enrollment())
359 sample = policy::kMetricEnrollmentAutoFailed;
360 UMA(sample);
363 void EnrollmentScreen::ShowSigninScreen() {
364 actor_->Show();
365 actor_->ShowSigninScreen();
368 } // namespace chromeos