enrollment_screen.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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. 4 5#include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h" 6 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/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" 27 28namespace chromeos { 29 30namespace { 31 32void UMA(int sample) { 33 UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment, 34 sample, 35 policy::kMetricEnrollmentSize); 36} 37 38} // namespace 39 40EnrollmentScreen::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()); 54} 55 56EnrollmentScreen::~EnrollmentScreen() {} 57 58void 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_); 65} 66 67void EnrollmentScreen::PrepareToShow() { 68 actor_->PrepareToShow(); 69} 70 71void 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())); 80 } 81} 82 83void EnrollmentScreen::Hide() { 84 actor_->Hide(); 85 weak_ptr_factory_.InvalidateWeakPtrs(); 86} 87 88std::string EnrollmentScreen::GetName() const { 89 return WizardController::kEnrollmentScreenName; 90} 91 92void EnrollmentScreen::OnLoginDone(const std::string& user) { 93 user_ = gaia::CanonicalizeEmail(user); 94 95 UMA(is_auto_enrollment_ ? policy::kMetricEnrollmentAutoRetried 96 : policy::kMetricEnrollmentStarted); 97 98 actor_->ShowEnrollmentSpinnerScreen(); 99 actor_->FetchOAuthToken(); 100} 101 102void EnrollmentScreen::OnAuthError( 103 const GoogleServiceAuthError& error) { 104 enrollment_failed_once_ = true; 105 actor_->ShowAuthError(error); 106 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; 132 } 133 134 NOTREACHED(); 135 UMAFailure(policy::kMetricEnrollmentOtherFailed); 136} 137 138void EnrollmentScreen::OnOAuthTokenAvailable( 139 const std::string& token) { 140 RegisterForDevicePolicy(token); 141} 142 143void EnrollmentScreen::OnRetry() { 144 actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen, 145 weak_ptr_factory_.GetWeakPtr())); 146} 147 148void 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; 155 } 156 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)); 165} 166 167void 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 policy::BrowserPolicyConnectorChromeOS* connector = 171 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 172 if (connector->GetDeviceMode() == policy::DEVICE_MODE_RETAIL_KIOSK) { 173 DBusThreadManager::Get()->GetSessionManagerClient()->StopSession(); 174 return; 175 } 176 177 if (is_auto_enrollment_ && 178 !enrollment_failed_once_ && 179 !user_.empty() && 180 LoginUtils::IsWhitelisted(user_, NULL)) { 181 actor_->ShowLoginSpinnerScreen(); 182 get_screen_observer()->OnExit( 183 ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED); 184 } else { 185 actor_->ResetAuth( 186 base::Bind(&ScreenObserver::OnExit, 187 base::Unretained(get_screen_observer()), 188 ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED)); 189 } 190} 191 192void EnrollmentScreen::RegisterForDevicePolicy( 193 const std::string& token) { 194 policy::BrowserPolicyConnectorChromeOS* connector = 195 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 196 if (connector->IsEnterpriseManaged() && 197 connector->GetEnterpriseDomain() != gaia::ExtractDomainName(user_)) { 198 LOG(ERROR) << "Trying to re-enroll to a different domain than " 199 << connector->GetEnterpriseDomain(); 200 UMAFailure(policy::kMetricEnrollmentWrongUserError); 201 actor_->ShowUIError( 202 EnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH); 203 return; 204 } 205 206 policy::DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes modes; 207 modes[policy::DEVICE_MODE_ENTERPRISE] = true; 208 modes[policy::DEVICE_MODE_RETAIL_KIOSK] = !is_auto_enrollment_; 209 connector->ScheduleServiceInitialization(0); 210 connector->GetDeviceCloudPolicyManager()->StartEnrollment( 211 token, is_auto_enrollment_, modes, 212 base::Bind(&EnrollmentScreen::ReportEnrollmentStatus, 213 weak_ptr_factory_.GetWeakPtr())); 214} 215 216void EnrollmentScreen::ReportEnrollmentStatus( 217 policy::EnrollmentStatus status) { 218 bool success = status.status() == policy::EnrollmentStatus::STATUS_SUCCESS; 219 enrollment_failed_once_ |= !success; 220 actor_->ShowEnrollmentStatus(status); 221 222 switch (status.status()) { 223 case policy::EnrollmentStatus::STATUS_SUCCESS: 224 StartupUtils::MarkDeviceRegistered(); 225 UMA(is_auto_enrollment_ ? policy::kMetricEnrollmentAutoOK 226 : policy::kMetricEnrollmentOK); 227 return; 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); 239 return; 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); 245 return; 246 case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED: 247 UMAFailure(policy::kMetricEnrollmentNotSupported); 248 return; 249 case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER: 250 UMAFailure(policy::kMetricEnrollmentInvalidSerialNumber); 251 return; 252 case policy::DM_STATUS_SERVICE_MISSING_LICENSES: 253 UMAFailure(policy::kMetricMissingLicensesError); 254 return; 255 case policy::DM_STATUS_SERVICE_DEPROVISIONED: 256 UMAFailure(policy::kMetricEnrollmentDeprovisioned); 257 return; 258 } 259 break; 260 case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE: 261 UMAFailure(policy::kMetricEnrollmentInvalidEnrollmentMode); 262 return; 263 case policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT: 264 UMAFailure(policy::kMetricLockboxTimeoutError); 265 return; 266 case policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER: 267 UMAFailure(policy::kMetricEnrollmentWrongUserError); 268 return; 269 case policy::EnrollmentStatus::STATUS_VALIDATION_FAILED: 270 case policy::EnrollmentStatus::STATUS_STORE_ERROR: 271 case policy::EnrollmentStatus::STATUS_LOCK_ERROR: 272 UMAFailure(policy::kMetricEnrollmentOtherFailed); 273 return; 274 case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED: 275 UMAFailure(policy::kMetricEnrollmentRobotAuthCodeFetchFailed); 276 return; 277 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED: 278 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenFetchFailed); 279 return; 280 case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED: 281 UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenStoreFailed); 282 return; 283 } 284 285 NOTREACHED(); 286 UMAFailure(policy::kMetricEnrollmentOtherFailed); 287} 288 289void EnrollmentScreen::UMAFailure(int sample) { 290 if (is_auto_enrollment_) 291 sample = policy::kMetricEnrollmentAutoFailed; 292 UMA(sample); 293} 294 295void EnrollmentScreen::ShowSigninScreen() { 296 actor_->Show(); 297 actor_->ShowSigninScreen(); 298} 299 300} // namespace chromeos 301