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/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"
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 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_
) {
74 UMA(policy::kMetricEnrollmentAutoStarted
);
75 actor_
->ShowEnrollmentSpinnerScreen();
76 actor_
->FetchOAuthToken();
78 actor_
->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen
,
79 weak_ptr_factory_
.GetWeakPtr()));
83 void EnrollmentScreen::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();
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();
125 case GoogleServiceAuthError::CONNECTION_FAILED
:
126 case GoogleServiceAuthError::SERVICE_UNAVAILABLE
:
127 UMAFailure(policy::kMetricEnrollmentNetworkFailed
);
128 LOG(WARNING
) << "Network error " << error
.state();
130 case GoogleServiceAuthError::NUM_STATES
:
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_
) {
151 base::Bind(&ScreenObserver::OnExit
,
152 base::Unretained(get_screen_observer()),
153 ScreenObserver::ENTERPRISE_ENROLLMENT_BACK
));
157 if (is_auto_enrollment_
)
158 policy::AutoEnrollmentClient::CancelAutoEnrollment();
159 UMA(is_auto_enrollment_
? policy::kMetricEnrollmentAutoCancelled
160 : policy::kMetricEnrollmentCancelled
);
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();
176 if (is_auto_enrollment_
&&
177 !enrollment_failed_once_
&&
179 LoginUtils::IsWhitelisted(user_
)) {
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::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
);
201 EnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH
);
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
);
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
);
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
);
245 case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED
:
246 UMAFailure(policy::kMetricEnrollmentNotSupported
);
248 case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER
:
249 UMAFailure(policy::kMetricEnrollmentInvalidSerialNumber
);
251 case policy::DM_STATUS_SERVICE_MISSING_LICENSES
:
252 UMAFailure(policy::kMetricMissingLicensesError
);
254 case policy::DM_STATUS_SERVICE_DEPROVISIONED
:
255 UMAFailure(policy::kMetricEnrollmentDeprovisioned
);
259 case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE
:
260 UMAFailure(policy::kMetricEnrollmentInvalidEnrollmentMode
);
262 case policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT
:
263 UMAFailure(policy::kMetricLockboxTimeoutError
);
265 case policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER
:
266 UMAFailure(policy::kMetricEnrollmentWrongUserError
);
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
);
273 case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED
:
274 UMAFailure(policy::kMetricEnrollmentRobotAuthCodeFetchFailed
);
276 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED
:
277 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenFetchFailed
);
279 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED
:
280 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenStoreFailed
);
285 UMAFailure(policy::kMetricEnrollmentOtherFailed
);
288 void EnrollmentScreen::UMAFailure(int sample
) {
289 if (is_auto_enrollment_
)
290 sample
= policy::kMetricEnrollmentAutoFailed
;
294 void EnrollmentScreen::ShowSigninScreen() {
296 actor_
->ShowSigninScreen();
299 } // namespace chromeos