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 "chrome/browser/policy/cloud/enterprise_metrics.h"
21 #include "chromeos/dbus/cryptohome_client.h"
22 #include "chromeos/dbus/dbus_method_call_status.h"
23 #include "chromeos/dbus/dbus_thread_manager.h"
24 #include "chromeos/dbus/session_manager_client.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_) {
150 NOTREACHED() << "Cancellation should not be permitted";
154 if (is_auto_enrollment_)
155 policy::AutoEnrollmentClient::CancelAutoEnrollment();
156 UMA(is_auto_enrollment_ ? policy::kMetricEnrollmentAutoCancelled
157 : policy::kMetricEnrollmentCancelled);
159 base::Bind(&ScreenObserver::OnExit,
160 base::Unretained(get_screen_observer()),
161 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
164 void EnrollmentScreen::OnConfirmationClosed() {
165 // If the machine has been put in KIOSK mode we have to restart the session
166 // here to go in the proper KIOSK mode login screen.
167 if (g_browser_process->browser_policy_connector()->GetDeviceMode() ==
168 policy::DEVICE_MODE_RETAIL_KIOSK) {
169 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
173 if (is_auto_enrollment_ &&
174 !enrollment_failed_once_ &&
176 LoginUtils::IsWhitelisted(user_)) {
177 actor_->ShowLoginSpinnerScreen();
178 get_screen_observer()->OnExit(
179 ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED);
182 base::Bind(&ScreenObserver::OnExit,
183 base::Unretained(get_screen_observer()),
184 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
188 void EnrollmentScreen::RegisterForDevicePolicy(
189 const std::string& token) {
190 policy::BrowserPolicyConnector* connector =
191 g_browser_process->browser_policy_connector();
192 if (connector->IsEnterpriseManaged() &&
193 connector->GetEnterpriseDomain() != gaia::ExtractDomainName(user_)) {
194 LOG(ERROR) << "Trying to re-enroll to a different domain than "
195 << connector->GetEnterpriseDomain();
196 UMAFailure(policy::kMetricEnrollmentWrongUserError);
198 EnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH);
202 policy::DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes modes;
203 modes[policy::DEVICE_MODE_ENTERPRISE] = true;
204 modes[policy::DEVICE_MODE_RETAIL_KIOSK] = !is_auto_enrollment_;
205 connector->ScheduleServiceInitialization(0);
206 connector->GetDeviceCloudPolicyManager()->StartEnrollment(
207 token, is_auto_enrollment_, modes,
208 base::Bind(&EnrollmentScreen::ReportEnrollmentStatus,
209 weak_ptr_factory_.GetWeakPtr()));
212 void EnrollmentScreen::ReportEnrollmentStatus(
213 policy::EnrollmentStatus status) {
214 bool success = status.status() == policy::EnrollmentStatus::STATUS_SUCCESS;
215 enrollment_failed_once_ |= !success;
216 actor_->ShowEnrollmentStatus(status);
218 switch (status.status()) {
219 case policy::EnrollmentStatus::STATUS_SUCCESS:
220 StartupUtils::MarkDeviceRegistered();
221 UMA(is_auto_enrollment_ ? policy::kMetricEnrollmentAutoOK
222 : policy::kMetricEnrollmentOK);
224 case policy::EnrollmentStatus::STATUS_REGISTRATION_FAILED:
225 case policy::EnrollmentStatus::STATUS_POLICY_FETCH_FAILED:
226 switch (status.client_status()) {
227 case policy::DM_STATUS_SUCCESS:
228 case policy::DM_STATUS_REQUEST_INVALID:
229 case policy::DM_STATUS_SERVICE_DEVICE_NOT_FOUND:
230 case policy::DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID:
231 case policy::DM_STATUS_SERVICE_ACTIVATION_PENDING:
232 case policy::DM_STATUS_SERVICE_DEVICE_ID_CONFLICT:
233 case policy::DM_STATUS_SERVICE_POLICY_NOT_FOUND:
234 UMAFailure(policy::kMetricEnrollmentOtherFailed);
236 case policy::DM_STATUS_REQUEST_FAILED:
237 case policy::DM_STATUS_TEMPORARY_UNAVAILABLE:
238 case policy::DM_STATUS_HTTP_STATUS_ERROR:
239 case policy::DM_STATUS_RESPONSE_DECODING_ERROR:
240 UMAFailure(policy::kMetricEnrollmentNetworkFailed);
242 case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
243 UMAFailure(policy::kMetricEnrollmentNotSupported);
245 case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
246 UMAFailure(policy::kMetricEnrollmentInvalidSerialNumber);
248 case policy::DM_STATUS_SERVICE_MISSING_LICENSES:
249 UMAFailure(policy::kMetricMissingLicensesError);
253 case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE:
254 UMAFailure(policy::kMetricEnrollmentInvalidEnrollmentMode);
256 case policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT:
257 UMAFailure(policy::kMetricLockboxTimeoutError);
259 case policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER:
260 UMAFailure(policy::kMetricEnrollmentWrongUserError);
262 case policy::EnrollmentStatus::STATUS_VALIDATION_FAILED:
263 case policy::EnrollmentStatus::STATUS_STORE_ERROR:
264 case policy::EnrollmentStatus::STATUS_LOCK_ERROR:
265 UMAFailure(policy::kMetricEnrollmentOtherFailed);
267 case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED:
268 UMAFailure(policy::kMetricEnrollmentRobotAuthCodeFetchFailed);
270 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED:
271 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenFetchFailed);
273 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED:
274 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenStoreFailed);
279 UMAFailure(policy::kMetricEnrollmentOtherFailed);
282 void EnrollmentScreen::UMAFailure(int sample) {
283 if (is_auto_enrollment_)
284 sample = policy::kMetricEnrollmentAutoFailed;
288 void EnrollmentScreen::ShowSigninScreen() {
290 actor_->ShowSigninScreen();
293 } // namespace chromeos