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"
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/browser_policy_connector_chromeos.h"
19 #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.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"
32 void UMA(int sample) {
33 UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment,
35 policy::kMetricEnrollmentSize);
40 EnrollmentScreen::EnrollmentScreen(
41 ScreenObserver* observer,
42 EnrollmentScreenActor* actor)
43 : WizardScreen(observer),
45 enrollment_mode_(EnrollmentScreenActor::ENROLLMENT_MODE_MANUAL),
46 enrollment_failed_once_(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 enrollment_mode_ = enrollment_mode;
62 user_ = user.empty() ? user : gaia::CanonicalizeEmail(user);
63 actor_->SetParameters(this, enrollment_mode_, management_domain);
66 void EnrollmentScreen::PrepareToShow() {
67 actor_->PrepareToShow();
70 void EnrollmentScreen::Show() {
71 if (is_auto_enrollment() && !enrollment_failed_once_) {
73 UMA(policy::kMetricEnrollmentAutoStarted);
74 actor_->ShowEnrollmentSpinnerScreen();
75 actor_->FetchOAuthToken();
77 actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen,
78 weak_ptr_factory_.GetWeakPtr()));
82 void EnrollmentScreen::Hide() {
84 weak_ptr_factory_.InvalidateWeakPtrs();
87 std::string EnrollmentScreen::GetName() const {
88 return WizardController::kEnrollmentScreenName;
91 void EnrollmentScreen::OnLoginDone(const std::string& user) {
92 user_ = gaia::CanonicalizeEmail(user);
94 UMA(is_auto_enrollment() ? policy::kMetricEnrollmentAutoRetried
95 : policy::kMetricEnrollmentStarted);
97 actor_->ShowEnrollmentSpinnerScreen();
98 actor_->FetchOAuthToken();
101 void EnrollmentScreen::OnAuthError(
102 const GoogleServiceAuthError& error) {
103 enrollment_failed_once_ = true;
104 actor_->ShowAuthError(error);
106 switch (error.state()) {
107 case GoogleServiceAuthError::NONE:
108 case GoogleServiceAuthError::CAPTCHA_REQUIRED:
109 case GoogleServiceAuthError::TWO_FACTOR:
110 case GoogleServiceAuthError::HOSTED_NOT_ALLOWED:
111 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
112 case GoogleServiceAuthError::REQUEST_CANCELED:
113 case GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE:
114 case GoogleServiceAuthError::SERVICE_ERROR:
115 UMAFailure(policy::kMetricEnrollmentLoginFailed);
116 LOG(ERROR) << "Auth error " << error.state();
118 case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
119 case GoogleServiceAuthError::ACCOUNT_DELETED:
120 case GoogleServiceAuthError::ACCOUNT_DISABLED:
121 UMAFailure(policy::kMetricEnrollmentNotSupported);
122 LOG(ERROR) << "Account error " << error.state();
124 case GoogleServiceAuthError::CONNECTION_FAILED:
125 case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
126 UMAFailure(policy::kMetricEnrollmentNetworkFailed);
127 LOG(WARNING) << "Network error " << error.state();
129 case GoogleServiceAuthError::NUM_STATES:
134 UMAFailure(policy::kMetricEnrollmentOtherFailed);
137 void EnrollmentScreen::OnOAuthTokenAvailable(
138 const std::string& token) {
139 RegisterForDevicePolicy(token);
142 void EnrollmentScreen::OnRetry() {
143 actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen,
144 weak_ptr_factory_.GetWeakPtr()));
147 void EnrollmentScreen::OnCancel() {
148 if (enrollment_mode_ == EnrollmentScreenActor::ENROLLMENT_MODE_FORCED) {
150 base::Bind(&ScreenObserver::OnExit,
151 base::Unretained(get_screen_observer()),
152 ScreenObserver::ENTERPRISE_ENROLLMENT_BACK));
156 if (is_auto_enrollment())
157 policy::AutoEnrollmentClient::CancelAutoEnrollment();
158 UMA(is_auto_enrollment() ? policy::kMetricEnrollmentAutoCancelled
159 : policy::kMetricEnrollmentCancelled);
161 base::Bind(&ScreenObserver::OnExit,
162 base::Unretained(get_screen_observer()),
163 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
166 void EnrollmentScreen::OnConfirmationClosed() {
167 // If the machine has been put in KIOSK mode we have to restart the session
168 // here to go in the proper KIOSK mode login screen.
169 policy::BrowserPolicyConnectorChromeOS* connector =
170 g_browser_process->platform_part()->browser_policy_connector_chromeos();
171 if (connector->GetDeviceMode() == policy::DEVICE_MODE_RETAIL_KIOSK) {
172 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
176 if (is_auto_enrollment() &&
177 !enrollment_failed_once_ &&
179 LoginUtils::IsWhitelisted(user_, NULL)) {
180 actor_->ShowLoginSpinnerScreen();
181 get_screen_observer()->OnExit(
182 ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED);
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::BrowserPolicyConnectorChromeOS* connector =
194 g_browser_process->platform_part()->browser_policy_connector_chromeos();
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);
201 EnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH);
205 policy::DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes device_modes;
206 device_modes[policy::DEVICE_MODE_ENTERPRISE] = true;
207 device_modes[policy::DEVICE_MODE_RETAIL_KIOSK] =
208 enrollment_mode_ == EnrollmentScreenActor::ENROLLMENT_MODE_MANUAL;
209 connector->ScheduleServiceInitialization(0);
210 connector->GetDeviceCloudPolicyManager()->StartEnrollment(
211 token, is_auto_enrollment(), device_modes,
212 base::Bind(&EnrollmentScreen::ReportEnrollmentStatus,
213 weak_ptr_factory_.GetWeakPtr()));
216 void EnrollmentScreen::ReportEnrollmentStatus(
217 policy::EnrollmentStatus status) {
218 bool success = status.status() == policy::EnrollmentStatus::STATUS_SUCCESS;
219 enrollment_failed_once_ |= !success;
220 actor_->ShowEnrollmentStatus(status);
222 switch (status.status()) {
223 case policy::EnrollmentStatus::STATUS_SUCCESS:
224 StartupUtils::MarkDeviceRegistered();
225 UMA(is_auto_enrollment() ? policy::kMetricEnrollmentAutoOK
226 : policy::kMetricEnrollmentOK);
228 case policy::EnrollmentStatus::STATUS_REGISTRATION_FAILED:
229 case policy::EnrollmentStatus::STATUS_POLICY_FETCH_FAILED:
230 switch (status.client_status()) {
231 case policy::DM_STATUS_SUCCESS:
232 case policy::DM_STATUS_REQUEST_INVALID:
233 case policy::DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
234 case policy::DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
235 case policy::DM_STATUS_SERVICE_ACTIVATION_PENDING:
236 case policy::DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
237 case policy::DM_STATUS_SERVICE_POLICY_NOT_FOUND:
238 UMAFailure(policy::kMetricEnrollmentOtherFailed);
240 case policy::DM_STATUS_REQUEST_FAILED:
241 case policy::DM_STATUS_TEMPORARY_UNAVAILABLE:
242 case policy::DM_STATUS_HTTP_STATUS_ERROR:
243 case policy::DM_STATUS_RESPONSE_DECODING_ERROR:
244 UMAFailure(policy::kMetricEnrollmentNetworkFailed);
246 case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
247 UMAFailure(policy::kMetricEnrollmentNotSupported);
249 case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
250 UMAFailure(policy::kMetricEnrollmentInvalidSerialNumber);
252 case policy::DM_STATUS_SERVICE_MISSING_LICENSES:
253 UMAFailure(policy::kMetricMissingLicensesError);
255 case policy::DM_STATUS_SERVICE_DEPROVISIONED:
256 UMAFailure(policy::kMetricEnrollmentDeprovisioned);
258 case policy::DM_STATUS_SERVICE_DOMAIN_MISMATCH:
259 UMAFailure(policy::kMetricEnrollmentDomainMismatch);
263 case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE:
264 UMAFailure(policy::kMetricEnrollmentInvalidEnrollmentMode);
266 case policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT:
267 UMAFailure(policy::kMetricLockboxTimeoutError);
269 case policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER:
270 UMAFailure(policy::kMetricEnrollmentWrongUserError);
272 case policy::EnrollmentStatus::STATUS_NO_STATE_KEYS:
273 case policy::EnrollmentStatus::STATUS_VALIDATION_FAILED:
274 case policy::EnrollmentStatus::STATUS_STORE_ERROR:
275 case policy::EnrollmentStatus::STATUS_LOCK_ERROR:
276 UMAFailure(policy::kMetricEnrollmentOtherFailed);
278 case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED:
279 UMAFailure(policy::kMetricEnrollmentRobotAuthCodeFetchFailed);
281 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED:
282 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenFetchFailed);
284 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED:
285 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenStoreFailed);
290 UMAFailure(policy::kMetricEnrollmentOtherFailed);
293 void EnrollmentScreen::UMAFailure(int sample) {
294 if (is_auto_enrollment())
295 sample = policy::kMetricEnrollmentAutoFailed;
299 void EnrollmentScreen::ShowSigninScreen() {
301 actor_->ShowSigninScreen();
304 } // namespace chromeos