Chromium Code Reviews| Index: chromeos/pairing/fake_controller_pairing_flow.cc |
| diff --git a/chromeos/pairing/fake_controller_pairing_flow.cc b/chromeos/pairing/fake_controller_pairing_flow.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..7205157f596db8f2f22a602993edbd7732bab646 |
| --- /dev/null |
| +++ b/chromeos/pairing/fake_controller_pairing_flow.cc |
| @@ -0,0 +1,251 @@ |
| +// 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 "chromeos/pairing/fake_controller_pairing_flow.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/logging.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/rand_util.h" |
| + |
| +namespace chromeos { |
| + |
| +const char* FakeControllerPairingFlow::kNotFoundDeviceID = "not_found"; |
| + |
| +FakeControllerPairingFlow::FakeControllerPairingFlow() |
| + : current_stage_(STAGE_NONE), |
| + async_duration_(base::TimeDelta::FromSeconds(3)), |
| + should_fail_on_connecting_(false), |
| + connection_lost_begin_(STAGE_NONE), |
| + connection_lost_end_(STAGE_NONE), |
| + enrollment_should_fail_(false) { |
| + SetDiscoveryScenario(GetDefaultScenario()); |
| + AddObserver(this); |
| +} |
| + |
| +FakeControllerPairingFlow::~FakeControllerPairingFlow() { |
| + RemoveObserver(this); |
| +} |
| + |
| +void FakeControllerPairingFlow::SetShouldFailOnConnecting() { |
| + should_fail_on_connecting_ = true; |
| +} |
| + |
| +void FakeControllerPairingFlow::SetShouldLoseConnection(Stage stage_begin, |
| + Stage stage_end) { |
| + connection_lost_begin_ = stage_begin; |
| + connection_lost_end_ = stage_end; |
| +} |
| + |
| +void FakeControllerPairingFlow::SetEnrollmentShouldFail() { |
| + enrollment_should_fail_ = true; |
| +} |
| + |
| +void FakeControllerPairingFlow::SetDiscoveryScenario( |
| + const DiscoveryScenario& discovery_scenario) { |
| + discovery_scenario_ = discovery_scenario; |
| + // Check that scenario is valid. |
| + std::set<std::string> devices; |
| + for (DiscoveryScenario::const_iterator event = discovery_scenario_.begin(); |
| + event != discovery_scenario_.end(); |
| + ++event) { |
| + if (event->second == kNotFoundDeviceID) { |
| + CHECK(devices.empty()); |
| + CHECK(++event == discovery_scenario_.end()); |
| + return; |
| + } else if (event->first == DEVICE_FOUND) { |
| + devices.insert(event->second); |
| + } else { |
| + CHECK(devices.count(event->second)); |
| + devices.erase(event->second); |
| + } |
| + } |
| +} |
| + |
| +void FakeControllerPairingFlow::AddObserver(Observer* observer) { |
| + observers_.AddObserver(observer); |
| +} |
| + |
| +void FakeControllerPairingFlow::RemoveObserver(Observer* observer) { |
| + observers_.RemoveObserver(observer); |
| +} |
| + |
| +ControllerPairingFlow::Stage FakeControllerPairingFlow::GetCurrentStage() { |
| + return current_stage_; |
| +} |
| + |
| +void FakeControllerPairingFlow::StartFlow() { |
| + CHECK(current_stage_ == STAGE_NONE); |
| + ChangeStage(STAGE_DEVICES_DISCOVERY); |
| +} |
| + |
| +ControllerPairingFlow::DeviceIdList |
| +FakeControllerPairingFlow::GetDiscoveredDevices() { |
| + CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY); |
| + return DeviceIdList(discovered_devices_.begin(), discovered_devices_.end()); |
| +} |
| + |
| +void FakeControllerPairingFlow::ChooseDeviceForPairing( |
| + const std::string& device_id) { |
| + CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY); |
| + CHECK(discovered_devices_.count(device_id)); |
| + choosen_device_ = device_id; |
| + ChangeStage(STAGE_ESTABLISHING_CONNECTION); |
| +} |
| + |
| +void FakeControllerPairingFlow::RepeatDiscovery() { |
| + CHECK(current_stage_ == STAGE_DEVICE_NOT_FOUND || |
| + current_stage_ == STAGE_ESTABLISHING_CONNECTION_ERROR || |
| + current_stage_ == STAGE_HOST_ENROLLMENT_ERROR); |
| + ChangeStage(STAGE_DEVICES_DISCOVERY); |
| +} |
| + |
| +std::string FakeControllerPairingFlow::GetConfirmationCode() { |
| + CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION); |
| + if (confirmation_code_.empty()) |
| + for (int i = 0; i < 6; ++i) |
| + confirmation_code_.push_back(base::RandInt('0', '9')); |
|
Dmitry Polukhin
2014/06/18 10:46:51
I would avoid randomness in test. I think you can
|
| + return confirmation_code_; |
| +} |
| + |
| +void FakeControllerPairingFlow::SetConfirmationCodeIsCorrect(bool correct) { |
| + CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION); |
| + if (correct) |
| + ChangeStage(STAGE_HOST_UPDATE_IN_PROGRESS); |
| + else |
| + ChangeStage(STAGE_DEVICES_DISCOVERY); |
| +} |
| + |
| +void FakeControllerPairingFlow::OnAuthenticationDone( |
| + const chromeos::UserContext& user_context, |
| + content::BrowserContext* browser_context) { |
| + CHECK(current_stage_ == STAGE_WAITING_FOR_CREDENTIALS); |
| + ChangeStage(STAGE_HOST_ENROLLMENT_IN_PROGRESS); |
| +} |
| + |
| +void FakeControllerPairingFlow::StartSession() { |
| + CHECK(current_stage_ == STAGE_PAIRING_DONE); |
| + ChangeStage(STAGE_FINISHED); |
| +} |
| + |
| +void FakeControllerPairingFlow::ChangeStage(Stage new_stage) { |
| + if (current_stage_ == new_stage) |
| + return; |
| + current_stage_ = new_stage; |
| + FOR_EACH_OBSERVER(Observer, observers_, PairingStageChanged(new_stage)); |
| +} |
| + |
| +void FakeControllerPairingFlow::ChangeStageLater(Stage new_stage) { |
| + base::MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + base::Bind(&FakeControllerPairingFlow::ChangeStage, |
| + base::Unretained(this), |
| + new_stage), |
| + async_duration_); |
| +} |
| + |
| +void FakeControllerPairingFlow::ExecuteDiscoveryEvent(size_t event_position) { |
| + if (current_stage_ != STAGE_DEVICES_DISCOVERY) |
| + return; |
| + CHECK(event_position < discovery_scenario_.size()); |
| + const DiscoveryEvent& event = discovery_scenario_[event_position]; |
| + if (event.second == kNotFoundDeviceID) { |
| + ChangeStage(STAGE_DEVICE_NOT_FOUND); |
| + return; |
| + } else if (event.first == DEVICE_FOUND) { |
| + DeviceFound(event.second); |
| + } else { |
| + DeviceLost(event.second); |
| + } |
| + if (++event_position == discovery_scenario_.size()) { |
| + return; |
| + } |
| + base::MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + base::Bind(&FakeControllerPairingFlow::ExecuteDiscoveryEvent, |
| + base::Unretained(this), |
| + event_position), |
| + async_duration_); |
| +} |
| + |
| +void FakeControllerPairingFlow::DeviceFound(const std::string& device_id) { |
| + CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY); |
| + discovered_devices_.insert(device_id); |
| + FOR_EACH_OBSERVER(Observer, observers_, DiscoveredDevicesListChanged()); |
| +} |
| + |
| +void FakeControllerPairingFlow::DeviceLost(const std::string& device_id) { |
| + CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY); |
| + discovered_devices_.erase(device_id); |
| + FOR_EACH_OBSERVER(Observer, observers_, DiscoveredDevicesListChanged()); |
| +} |
| + |
| +FakeControllerPairingFlow::DiscoveryScenario |
| +FakeControllerPairingFlow::GetDefaultScenario() const { |
| + DiscoveryScenario scenario; |
| + scenario.push_back(std::make_pair(DEVICE_FOUND, "Device_1")); |
| + scenario.push_back(std::make_pair(DEVICE_FOUND, "Device_5")); |
| + scenario.push_back(std::make_pair(DEVICE_FOUND, "Device_3")); |
| + scenario.push_back(std::make_pair(DEVICE_LOST, "Device_3")); |
| + scenario.push_back(std::make_pair(DEVICE_LOST, "Device_1")); |
| + scenario.push_back(std::make_pair(DEVICE_FOUND, "Device_1")); |
| + return scenario; |
| +} |
| + |
| +void FakeControllerPairingFlow::PairingStageChanged(Stage new_stage) { |
| + Stage next_stage = STAGE_NONE; |
| + switch (new_stage) { |
| + case STAGE_DEVICES_DISCOVERY: { |
| + discovered_devices_.clear(); |
| + base::MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + base::Bind(&FakeControllerPairingFlow::ExecuteDiscoveryEvent, |
| + base::Unretained(this), |
| + 0), |
| + async_duration_); |
| + break; |
| + } |
| + case STAGE_ESTABLISHING_CONNECTION: { |
| + if (should_fail_on_connecting_) { |
| + next_stage = STAGE_ESTABLISHING_CONNECTION_ERROR; |
| + should_fail_on_connecting_ = false; |
| + } else { |
| + confirmation_code_.clear(); |
| + next_stage = STAGE_WAITING_FOR_CODE_CONFIRMATION; |
| + } |
| + break; |
| + } |
| + case STAGE_HOST_UPDATE_IN_PROGRESS: { |
| + next_stage = STAGE_WAITING_FOR_CREDENTIALS; |
| + break; |
| + } |
| + case STAGE_HOST_ENROLLMENT_IN_PROGRESS: { |
| + if (enrollment_should_fail_) { |
| + enrollment_should_fail_ = false; |
| + next_stage = STAGE_HOST_ENROLLMENT_ERROR; |
| + } else { |
| + next_stage = STAGE_PAIRING_DONE; |
| + } |
| + break; |
| + } |
| + case STAGE_HOST_CONNECTION_LOST: { |
| + next_stage = connection_lost_end_; |
| + connection_lost_end_ = STAGE_NONE; |
| + break; |
| + } |
| + default: |
| + break; |
| + } |
| + if (new_stage == connection_lost_begin_) { |
| + connection_lost_begin_ = STAGE_NONE; |
| + next_stage = STAGE_HOST_CONNECTION_LOST; |
| + } |
| + if (next_stage != STAGE_NONE) |
| + ChangeStageLater(next_stage); |
| +} |
| + |
| +void FakeControllerPairingFlow::DiscoveredDevicesListChanged() { |
| +} |
| + |
| +} // namespace chromeos |