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. 4 5#include "chrome/browser/chromeos/login/enrollment/auto_enrollment_check_screen.h" 6 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/screen_manager.h" 12#include "chrome/browser/chromeos/login/screens/screen_observer.h" 13#include "chrome/browser/chromeos/login/wizard_controller.h" 14#include "chromeos/chromeos_switches.h" 15#include "chromeos/network/network_state.h" 16#include "chromeos/network/network_state_handler.h" 17 18namespace chromeos { 19 20// static 21AutoEnrollmentCheckScreen* AutoEnrollmentCheckScreen::Get( 22 ScreenManager* manager) { 23 return static_cast<AutoEnrollmentCheckScreen*>( 24 manager->GetScreen(WizardController::kAutoEnrollmentCheckScreenName)); 25} 26 27AutoEnrollmentCheckScreen::AutoEnrollmentCheckScreen( 28 ScreenObserver* observer, 29 AutoEnrollmentCheckScreenActor* actor) 30 : WizardScreen(observer), 31 actor_(actor), 32 captive_portal_status_( 33 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN), 34 auto_enrollment_state_(policy::AUTO_ENROLLMENT_STATE_IDLE) { 35 if (actor_) 36 actor_->SetDelegate(this); 37} 38 39AutoEnrollmentCheckScreen::~AutoEnrollmentCheckScreen() { 40 NetworkPortalDetector::Get()->RemoveObserver(this); 41 if (actor_) 42 actor_->SetDelegate(NULL); 43} 44 45void AutoEnrollmentCheckScreen::Start() { 46 if (!IsStartNeeded()) 47 return; 48 49 // Make sure the auto-enrollment client is running. 50 auto_enrollment_controller_->Start(); 51 52 auto_enrollment_progress_subscription_ = 53 auto_enrollment_controller_->RegisterProgressCallback( 54 base::Bind( 55 &AutoEnrollmentCheckScreen::OnAutoEnrollmentCheckProgressed, 56 base::Unretained(this))); 57 auto_enrollment_state_ = auto_enrollment_controller_->state(); 58 59 // NB: AddAndFireObserver below call back into OnPortalDetectionCompleted. 60 // This guarantees that the UI gets synced to current state. 61 NetworkPortalDetector* portal_detector = NetworkPortalDetector::Get(); 62 portal_detector->StartDetectionIfIdle(); 63 portal_detector->AddAndFireObserver(this); 64} 65 66bool AutoEnrollmentCheckScreen::IsStartNeeded() { 67 // Check that forced reenrollment is wanted and if the check is needed or we 68 // already know the outcome. 69 if (AutoEnrollmentController::GetMode() != 70 AutoEnrollmentController::MODE_FORCED_RE_ENROLLMENT || 71 auto_enrollment_state_ == 72 policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT || 73 auto_enrollment_state_ == policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT) { 74 SignalCompletion(); 75 return false; 76 } 77 return true; 78} 79 80void AutoEnrollmentCheckScreen::PrepareToShow() { 81} 82 83void AutoEnrollmentCheckScreen::Show() { 84 if (IsStartNeeded()) { 85 Start(); 86 if (actor_) 87 actor_->Show(); 88 } 89} 90 91void AutoEnrollmentCheckScreen::Hide() { 92} 93 94std::string AutoEnrollmentCheckScreen::GetName() const { 95 return WizardController::kAutoEnrollmentCheckScreenName; 96} 97 98void AutoEnrollmentCheckScreen::OnExit() { 99 get_screen_observer()->OnExit( 100 ScreenObserver::ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED); 101} 102 103void AutoEnrollmentCheckScreen::OnActorDestroyed( 104 AutoEnrollmentCheckScreenActor* actor) { 105 if (actor_ == actor) 106 actor_ = NULL; 107} 108 109void AutoEnrollmentCheckScreen::OnPortalDetectionCompleted( 110 const NetworkState* /* network */, 111 const NetworkPortalDetector::CaptivePortalState& state) { 112 UpdateState(state.status, auto_enrollment_state_); 113} 114 115void AutoEnrollmentCheckScreen::OnAutoEnrollmentCheckProgressed( 116 policy::AutoEnrollmentState state) { 117 UpdateState(captive_portal_status_, state); 118} 119 120void AutoEnrollmentCheckScreen::UpdateState( 121 NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status, 122 policy::AutoEnrollmentState new_auto_enrollment_state) { 123 // Configure the error screen to show the approriate error message. 124 if (!UpdateCaptivePortalStatus(new_captive_portal_status)) 125 UpdateAutoEnrollmentState(new_auto_enrollment_state); 126 127 // Update the connecting indicator. 128 ErrorScreen* error_screen = get_screen_observer()->GetErrorScreen(); 129 error_screen->ShowConnectingIndicator( 130 new_auto_enrollment_state == policy::AUTO_ENROLLMENT_STATE_PENDING); 131 132 // Determine whether a retry is in order. 133 bool retry = (new_captive_portal_status == 134 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE) && 135 (captive_portal_status_ != 136 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE); 137 138 // Save the new state. 139 captive_portal_status_ = new_captive_portal_status; 140 auto_enrollment_state_ = new_auto_enrollment_state; 141 142 // Check whether a decision got made. 143 switch (new_auto_enrollment_state) { 144 case policy::AUTO_ENROLLMENT_STATE_IDLE: 145 NOTREACHED(); 146 // fall through. 147 case policy::AUTO_ENROLLMENT_STATE_PENDING: 148 case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR: 149 break; 150 case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR: 151 // Server errors don't block OOBE. 152 case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT: 153 case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT: 154 // Decision made, ready to proceed. 155 SignalCompletion(); 156 return; 157 } 158 159 // Retry if applicable. This is last so eventual callbacks find consistent 160 // state. 161 if (retry) 162 auto_enrollment_controller_->Retry(); 163} 164 165bool AutoEnrollmentCheckScreen::UpdateCaptivePortalStatus( 166 NetworkPortalDetector::CaptivePortalStatus new_captive_portal_status) { 167 switch (new_captive_portal_status) { 168 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN: 169 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE: 170 return false; 171 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE: 172 ShowErrorScreen(ErrorScreen::ERROR_STATE_OFFLINE); 173 return true; 174 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL: 175 ShowErrorScreen(ErrorScreen::ERROR_STATE_PORTAL); 176 if (captive_portal_status_ != new_captive_portal_status) 177 get_screen_observer()->GetErrorScreen()->FixCaptivePortal(); 178 return true; 179 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED: 180 ShowErrorScreen(ErrorScreen::ERROR_STATE_PROXY); 181 return true; 182 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_COUNT: 183 NOTREACHED() << "Bad status: CAPTIVE_PORTAL_STATUS_COUNT"; 184 return false; 185 } 186 187 // Return is required to avoid compiler warning. 188 NOTREACHED() << "Bad status " << new_captive_portal_status; 189 return false; 190} 191 192bool AutoEnrollmentCheckScreen::UpdateAutoEnrollmentState( 193 policy::AutoEnrollmentState new_auto_enrollment_state) { 194 switch (new_auto_enrollment_state) { 195 case policy::AUTO_ENROLLMENT_STATE_IDLE: 196 // The client should have been started already. 197 NOTREACHED(); 198 return false; 199 case policy::AUTO_ENROLLMENT_STATE_PENDING: 200 case policy::AUTO_ENROLLMENT_STATE_SERVER_ERROR: 201 case policy::AUTO_ENROLLMENT_STATE_TRIGGER_ENROLLMENT: 202 case policy::AUTO_ENROLLMENT_STATE_NO_ENROLLMENT: 203 return false; 204 case policy::AUTO_ENROLLMENT_STATE_CONNECTION_ERROR: 205 ShowErrorScreen(ErrorScreen::ERROR_STATE_OFFLINE); 206 return true; 207 } 208 209 // Return is required to avoid compiler warning. 210 NOTREACHED() << "bad state " << new_auto_enrollment_state; 211 return false; 212} 213 214void AutoEnrollmentCheckScreen::ShowErrorScreen( 215 ErrorScreen::ErrorState error_state) { 216 const NetworkState* network = 217 NetworkHandler::Get()->network_state_handler()->DefaultNetwork(); 218 ErrorScreen* error_screen = get_screen_observer()->GetErrorScreen(); 219 error_screen->SetUIState(ErrorScreen::UI_STATE_AUTO_ENROLLMENT_ERROR); 220 error_screen->AllowGuestSignin(true); 221 error_screen->SetErrorState(error_state, 222 network ? network->name() : std::string()); 223 get_screen_observer()->ShowErrorScreen(); 224} 225 226void AutoEnrollmentCheckScreen::SignalCompletion() { 227 NetworkPortalDetector::Get()->RemoveObserver(this); 228 auto_enrollment_progress_subscription_.reset(); 229 get_screen_observer()->OnExit( 230 ScreenObserver::ENTERPRISE_AUTO_ENROLLMENT_CHECK_COMPLETED); 231} 232 233} // namespace chromeos 234