Allow only one bookmark to be added for multiple fast starring
[chromium-blink-merge.git] / components / pairing / fake_controller_pairing_controller.cc
blobff24b9e0055ca7d9b3b611cc26a6baf1e0dc2ba8
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 "components/pairing/fake_controller_pairing_controller.h"
7 #include <map>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/rand_util.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_split.h"
15 #include "base/strings/string_util.h"
17 namespace pairing_chromeos {
19 FakeControllerPairingController::FakeControllerPairingController(
20 const std::string& config)
21 : current_stage_(STAGE_NONE),
22 should_fail_on_connecting_(false),
23 connection_lost_begin_(STAGE_NONE),
24 connection_lost_end_(STAGE_NONE),
25 enrollment_should_fail_(false) {
26 ApplyConfig(config);
27 AddObserver(this);
30 FakeControllerPairingController::~FakeControllerPairingController() {
31 RemoveObserver(this);
34 void FakeControllerPairingController::ApplyConfig(const std::string& config) {
35 typedef std::vector<std::string> Tokens;
37 base::StringPairs kv_pairs;
38 CHECK(base::SplitStringIntoKeyValuePairs(config, ':', ',', &kv_pairs))
39 << "Wrong config format.";
40 std::map<std::string, std::string> dict(kv_pairs.begin(), kv_pairs.end());
42 if (dict.count("async_duration")) {
43 int ms = 0;
44 CHECK(base::StringToInt(dict["async_duration"], &ms))
45 << "Wrong 'async_duration' format.";
46 async_duration_ = base::TimeDelta::FromMilliseconds(ms);
47 } else {
48 async_duration_ = base::TimeDelta::FromMilliseconds(3000);
51 should_fail_on_connecting_ =
52 dict.count("fail_connecting") && (dict["fail_connecting"] == "1");
54 enrollment_should_fail_ =
55 dict.count("fail_enrollment") && (dict["fail_enrollment"] == "1");
57 if (dict.count("connection_lost")) {
58 Tokens lost_begin_end = base::SplitString(
59 dict["connection_lost"], "-", base::KEEP_WHITESPACE,
60 base::SPLIT_WANT_NONEMPTY);
61 CHECK_EQ(2u, lost_begin_end.size()) << "Wrong 'connection_lost' format.";
62 int begin = 0;
63 int end = 0;
64 CHECK(base::StringToInt(lost_begin_end[0], &begin) &&
65 base::StringToInt(lost_begin_end[1], &end))
66 << "Wrong 'connection_lost' format.";
67 CHECK((begin == 0 && end == 0) ||
68 (STAGE_WAITING_FOR_CODE_CONFIRMATION <= begin && begin <= end &&
69 end <= STAGE_HOST_ENROLLMENT_ERROR))
70 << "Wrong 'connection_lost' interval.";
71 connection_lost_begin_ = static_cast<Stage>(begin);
72 connection_lost_end_ = static_cast<Stage>(end);
73 } else {
74 connection_lost_begin_ = connection_lost_end_ = STAGE_NONE;
77 if (!dict.count("discovery")) {
78 dict["discovery"] =
79 "F-Device_1~F-Device_5~F-Device_3~L-Device_3~L-Device_1~F-Device_1";
81 base::StringPairs events;
82 CHECK(
83 base::SplitStringIntoKeyValuePairs(dict["discovery"], '-', '~', &events))
84 << "Wrong 'discovery' format.";
85 DiscoveryScenario scenario;
86 for (const auto& event : events) {
87 const std::string& type = event.first;
88 const std::string& device_id = event.second;
89 CHECK(type == "F" || type == "L" || type == "N")
90 << "Wrong discovery event type.";
91 CHECK(!device_id.empty() || type == "N") << "Empty device ID.";
92 scenario.push_back(DiscoveryEvent(
93 type == "F" ? DEVICE_FOUND : type == "L" ? DEVICE_LOST : NOTHING_FOUND,
94 device_id));
96 SetDiscoveryScenario(scenario);
98 preset_confirmation_code_ = dict["code"];
99 CHECK(preset_confirmation_code_.empty() ||
100 (preset_confirmation_code_.length() == 6 &&
101 preset_confirmation_code_.find_first_not_of("0123456789") ==
102 std::string::npos))
103 << "Wrong 'code' format.";
106 void FakeControllerPairingController::SetShouldFailOnConnecting() {
107 should_fail_on_connecting_ = true;
110 void FakeControllerPairingController::SetShouldLoseConnection(Stage stage_begin,
111 Stage stage_end) {
112 connection_lost_begin_ = stage_begin;
113 connection_lost_end_ = stage_end;
116 void FakeControllerPairingController::SetEnrollmentShouldFail() {
117 enrollment_should_fail_ = true;
120 void FakeControllerPairingController::SetDiscoveryScenario(
121 const DiscoveryScenario& discovery_scenario) {
122 discovery_scenario_ = discovery_scenario;
123 // Check that scenario is valid.
124 std::set<std::string> devices;
125 for (DiscoveryScenario::const_iterator event = discovery_scenario_.begin();
126 event != discovery_scenario_.end();
127 ++event) {
128 switch (event->first) {
129 case DEVICE_FOUND: {
130 devices.insert(event->second);
131 break;
133 case DEVICE_LOST: {
134 CHECK(devices.count(event->second));
135 devices.erase(event->second);
136 break;
138 case NOTHING_FOUND: {
139 CHECK(++event == discovery_scenario_.end());
140 return;
146 void FakeControllerPairingController::AddObserver(Observer* observer) {
147 observers_.AddObserver(observer);
150 void FakeControllerPairingController::RemoveObserver(Observer* observer) {
151 observers_.RemoveObserver(observer);
154 ControllerPairingController::Stage
155 FakeControllerPairingController::GetCurrentStage() {
156 return current_stage_;
159 void FakeControllerPairingController::StartPairing() {
160 CHECK(current_stage_ == STAGE_NONE);
161 ChangeStage(STAGE_DEVICES_DISCOVERY);
164 ControllerPairingController::DeviceIdList
165 FakeControllerPairingController::GetDiscoveredDevices() {
166 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
167 return DeviceIdList(discovered_devices_.begin(), discovered_devices_.end());
170 void FakeControllerPairingController::ChooseDeviceForPairing(
171 const std::string& device_id) {
172 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
173 CHECK(discovered_devices_.count(device_id));
174 choosen_device_ = device_id;
175 ChangeStage(STAGE_ESTABLISHING_CONNECTION);
178 void FakeControllerPairingController::RepeatDiscovery() {
179 CHECK(current_stage_ == STAGE_DEVICE_NOT_FOUND ||
180 current_stage_ == STAGE_ESTABLISHING_CONNECTION_ERROR ||
181 current_stage_ == STAGE_HOST_ENROLLMENT_ERROR);
182 ChangeStage(STAGE_DEVICES_DISCOVERY);
185 std::string FakeControllerPairingController::GetConfirmationCode() {
186 CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION);
187 if (confirmation_code_.empty()) {
188 if (preset_confirmation_code_.empty()) {
189 for (int i = 0; i < 6; ++i)
190 confirmation_code_.push_back(base::RandInt('0', '9'));
191 } else {
192 confirmation_code_ = preset_confirmation_code_;
195 return confirmation_code_;
198 void FakeControllerPairingController::SetConfirmationCodeIsCorrect(
199 bool correct) {
200 CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION);
201 if (correct)
202 ChangeStage(STAGE_HOST_UPDATE_IN_PROGRESS);
203 else
204 ChangeStage(STAGE_DEVICES_DISCOVERY);
207 void FakeControllerPairingController::SetHostConfiguration(
208 bool accepted_eula,
209 const std::string& lang,
210 const std::string& timezone,
211 bool send_reports,
212 const std::string& keyboard_layout) {
215 void FakeControllerPairingController::OnAuthenticationDone(
216 const std::string& domain,
217 const std::string& auth_token) {
218 CHECK(current_stage_ == STAGE_WAITING_FOR_CREDENTIALS);
219 ChangeStage(STAGE_HOST_ENROLLMENT_IN_PROGRESS);
222 void FakeControllerPairingController::StartSession() {
223 CHECK(current_stage_ == STAGE_HOST_ENROLLMENT_SUCCESS);
224 ChangeStage(STAGE_FINISHED);
227 void FakeControllerPairingController::ChangeStage(Stage new_stage) {
228 if (current_stage_ == new_stage)
229 return;
230 current_stage_ = new_stage;
231 FOR_EACH_OBSERVER(Observer, observers_, PairingStageChanged(new_stage));
234 void FakeControllerPairingController::ChangeStageLater(Stage new_stage) {
235 base::MessageLoop::current()->PostDelayedTask(
236 FROM_HERE,
237 base::Bind(&FakeControllerPairingController::ChangeStage,
238 base::Unretained(this),
239 new_stage),
240 async_duration_);
243 void FakeControllerPairingController::ExecuteDiscoveryEvent(
244 size_t event_position) {
245 if (current_stage_ != STAGE_DEVICES_DISCOVERY)
246 return;
247 CHECK(event_position < discovery_scenario_.size());
248 const DiscoveryEvent& event = discovery_scenario_[event_position];
249 switch (event.first) {
250 case DEVICE_FOUND: {
251 DeviceFound(event.second);
252 break;
254 case DEVICE_LOST: {
255 DeviceLost(event.second);
256 break;
258 case NOTHING_FOUND: {
259 ChangeStage(STAGE_DEVICE_NOT_FOUND);
260 break;
263 if (++event_position == discovery_scenario_.size()) {
264 return;
266 base::MessageLoop::current()->PostDelayedTask(
267 FROM_HERE,
268 base::Bind(&FakeControllerPairingController::ExecuteDiscoveryEvent,
269 base::Unretained(this),
270 event_position),
271 async_duration_);
274 void FakeControllerPairingController::DeviceFound(
275 const std::string& device_id) {
276 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
277 discovered_devices_.insert(device_id);
278 FOR_EACH_OBSERVER(Observer, observers_, DiscoveredDevicesListChanged());
281 void FakeControllerPairingController::DeviceLost(const std::string& device_id) {
282 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
283 discovered_devices_.erase(device_id);
284 FOR_EACH_OBSERVER(Observer, observers_, DiscoveredDevicesListChanged());
287 void FakeControllerPairingController::PairingStageChanged(Stage new_stage) {
288 Stage next_stage = STAGE_NONE;
289 switch (new_stage) {
290 case STAGE_DEVICES_DISCOVERY: {
291 discovered_devices_.clear();
292 base::MessageLoop::current()->PostDelayedTask(
293 FROM_HERE,
294 base::Bind(&FakeControllerPairingController::ExecuteDiscoveryEvent,
295 base::Unretained(this),
297 async_duration_);
298 break;
300 case STAGE_ESTABLISHING_CONNECTION: {
301 if (should_fail_on_connecting_) {
302 next_stage = STAGE_ESTABLISHING_CONNECTION_ERROR;
303 should_fail_on_connecting_ = false;
304 } else {
305 confirmation_code_.clear();
306 next_stage = STAGE_WAITING_FOR_CODE_CONFIRMATION;
308 break;
310 case STAGE_HOST_UPDATE_IN_PROGRESS: {
311 next_stage = STAGE_WAITING_FOR_CREDENTIALS;
312 break;
314 case STAGE_HOST_ENROLLMENT_IN_PROGRESS: {
315 if (enrollment_should_fail_) {
316 enrollment_should_fail_ = false;
317 next_stage = STAGE_HOST_ENROLLMENT_ERROR;
318 } else {
319 next_stage = STAGE_HOST_ENROLLMENT_SUCCESS;
321 break;
323 case STAGE_HOST_CONNECTION_LOST: {
324 next_stage = connection_lost_end_;
325 connection_lost_end_ = STAGE_NONE;
326 break;
328 default:
329 break;
331 if (new_stage == connection_lost_begin_) {
332 connection_lost_begin_ = STAGE_NONE;
333 next_stage = STAGE_HOST_CONNECTION_LOST;
335 if (next_stage != STAGE_NONE)
336 ChangeStageLater(next_stage);
339 void FakeControllerPairingController::DiscoveredDevicesListChanged() {
342 } // namespace pairing_chromeos