- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / enrollment / enrollment_screen.cc
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/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"
27
28 namespace chromeos {
29
30 namespace {
31
32 void UMA(int sample) {
33   UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment,
34                             sample,
35                             policy::kMetricEnrollmentSize);
36 }
37
38 }  // namespace
39
40 EnrollmentScreen::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
56 EnrollmentScreen::~EnrollmentScreen() {}
57
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_);
65 }
66
67 void EnrollmentScreen::PrepareToShow() {
68   actor_->PrepareToShow();
69 }
70
71 void 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
83 void EnrollmentScreen::Hide() {
84   actor_->Hide();
85   weak_ptr_factory_.InvalidateWeakPtrs();
86 }
87
88 std::string EnrollmentScreen::GetName() const {
89   return WizardController::kEnrollmentScreenName;
90 }
91
92 void 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
102 void 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
138 void EnrollmentScreen::OnOAuthTokenAvailable(
139     const std::string& token) {
140   RegisterForDevicePolicy(token);
141 }
142
143 void EnrollmentScreen::OnRetry() {
144   actor_->ResetAuth(base::Bind(&EnrollmentScreen::ShowSigninScreen,
145                                weak_ptr_factory_.GetWeakPtr()));
146 }
147
148 void EnrollmentScreen::OnCancel() {
149   if (!can_exit_enrollment_) {
150     NOTREACHED() << "Cancellation should not be permitted";
151     return;
152   }
153
154   if (is_auto_enrollment_)
155     policy::AutoEnrollmentClient::CancelAutoEnrollment();
156   UMA(is_auto_enrollment_ ? policy::kMetricEnrollmentAutoCancelled
157                           : policy::kMetricEnrollmentCancelled);
158   actor_->ResetAuth(
159       base::Bind(&ScreenObserver::OnExit,
160                  base::Unretained(get_screen_observer()),
161                  ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
162 }
163
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();
170     return;
171   }
172
173   if (is_auto_enrollment_ &&
174       !enrollment_failed_once_ &&
175       !user_.empty() &&
176       LoginUtils::IsWhitelisted(user_)) {
177     actor_->ShowLoginSpinnerScreen();
178     get_screen_observer()->OnExit(
179         ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED);
180   } else {
181     actor_->ResetAuth(
182         base::Bind(&ScreenObserver::OnExit,
183                    base::Unretained(get_screen_observer()),
184                    ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED));
185   }
186 }
187
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);
197     actor_->ShowUIError(
198         EnrollmentScreenActor::UI_ERROR_DOMAIN_MISMATCH);
199     return;
200   }
201
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()));
210 }
211
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);
217
218   switch (status.status()) {
219     case policy::EnrollmentStatus::STATUS_SUCCESS:
220       StartupUtils::MarkDeviceRegistered();
221       UMA(is_auto_enrollment_ ? policy::kMetricEnrollmentAutoOK
222                               : policy::kMetricEnrollmentOK);
223       return;
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);
235           return;
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);
241           return;
242         case policy::DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED:
243           UMAFailure(policy::kMetricEnrollmentNotSupported);
244           return;
245         case policy::DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER:
246           UMAFailure(policy::kMetricEnrollmentInvalidSerialNumber);
247           return;
248         case policy::DM_STATUS_SERVICE_MISSING_LICENSES:
249           UMAFailure(policy::kMetricMissingLicensesError);
250           return;
251       }
252       break;
253     case policy::EnrollmentStatus::STATUS_REGISTRATION_BAD_MODE:
254       UMAFailure(policy::kMetricEnrollmentInvalidEnrollmentMode);
255       return;
256     case policy::EnrollmentStatus::STATUS_LOCK_TIMEOUT:
257       UMAFailure(policy::kMetricLockboxTimeoutError);
258       return;
259     case policy::EnrollmentStatus::STATUS_LOCK_WRONG_USER:
260       UMAFailure(policy::kMetricEnrollmentWrongUserError);
261       return;
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);
266       return;
267     case policy::EnrollmentStatus::STATUS_ROBOT_AUTH_FETCH_FAILED:
268       UMAFailure(policy::kMetricEnrollmentRobotAuthCodeFetchFailed);
269       return;
270     case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_FETCH_FAILED:
271       UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenFetchFailed);
272       return;
273     case policy::EnrollmentStatus::STATUS_ROBOT_REFRESH_STORE_FAILED:
274       UMAFailure(policy::kMetricEnrollmentRobotRefreshTokenStoreFailed);
275       return;
276   }
277
278   NOTREACHED();
279   UMAFailure(policy::kMetricEnrollmentOtherFailed);
280 }
281
282 void EnrollmentScreen::UMAFailure(int sample) {
283   if (is_auto_enrollment_)
284     sample = policy::kMetricEnrollmentAutoFailed;
285   UMA(sample);
286 }
287
288 void EnrollmentScreen::ShowSigninScreen() {
289   actor_->Show();
290   actor_->ShowSigninScreen();
291 }
292
293 }  // namespace chromeos