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 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) {
56 actor_
->SetDelegate(this);
59 AutoEnrollmentCheckScreen::~AutoEnrollmentCheckScreen() {
60 NetworkPortalDetector::Get()->RemoveObserver(this);
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
||
86 // Start from a clean slate.
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
93 histogram_helper_
->OnScreenShow();
95 // Set up state change observers.
96 auto_enrollment_progress_subscription_
=
97 auto_enrollment_controller_
->RegisterProgressCallback(
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
) {
134 void AutoEnrollmentCheckScreen::OnPortalDetectionCompleted(
135 const NetworkState
* /* network */,
136 const NetworkPortalDetector::CaptivePortalState
& /* state */) {
140 void AutoEnrollmentCheckScreen::OnAutoEnrollmentCheckProgressed(
141 policy::AutoEnrollmentState state
) {
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
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
:
187 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE
:
188 ShowErrorScreen(NetworkError::ERROR_STATE_OFFLINE
);
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();
195 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED
:
196 ShowErrorScreen(NetworkError::ERROR_STATE_PROXY
);
198 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_COUNT
:
199 NOTREACHED() << "Bad status: CAPTIVE_PORTAL_STATUS_COUNT";
203 // Return is required to avoid compiler warning.
204 NOTREACHED() << "Bad status " << new_captive_portal_status
;
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.
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
:
220 case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR
:
221 ShowErrorScreen(NetworkError::ERROR_STATE_OFFLINE
);
225 // Return is required to avoid compiler warning.
226 NOTREACHED() << "bad state " << new_auto_enrollment_state
;
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(
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
:
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.
277 void AutoEnrollmentCheckScreen::OnConnectRequested() {
278 auto_enrollment_controller_
->Retry();
281 } // namespace chromeos