Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / login / enrollment / auto_enrollment_check_screen.cc
blob0d79aeed399fdf121ffbb1ba35a07bb004ce251c
1 // Copyright 2014 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/auto_enrollment_check_screen.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
12 #include "chrome/browser/chromeos/login/screen_manager.h"
13 #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h"
14 #include "chrome/browser/chromeos/login/screens/error_screen.h"
15 #include "chrome/browser/chromeos/login/screens/network_error.h"
16 #include "chrome/browser/chromeos/login/wizard_controller.h"
17 #include "chromeos/chromeos_switches.h"
18 #include "chromeos/network/network_state.h"
19 #include "chromeos/network/network_state_handler.h"
21 namespace chromeos {
23 namespace {
25 NetworkPortalDetector::CaptivePortalStatus GetCaptivePortalStatus() {
26 const NetworkState* default_network =
27 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
28 return default_network
29 ? NetworkPortalDetector::Get()
30 ->GetCaptivePortalState(default_network->guid())
31 .status
32 : NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN;
35 } // namespace
37 // static
38 AutoEnrollmentCheckScreen* AutoEnrollmentCheckScreen::Get(
39 ScreenManager* manager) {
40 return static_cast<AutoEnrollmentCheckScreen*>(
41 manager->GetScreen(WizardController::kAutoEnrollmentCheckScreenName));
44 AutoEnrollmentCheckScreen::AutoEnrollmentCheckScreen(
45 BaseScreenDelegate* base_screen_delegate,
46 AutoEnrollmentCheckScreenActor* actor)
47 : BaseScreen(base_screen_delegate),
48 actor_(actor),
49 auto_enrollment_controller_(nullptr),
50 captive_portal_status_(
51 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN),
52 auto_enrollment_state_(policy::AUTO_ENROLLMENT_STATE_IDLE),
53 histogram_helper_(new ErrorScreensHistogramHelper("Enrollment")),
54 weak_ptr_factory_(this) {
55 if (actor_)
56 actor_->SetDelegate(this);
59 AutoEnrollmentCheckScreen::~AutoEnrollmentCheckScreen() {
60 NetworkPortalDetector::Get()->RemoveObserver(this);
61 if (actor_)
62 actor_->SetDelegate(NULL);
65 void AutoEnrollmentCheckScreen::ClearState() {
66 auto_enrollment_progress_subscription_.reset();
67 connect_request_subscription_.reset();
68 NetworkPortalDetector::Get()->RemoveObserver(this);
70 auto_enrollment_state_ = policy::AUTO_ENROLLMENT_STATE_IDLE;
71 captive_portal_status_ = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN;
74 void AutoEnrollmentCheckScreen::PrepareToShow() {
77 void AutoEnrollmentCheckScreen::Show() {
78 // If the decision got made already, don't show the screen at all.
79 if (AutoEnrollmentController::GetMode() !=
80 AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT ||
81 IsCompleted()) {
82 SignalCompletion();
83 return;
86 // Start from a clean slate.
87 ClearState();
89 // Bring up the screen. It's important to do this before updating the UI,
90 // because the latter may switch to the error screen, which needs to stay on
91 // top.
92 actor_->Show();
93 histogram_helper_->OnScreenShow();
95 // Set up state change observers.
96 auto_enrollment_progress_subscription_ =
97 auto_enrollment_controller_->RegisterProgressCallback(
98 base::Bind(
99 &AutoEnrollmentCheckScreen::OnAutoEnrollmentCheckProgressed,
100 base::Unretained(this)));
101 NetworkPortalDetector* portal_detector = NetworkPortalDetector::Get();
102 portal_detector->AddObserver(this);
104 // Perform an initial UI update.
105 NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status =
106 GetCaptivePortalStatus();
107 policy::AutoEnrollmentState new_auto_enrollment_state =
108 auto_enrollment_controller_->state();
110 if (!UpdateCaptivePortalStatus(new_captive_portal_status))
111 UpdateAutoEnrollmentState(new_auto_enrollment_state);
113 captive_portal_status_ = new_captive_portal_status;
114 auto_enrollment_state_ = new_auto_enrollment_state;
116 // Make sure gears are in motion in the background.
117 auto_enrollment_controller_->Start();
118 portal_detector->StartDetectionIfIdle();
121 void AutoEnrollmentCheckScreen::Hide() {
124 std::string AutoEnrollmentCheckScreen::GetName() const {
125 return WizardController::kAutoEnrollmentCheckScreenName;
128 void AutoEnrollmentCheckScreen::OnActorDestroyed(
129 AutoEnrollmentCheckScreenActor* actor) {
130 if (actor_ == actor)
131 actor_ = NULL;
134 void AutoEnrollmentCheckScreen::OnPortalDetectionCompleted(
135 const NetworkState* /* network */,
136 const NetworkPortalDetector::CaptivePortalState& /* state */) {
137 UpdateState();
140 void AutoEnrollmentCheckScreen::OnAutoEnrollmentCheckProgressed(
141 policy::AutoEnrollmentState state) {
142 if (IsCompleted()) {
143 SignalCompletion();
144 return;
147 UpdateState();
150 void AutoEnrollmentCheckScreen::UpdateState() {
151 NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status =
152 GetCaptivePortalStatus();
153 policy::AutoEnrollmentState new_auto_enrollment_state =
154 auto_enrollment_controller_->state();
156 // Configure the error screen to show the appropriate error message.
157 if (!UpdateCaptivePortalStatus(new_captive_portal_status))
158 UpdateAutoEnrollmentState(new_auto_enrollment_state);
160 // Update the connecting indicator.
161 ErrorScreen* error_screen = get_base_screen_delegate()->GetErrorScreen();
162 error_screen->ShowConnectingIndicator(
163 new_auto_enrollment_state == policy::AUTO_ENROLLMENT_STATE_PENDING);
165 // Determine whether a retry is in order.
166 bool retry = (new_captive_portal_status ==
167 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE) &&
168 (captive_portal_status_ !=
169 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE);
171 // Save the new state.
172 captive_portal_status_ = new_captive_portal_status;
173 auto_enrollment_state_ = new_auto_enrollment_state;
175 // Retry if applicable. This is last so eventual callbacks find consistent
176 // state.
177 if (retry)
178 auto_enrollment_controller_->Retry();
181 bool AutoEnrollmentCheckScreen::UpdateCaptivePortalStatus(
182 NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status) {
183 switch (new_captive_portal_status) {
184 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN:
185 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE:
186 return false;
187 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE:
188 ShowErrorScreen(NetworkError::ERROR_STATE_OFFLINE);
189 return true;
190 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL:
191 ShowErrorScreen(NetworkError::ERROR_STATE_PORTAL);
192 if (captive_portal_status_ != new_captive_portal_status)
193 get_base_screen_delegate()->GetErrorScreen()->FixCaptivePortal();
194 return true;
195 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED:
196 ShowErrorScreen(NetworkError::ERROR_STATE_PROXY);
197 return true;
198 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_COUNT:
199 NOTREACHED() << "Bad status: CAPTIVE_PORTAL_STATUS_COUNT";
200 return false;
203 // Return is required to avoid compiler warning.
204 NOTREACHED() << "Bad status " << new_captive_portal_status;
205 return false;
208 bool AutoEnrollmentCheckScreen::UpdateAutoEnrollmentState(
209 policy::AutoEnrollmentState new_auto_enrollment_state) {
210 switch (new_auto_enrollment_state) {
211 case policy::AUTO_ENROLLMENT_STATE_IDLE:
212 // The client should have been started already.
213 NOTREACHED();
214 return false;
215 case policy::AUTO_ENROLLMENT_STATE_PENDING:
216 case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR:
217 case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT:
218 case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT:
219 return false;
220 case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR:
221 ShowErrorScreen(NetworkError::ERROR_STATE_OFFLINE);
222 return true;
225 // Return is required to avoid compiler warning.
226 NOTREACHED() << "bad state " << new_auto_enrollment_state;
227 return false;
230 void AutoEnrollmentCheckScreen::ShowErrorScreen(
231 NetworkError::ErrorState error_state) {
232 const NetworkState* network =
233 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
234 ErrorScreen* error_screen = get_base_screen_delegate()->GetErrorScreen();
235 error_screen->SetUIState(NetworkError::UI_STATE_AUTO_ENROLLMENT_ERROR);
236 error_screen->AllowGuestSignin(true);
237 error_screen->SetErrorState(error_state,
238 network ? network->name() : std::string());
239 connect_request_subscription_ = error_screen->RegisterConnectRequestCallback(
240 base::Bind(&AutoEnrollmentCheckScreen::OnConnectRequested,
241 base::Unretained(this)));
242 get_base_screen_delegate()->ShowErrorScreen();
243 histogram_helper_->OnErrorShow(error_state);
246 void AutoEnrollmentCheckScreen::SignalCompletion() {
247 NetworkPortalDetector::Get()->RemoveObserver(this);
248 auto_enrollment_progress_subscription_.reset();
249 connect_request_subscription_.reset();
251 // Calling Finish() can cause |this| destruction, so let other methods finish
252 // their work before.
253 base::MessageLoop::current()->PostTask(
254 FROM_HERE,
255 base::Bind(
256 &AutoEnrollmentCheckScreen::Finish, weak_ptr_factory_.GetWeakPtr(),
257 BaseScreenDelegate::ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED));
260 bool AutoEnrollmentCheckScreen::IsCompleted() const {
261 switch (auto_enrollment_controller_->state()) {
262 case policy::AUTO_ENROLLMENT_STATE_IDLE:
263 case policy::AUTO_ENROLLMENT_STATE_PENDING:
264 case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR:
265 return false;
266 case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR:
267 // Server errors don't block OOBE.
268 case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT:
269 case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT:
270 // Decision made, ready to proceed.
271 return true;
273 NOTREACHED();
274 return false;
277 void AutoEnrollmentCheckScreen::OnConnectRequested() {
278 auto_enrollment_controller_->Retry();
281 } // namespace chromeos