blob: 9c0dff9ec946f101807391f9f2dda86860f3b674 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/login/screens/controller_pairing_screen.h"
#include "base/command_line.h"
#include "base/values.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/login/auth/user_context.h"
#include "components/pairing/fake_controller_pairing_controller.h"
#include "google_apis/gaia/gaia_auth_util.h"
using namespace chromeos::controller_pairing;
using namespace pairing_chromeos;
namespace chromeos {
ControllerPairingScreen::ControllerPairingScreen(
ScreenObserver* observer,
ControllerPairingScreenActor* actor)
: WizardScreen(observer),
actor_(actor),
current_stage_(ControllerPairingController::STAGE_NONE),
device_preselected_(false) {
actor_->SetDelegate(this);
std::string controller_config =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kShowControllerPairingDemo);
controller_.reset(new FakeControllerPairingController(controller_config));
controller_->AddObserver(this);
}
ControllerPairingScreen::~ControllerPairingScreen() {
if (actor_)
actor_->SetDelegate(NULL);
controller_->RemoveObserver(this);
}
void ControllerPairingScreen::CommitContextChanges() {
if (!context_.HasChanges())
return;
base::DictionaryValue diff;
context_.GetChangesAndReset(&diff);
if (actor_)
actor_->OnContextChanged(diff);
}
bool ControllerPairingScreen::ExpectStageIs(Stage stage) const {
DCHECK(stage == current_stage_);
if (current_stage_ != stage)
LOG(ERROR) << "Incorrect stage. Expected: " << stage
<< ", current stage: " << current_stage_;
return stage == current_stage_;
}
void ControllerPairingScreen::PrepareToShow() {
}
void ControllerPairingScreen::Show() {
if (actor_)
actor_->Show();
controller_->StartPairing();
}
void ControllerPairingScreen::Hide() {
if (actor_)
actor_->Hide();
}
std::string ControllerPairingScreen::GetName() const {
return WizardController::kControllerPairingScreenName;
}
// Overridden from ControllerPairingController::Observer:
void ControllerPairingScreen::PairingStageChanged(Stage new_stage) {
DCHECK(new_stage != current_stage_);
std::string desired_page;
switch (new_stage) {
case ControllerPairingController::STAGE_DEVICES_DISCOVERY: {
desired_page = kPageDevicesDiscovery;
context_.SetStringList(kContextKeyDevices, StringList());
context_.SetString(kContextKeySelectedDevice, std::string());
device_preselected_ = false;
break;
}
case ControllerPairingController::STAGE_DEVICE_NOT_FOUND: {
desired_page = kPageDeviceNotFound;
break;
}
case ControllerPairingController::STAGE_ESTABLISHING_CONNECTION: {
desired_page = kPageEstablishingConnection;
break;
}
case ControllerPairingController::STAGE_ESTABLISHING_CONNECTION_ERROR: {
desired_page = kPageEstablishingConnectionError;
break;
}
case ControllerPairingController::STAGE_WAITING_FOR_CODE_CONFIRMATION: {
desired_page = kPageCodeConfirmation;
context_.SetString(kContextKeyConfirmationCode,
controller_->GetConfirmationCode());
break;
}
case ControllerPairingController::STAGE_HOST_UPDATE_IN_PROGRESS: {
desired_page = kPageHostUpdate;
break;
}
case ControllerPairingController::STAGE_HOST_CONNECTION_LOST: {
desired_page = kPageHostConnectionLost;
break;
}
case ControllerPairingController::STAGE_WAITING_FOR_CREDENTIALS: {
desired_page = kPageEnrollmentIntroduction;
break;
}
case ControllerPairingController::STAGE_HOST_ENROLLMENT_IN_PROGRESS: {
desired_page = kPageHostEnrollment;
break;
}
case ControllerPairingController::STAGE_HOST_ENROLLMENT_ERROR: {
desired_page = kPageHostEnrollmentError;
break;
}
case ControllerPairingController::STAGE_PAIRING_DONE: {
desired_page = kPagePairingDone;
break;
}
case ControllerPairingController::STAGE_FINISHED: {
get_screen_observer()->OnExit(
WizardController::CONTROLLER_PAIRING_FINISHED);
break;
}
default:
NOTREACHED();
}
current_stage_ = new_stage;
context_.SetString(kContextKeyPage, desired_page);
context_.SetBoolean(kContextKeyControlsDisabled, false);
CommitContextChanges();
}
void ControllerPairingScreen::DiscoveredDevicesListChanged() {
if (!ExpectStageIs(ControllerPairingController::STAGE_DEVICES_DISCOVERY))
return;
ControllerPairingController::DeviceIdList devices =
controller_->GetDiscoveredDevices();
std::sort(devices.begin(), devices.end());
context_.SetStringList(kContextKeyDevices, devices);
context_.SetString(
kContextKeyPage,
devices.empty() ? kPageDevicesDiscovery : kPageDeviceSelect);
std::string selected_device = context_.GetString(kContextKeySelectedDevice);
if (std::find(devices.begin(), devices.end(), selected_device) ==
devices.end()) {
selected_device.clear();
}
if (devices.empty()) {
device_preselected_ = false;
} else if (!device_preselected_) {
selected_device = devices.front();
device_preselected_ = true;
}
context_.SetString(kContextKeySelectedDevice, selected_device);
context_.SetBoolean(kContextKeyControlsDisabled, selected_device.empty());
CommitContextChanges();
}
void ControllerPairingScreen::OnActorDestroyed(
ControllerPairingScreenActor* actor) {
if (actor_ == actor)
actor_ = NULL;
}
// Overridden from ControllerPairingView::Delegate:
void ControllerPairingScreen::OnUserActed(const std::string& action) {
if (context_.GetBoolean(kContextKeyControlsDisabled)) {
LOG(WARNING) << "User acted, but controls are disabled. Ignoring.";
return;
}
bool disable_controls = true;
if (action == kActionChooseDevice) {
std::string selectedDevice = context_.GetString(kContextKeySelectedDevice);
if (selectedDevice.empty())
LOG(ERROR) << "Device was not selected.";
else
controller_->ChooseDeviceForPairing(selectedDevice);
} else if (action == kActionRepeatDiscovery) {
controller_->RepeatDiscovery();
} else if (action == kActionAcceptCode) {
controller_->SetConfirmationCodeIsCorrect(true);
} else if (action == kActionRejectCode) {
controller_->SetConfirmationCodeIsCorrect(false);
} else if (action == kActionProceedToAuthentication) {
context_.SetString(kContextKeyPage, kPageAuthentication);
disable_controls = false;
} else if (action == kActionEnroll) {
std::string account_id =
gaia::SanitizeEmail(context_.GetString(kContextKeyAccountId));
context_.SetString(kContextKeyEnrollmentDomain,
gaia::ExtractDomainName(account_id));
UserContext user_context(account_id);
controller_->OnAuthenticationDone(user_context,
actor_->GetBrowserContext());
} else if (action == kActionStartSession) {
controller_->StartSession();
}
context_.SetBoolean(kContextKeyControlsDisabled, disable_controls);
CommitContextChanges();
}
void ControllerPairingScreen::OnScreenContextChanged(
const base::DictionaryValue& diff) {
std::vector<std::string> changedKeys;
context_.ApplyChanges(diff, &changedKeys);
for (std::vector<std::string>::const_iterator key = changedKeys.begin();
key != changedKeys.end();
++key) {
if (*key == kContextKeySelectedDevice) {
context_.SetBoolean(kContextKeyControlsDisabled,
context_.GetString(*key).empty());
CommitContextChanges();
}
}
}
} // namespace chromeos