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"
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"
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())
32 : NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN
;
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
),
49 captive_portal_status_(
50 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN
),
51 auto_enrollment_state_(policy::AUTO_ENROLLMENT_STATE_IDLE
),
52 histogram_helper_(new ErrorScreensHistogramHelper("Enrollment")),
53 weak_ptr_factory_(this) {
55 actor_
->SetDelegate(this);
58 AutoEnrollmentCheckScreen::~AutoEnrollmentCheckScreen() {
59 NetworkPortalDetector::Get()->RemoveObserver(this);
61 actor_
->SetDelegate(NULL
);
64 void AutoEnrollmentCheckScreen::ClearState() {
65 auto_enrollment_progress_subscription_
.reset();
66 NetworkPortalDetector::Get()->RemoveObserver(this);
68 auto_enrollment_state_
= policy::AUTO_ENROLLMENT_STATE_IDLE
;
69 captive_portal_status_
=
70 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN
;
73 void AutoEnrollmentCheckScreen::PrepareToShow() {
76 void AutoEnrollmentCheckScreen::Show() {
77 // If the decision got made already, don't show the screen at all.
78 if (AutoEnrollmentController::GetMode() !=
79 AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT
||
85 // Start from a clean slate.
88 // Bring up the screen. It's important to do this before updating the UI,
89 // because the latter may switch to the error screen, which needs to stay on
92 histogram_helper_
->OnScreenShow();
94 // Set up state change observers.
95 auto_enrollment_progress_subscription_
=
96 auto_enrollment_controller_
->RegisterProgressCallback(
98 &AutoEnrollmentCheckScreen::OnAutoEnrollmentCheckProgressed
,
99 base::Unretained(this)));
100 NetworkPortalDetector
* portal_detector
= NetworkPortalDetector::Get();
101 portal_detector
->AddObserver(this);
103 // Perform an initial UI update.
104 NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status
=
105 GetCaptivePortalStatus();
106 policy::AutoEnrollmentState new_auto_enrollment_state
=
107 auto_enrollment_controller_
->state();
109 if (!UpdateCaptivePortalStatus(new_captive_portal_status
))
110 UpdateAutoEnrollmentState(new_auto_enrollment_state
);
112 captive_portal_status_
= new_captive_portal_status
;
113 auto_enrollment_state_
= new_auto_enrollment_state
;
115 // Make sure gears are in motion in the background.
116 auto_enrollment_controller_
->Start();
117 portal_detector
->StartDetectionIfIdle();
120 void AutoEnrollmentCheckScreen::Hide() {
123 std::string
AutoEnrollmentCheckScreen::GetName() const {
124 return WizardController::kAutoEnrollmentCheckScreenName
;
127 void AutoEnrollmentCheckScreen::OnActorDestroyed(
128 AutoEnrollmentCheckScreenActor
* actor
) {
133 void AutoEnrollmentCheckScreen::OnPortalDetectionCompleted(
134 const NetworkState
* /* network */,
135 const NetworkPortalDetector::CaptivePortalState
& /* state */) {
139 void AutoEnrollmentCheckScreen::OnAutoEnrollmentCheckProgressed(
140 policy::AutoEnrollmentState state
) {
149 void AutoEnrollmentCheckScreen::UpdateState() {
150 NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status
=
151 GetCaptivePortalStatus();
152 policy::AutoEnrollmentState new_auto_enrollment_state
=
153 auto_enrollment_controller_
->state();
155 // Configure the error screen to show the appropriate error message.
156 if (!UpdateCaptivePortalStatus(new_captive_portal_status
))
157 UpdateAutoEnrollmentState(new_auto_enrollment_state
);
159 // Update the connecting indicator.
160 ErrorScreen
* error_screen
= get_base_screen_delegate()->GetErrorScreen();
161 error_screen
->ShowConnectingIndicator(
162 new_auto_enrollment_state
== policy::AUTO_ENROLLMENT_STATE_PENDING
);
164 // Determine whether a retry is in order.
165 bool retry
= (new_captive_portal_status
==
166 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
) &&
167 (captive_portal_status_
!=
168 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
);
170 // Save the new state.
171 captive_portal_status_
= new_captive_portal_status
;
172 auto_enrollment_state_
= new_auto_enrollment_state
;
174 // Retry if applicable. This is last so eventual callbacks find consistent
177 auto_enrollment_controller_
->Retry();
180 bool AutoEnrollmentCheckScreen::UpdateCaptivePortalStatus(
181 NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status
) {
182 switch (new_captive_portal_status
) {
183 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN
:
184 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
:
186 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE
:
187 ShowErrorScreen(NetworkError::ERROR_STATE_OFFLINE
);
189 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
:
190 ShowErrorScreen(NetworkError::ERROR_STATE_PORTAL
);
191 if (captive_portal_status_
!= new_captive_portal_status
)
192 get_base_screen_delegate()->GetErrorScreen()->FixCaptivePortal();
194 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED
:
195 ShowErrorScreen(NetworkError::ERROR_STATE_PROXY
);
197 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_COUNT
:
198 NOTREACHED() << "Bad status: CAPTIVE_PORTAL_STATUS_COUNT";
202 // Return is required to avoid compiler warning.
203 NOTREACHED() << "Bad status " << new_captive_portal_status
;
207 bool AutoEnrollmentCheckScreen::UpdateAutoEnrollmentState(
208 policy::AutoEnrollmentState new_auto_enrollment_state
) {
209 switch (new_auto_enrollment_state
) {
210 case policy::AUTO_ENROLLMENT_STATE_IDLE
:
211 // The client should have been started already.
214 case policy::AUTO_ENROLLMENT_STATE_PENDING
:
215 case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR
:
216 case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT
:
217 case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT
:
219 case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR
:
220 ShowErrorScreen(NetworkError::ERROR_STATE_OFFLINE
);
224 // Return is required to avoid compiler warning.
225 NOTREACHED() << "bad state " << new_auto_enrollment_state
;
229 void AutoEnrollmentCheckScreen::ShowErrorScreen(
230 NetworkError::ErrorState error_state
) {
231 const NetworkState
* network
=
232 NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
233 ErrorScreen
* error_screen
= get_base_screen_delegate()->GetErrorScreen();
234 error_screen
->SetUIState(NetworkError::UI_STATE_AUTO_ENROLLMENT_ERROR
);
235 error_screen
->AllowGuestSignin(true);
236 error_screen
->SetErrorState(error_state
,
237 network
? network
->name() : std::string());
238 get_base_screen_delegate()->ShowErrorScreen();
239 histogram_helper_
->OnErrorShow(error_state
);
242 void AutoEnrollmentCheckScreen::SignalCompletion() {
243 NetworkPortalDetector::Get()->RemoveObserver(this);
244 auto_enrollment_progress_subscription_
.reset();
246 // Calling Finish() can cause |this| destruction, so let other methods finish
247 // their work before.
248 base::MessageLoop::current()->PostTask(
251 &AutoEnrollmentCheckScreen::Finish
, weak_ptr_factory_
.GetWeakPtr(),
252 BaseScreenDelegate::ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED
));
255 bool AutoEnrollmentCheckScreen::IsCompleted() const {
256 switch (auto_enrollment_controller_
->state()) {
257 case policy::AUTO_ENROLLMENT_STATE_IDLE
:
258 case policy::AUTO_ENROLLMENT_STATE_PENDING
:
259 case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR
:
261 case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR
:
262 // Server errors don't block OOBE.
263 case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT
:
264 case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT
:
265 // Decision made, ready to proceed.
272 } // namespace chromeos