controller_pairing_screen.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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/screens/controller_pairing_screen.h" 6 7#include "base/command_line.h" 8#include "base/values.h" 9#include "chrome/browser/chromeos/login/wizard_controller.h" 10#include "chromeos/chromeos_switches.h" 11#include "chromeos/login/auth/user_context.h" 12#include "components/pairing/fake_controller_pairing_controller.h" 13#include "google_apis/gaia/gaia_auth_util.h" 14 15using namespace chromeos::controller_pairing; 16using namespace pairing_chromeos; 17 18namespace chromeos { 19 20ControllerPairingScreen::ControllerPairingScreen( 21 ScreenObserver* observer, 22 ControllerPairingScreenActor* actor) 23 : WizardScreen(observer), 24 actor_(actor), 25 current_stage_(ControllerPairingController::STAGE_NONE), 26 device_preselected_(false) { 27 actor_->SetDelegate(this); 28 std::string controller_config = 29 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 30 switches::kShowControllerPairingDemo); 31 controller_.reset(new FakeControllerPairingController(controller_config)); 32 controller_->AddObserver(this); 33} 34 35ControllerPairingScreen::~ControllerPairingScreen() { 36 if (actor_) 37 actor_->SetDelegate(NULL); 38 controller_->RemoveObserver(this); 39} 40 41void ControllerPairingScreen::CommitContextChanges() { 42 if (!context_.HasChanges()) 43 return; 44 base::DictionaryValue diff; 45 context_.GetChangesAndReset(&diff); 46 if (actor_) 47 actor_->OnContextChanged(diff); 48} 49 50bool ControllerPairingScreen::ExpectStageIs(Stage stage) const { 51 DCHECK(stage == current_stage_); 52 if (current_stage_ != stage) 53 LOG(ERROR) << "Incorrect stage. Expected: " << stage 54 << ", current stage: " << current_stage_; 55 return stage == current_stage_; 56} 57 58void ControllerPairingScreen::PrepareToShow() { 59} 60 61void ControllerPairingScreen::Show() { 62 if (actor_) 63 actor_->Show(); 64 controller_->StartPairing(); 65} 66 67void ControllerPairingScreen::Hide() { 68 if (actor_) 69 actor_->Hide(); 70} 71 72std::string ControllerPairingScreen::GetName() const { 73 return WizardController::kControllerPairingScreenName; 74} 75 76// Overridden from ControllerPairingController::Observer: 77void ControllerPairingScreen::PairingStageChanged(Stage new_stage) { 78 DCHECK(new_stage != current_stage_); 79 80 std::string desired_page; 81 switch (new_stage) { 82 case ControllerPairingController::STAGE_DEVICES_DISCOVERY: { 83 desired_page = kPageDevicesDiscovery; 84 context_.SetStringList(kContextKeyDevices, StringList()); 85 context_.SetString(kContextKeySelectedDevice, std::string()); 86 device_preselected_ = false; 87 break; 88 } 89 case ControllerPairingController::STAGE_DEVICE_NOT_FOUND: { 90 desired_page = kPageDeviceNotFound; 91 break; 92 } 93 case ControllerPairingController::STAGE_ESTABLISHING_CONNECTION: { 94 desired_page = kPageEstablishingConnection; 95 break; 96 } 97 case ControllerPairingController::STAGE_ESTABLISHING_CONNECTION_ERROR: { 98 desired_page = kPageEstablishingConnectionError; 99 break; 100 } 101 case ControllerPairingController::STAGE_WAITING_FOR_CODE_CONFIRMATION: { 102 desired_page = kPageCodeConfirmation; 103 context_.SetString(kContextKeyConfirmationCode, 104 controller_->GetConfirmationCode()); 105 break; 106 } 107 case ControllerPairingController::STAGE_HOST_UPDATE_IN_PROGRESS: { 108 desired_page = kPageHostUpdate; 109 break; 110 } 111 case ControllerPairingController::STAGE_HOST_CONNECTION_LOST: { 112 desired_page = kPageHostConnectionLost; 113 break; 114 } 115 case ControllerPairingController::STAGE_WAITING_FOR_CREDENTIALS: { 116 desired_page = kPageEnrollmentIntroduction; 117 break; 118 } 119 case ControllerPairingController::STAGE_HOST_ENROLLMENT_IN_PROGRESS: { 120 desired_page = kPageHostEnrollment; 121 break; 122 } 123 case ControllerPairingController::STAGE_HOST_ENROLLMENT_ERROR: { 124 desired_page = kPageHostEnrollmentError; 125 break; 126 } 127 case ControllerPairingController::STAGE_PAIRING_DONE: { 128 desired_page = kPagePairingDone; 129 break; 130 } 131 case ControllerPairingController::STAGE_FINISHED: { 132 get_screen_observer()->OnExit( 133 WizardController::CONTROLLER_PAIRING_FINISHED); 134 break; 135 } 136 default: 137 NOTREACHED(); 138 } 139 current_stage_ = new_stage; 140 context_.SetString(kContextKeyPage, desired_page); 141 context_.SetBoolean(kContextKeyControlsDisabled, false); 142 CommitContextChanges(); 143} 144 145void ControllerPairingScreen::DiscoveredDevicesListChanged() { 146 if (!ExpectStageIs(ControllerPairingController::STAGE_DEVICES_DISCOVERY)) 147 return; 148 ControllerPairingController::DeviceIdList devices = 149 controller_->GetDiscoveredDevices(); 150 std::sort(devices.begin(), devices.end()); 151 context_.SetStringList(kContextKeyDevices, devices); 152 context_.SetString( 153 kContextKeyPage, 154 devices.empty() ? kPageDevicesDiscovery : kPageDeviceSelect); 155 std::string selected_device = context_.GetString(kContextKeySelectedDevice); 156 if (std::find(devices.begin(), devices.end(), selected_device) == 157 devices.end()) { 158 selected_device.clear(); 159 } 160 if (devices.empty()) { 161 device_preselected_ = false; 162 } else if (!device_preselected_) { 163 selected_device = devices.front(); 164 device_preselected_ = true; 165 } 166 context_.SetString(kContextKeySelectedDevice, selected_device); 167 context_.SetBoolean(kContextKeyControlsDisabled, selected_device.empty()); 168 CommitContextChanges(); 169} 170 171void ControllerPairingScreen::OnActorDestroyed( 172 ControllerPairingScreenActor* actor) { 173 if (actor_ == actor) 174 actor_ = NULL; 175} 176 177// Overridden from ControllerPairingView::Delegate: 178void ControllerPairingScreen::OnUserActed(const std::string& action) { 179 if (context_.GetBoolean(kContextKeyControlsDisabled)) { 180 LOG(WARNING) << "User acted, but controls are disabled. Ignoring."; 181 return; 182 } 183 bool disable_controls = true; 184 if (action == kActionChooseDevice) { 185 std::string selectedDevice = context_.GetString(kContextKeySelectedDevice); 186 if (selectedDevice.empty()) 187 LOG(ERROR) << "Device was not selected."; 188 else 189 controller_->ChooseDeviceForPairing(selectedDevice); 190 } else if (action == kActionRepeatDiscovery) { 191 controller_->RepeatDiscovery(); 192 } else if (action == kActionAcceptCode) { 193 controller_->SetConfirmationCodeIsCorrect(true); 194 } else if (action == kActionRejectCode) { 195 controller_->SetConfirmationCodeIsCorrect(false); 196 } else if (action == kActionProceedToAuthentication) { 197 context_.SetString(kContextKeyPage, kPageAuthentication); 198 disable_controls = false; 199 } else if (action == kActionEnroll) { 200 std::string account_id = 201 gaia::SanitizeEmail(context_.GetString(kContextKeyAccountId)); 202 context_.SetString(kContextKeyEnrollmentDomain, 203 gaia::ExtractDomainName(account_id)); 204 UserContext user_context(account_id); 205 controller_->OnAuthenticationDone(user_context, 206 actor_->GetBrowserContext()); 207 } else if (action == kActionStartSession) { 208 controller_->StartSession(); 209 } 210 context_.SetBoolean(kContextKeyControlsDisabled, disable_controls); 211 CommitContextChanges(); 212} 213 214void ControllerPairingScreen::OnScreenContextChanged( 215 const base::DictionaryValue& diff) { 216 std::vector<std::string> changedKeys; 217 context_.ApplyChanges(diff, &changedKeys); 218 for (std::vector<std::string>::const_iterator key = changedKeys.begin(); 219 key != changedKeys.end(); 220 ++key) { 221 if (*key == kContextKeySelectedDevice) { 222 context_.SetBoolean(kContextKeyControlsDisabled, 223 context_.GetString(*key).empty()); 224 CommitContextChanges(); 225 } 226 } 227} 228 229} // namespace chromeos 230