Blink roll a6d61dbff0a4bce30fce5b29c2efb77a94ddc3ee:a11635f657e0f1ce75179fd7336a309a6...
[chromium-blink-merge.git] / components / pairing / fake_controller_pairing_controller.cc
blob0b05ee6a9e5c61f0b83bd0c3a0ae7b0d982a1034
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;
59 CHECK(Tokenize(dict["connection_lost"], "-", &lost_begin_end) == 2)
60 << "Wrong 'connection_lost' format.";
61 int begin = 0;
62 int end = 0;
63 CHECK(base::StringToInt(lost_begin_end[0], &begin) &&
64 base::StringToInt(lost_begin_end[1], &end))
65 << "Wrong 'connection_lost' format.";
66 CHECK((begin == 0 && end == 0) ||
67 (STAGE_WAITING_FOR_CODE_CONFIRMATION <= begin && begin <= end &&
68 end <= STAGE_HOST_ENROLLMENT_ERROR))
69 << "Wrong 'connection_lost' interval.";
70 connection_lost_begin_ = static_cast<Stage>(begin);
71 connection_lost_end_ = static_cast<Stage>(end);
72 } else {
73 connection_lost_begin_ = connection_lost_end_ = STAGE_NONE;
76 if (!dict.count("discovery")) {
77 dict["discovery"] =
78 "F-Device_1~F-Device_5~F-Device_3~L-Device_3~L-Device_1~F-Device_1";
80 base::StringPairs events;
81 CHECK(
82 base::SplitStringIntoKeyValuePairs(dict["discovery"], '-', '~', &events))
83 << "Wrong 'discovery' format.";
84 DiscoveryScenario scenario;
85 for (base::StringPairs::const_iterator event = events.begin();
86 event != events.end();
87 ++event) {
88 std::string type = event->first;
89 std::string device_id = event->second;
90 CHECK(type == "F" || type == "L" || type == "N")
91 << "Wrong discovery event type.";
92 CHECK(!device_id.empty() || type == "N") << "Empty device ID.";
93 scenario.push_back(DiscoveryEvent(
94 type == "F" ? DEVICE_FOUND : type == "L" ? DEVICE_LOST : NOTHING_FOUND,
95 device_id));
97 SetDiscoveryScenario(scenario);
99 preset_confirmation_code_ = dict["code"];
100 CHECK(preset_confirmation_code_.empty() ||
101 (preset_confirmation_code_.length() == 6 &&
102 preset_confirmation_code_.find_first_not_of("0123456789") ==
103 std::string::npos))
104 << "Wrong 'code' format.";
107 void FakeControllerPairingController::SetShouldFailOnConnecting() {
108 should_fail_on_connecting_ = true;
111 void FakeControllerPairingController::SetShouldLoseConnection(Stage stage_begin,
112 Stage stage_end) {
113 connection_lost_begin_ = stage_begin;
114 connection_lost_end_ = stage_end;
117 void FakeControllerPairingController::SetEnrollmentShouldFail() {
118 enrollment_should_fail_ = true;
121 void FakeControllerPairingController::SetDiscoveryScenario(
122 const DiscoveryScenario& discovery_scenario) {
123 discovery_scenario_ = discovery_scenario;
124 // Check that scenario is valid.
125 std::set<std::string> devices;
126 for (DiscoveryScenario::const_iterator event = discovery_scenario_.begin();
127 event != discovery_scenario_.end();
128 ++event) {
129 switch (event->first) {
130 case DEVICE_FOUND: {
131 devices.insert(event->second);
132 break;
134 case DEVICE_LOST: {
135 CHECK(devices.count(event->second));
136 devices.erase(event->second);
137 break;
139 case NOTHING_FOUND: {
140 CHECK(++event == discovery_scenario_.end());
141 return;
147 void FakeControllerPairingController::AddObserver(Observer* observer) {
148 observers_.AddObserver(observer);
151 void FakeControllerPairingController::RemoveObserver(Observer* observer) {
152 observers_.RemoveObserver(observer);
155 ControllerPairingController::Stage
156 FakeControllerPairingController::GetCurrentStage() {
157 return current_stage_;
160 void FakeControllerPairingController::StartPairing() {
161 CHECK(current_stage_ == STAGE_NONE);
162 ChangeStage(STAGE_DEVICES_DISCOVERY);
165 ControllerPairingController::DeviceIdList
166 FakeControllerPairingController::GetDiscoveredDevices() {
167 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
168 return DeviceIdList(discovered_devices_.begin(), discovered_devices_.end());
171 void FakeControllerPairingController::ChooseDeviceForPairing(
172 const std::string& device_id) {
173 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
174 CHECK(discovered_devices_.count(device_id));
175 choosen_device_ = device_id;
176 ChangeStage(STAGE_ESTABLISHING_CONNECTION);
179 void FakeControllerPairingController::RepeatDiscovery() {
180 CHECK(current_stage_ == STAGE_DEVICE_NOT_FOUND ||
181 current_stage_ == STAGE_ESTABLISHING_CONNECTION_ERROR ||
182 current_stage_ == STAGE_HOST_ENROLLMENT_ERROR);
183 ChangeStage(STAGE_DEVICES_DISCOVERY);
186 std::string FakeControllerPairingController::GetConfirmationCode() {
187 CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION);
188 if (confirmation_code_.empty()) {
189 if (preset_confirmation_code_.empty()) {
190 for (int i = 0; i < 6; ++i)
191 confirmation_code_.push_back(base::RandInt('0', '9'));
192 } else {
193 confirmation_code_ = preset_confirmation_code_;
196 return confirmation_code_;
199 void FakeControllerPairingController::SetConfirmationCodeIsCorrect(
200 bool correct) {
201 CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION);
202 if (correct)
203 ChangeStage(STAGE_HOST_UPDATE_IN_PROGRESS);
204 else
205 ChangeStage(STAGE_DEVICES_DISCOVERY);
208 void FakeControllerPairingController::SetHostConfiguration(
209 bool accepted_eula,
210 const std::string& lang,
211 const std::string& timezone,
212 bool send_reports,
213 const std::string& keyboard_layout) {
216 void FakeControllerPairingController::OnAuthenticationDone(
217 const std::string& domain,
218 const std::string& auth_token) {
219 CHECK(current_stage_ == STAGE_WAITING_FOR_CREDENTIALS);
220 ChangeStage(STAGE_HOST_ENROLLMENT_IN_PROGRESS);
223 void FakeControllerPairingController::StartSession() {
224 CHECK(current_stage_ == STAGE_PAIRING_DONE);
225 ChangeStage(STAGE_FINISHED);
228 void FakeControllerPairingController::ChangeStage(Stage new_stage) {
229 if (current_stage_ == new_stage)
230 return;
231 current_stage_ = new_stage;
232 FOR_EACH_OBSERVER(Observer, observers_, PairingStageChanged(new_stage));
235 void FakeControllerPairingController::ChangeStageLater(Stage new_stage) {
236 base::MessageLoop::current()->PostDelayedTask(
237 FROM_HERE,
238 base::Bind(&FakeControllerPairingController::ChangeStage,
239 base::Unretained(this),
240 new_stage),
241 async_duration_);
244 void FakeControllerPairingController::ExecuteDiscoveryEvent(
245 size_t event_position) {
246 if (current_stage_ != STAGE_DEVICES_DISCOVERY)
247 return;
248 CHECK(event_position < discovery_scenario_.size());
249 const DiscoveryEvent& event = discovery_scenario_[event_position];
250 switch (event.first) {
251 case DEVICE_FOUND: {
252 DeviceFound(event.second);
253 break;
255 case DEVICE_LOST: {
256 DeviceLost(event.second);
257 break;
259 case NOTHING_FOUND: {
260 ChangeStage(STAGE_DEVICE_NOT_FOUND);
261 break;
264 if (++event_position == discovery_scenario_.size()) {
265 return;
267 base::MessageLoop::current()->PostDelayedTask(
268 FROM_HERE,
269 base::Bind(&FakeControllerPairingController::ExecuteDiscoveryEvent,
270 base::Unretained(this),
271 event_position),
272 async_duration_);
275 void FakeControllerPairingController::DeviceFound(
276 const std::string& device_id) {
277 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
278 discovered_devices_.insert(device_id);
279 FOR_EACH_OBSERVER(Observer, observers_, DiscoveredDevicesListChanged());
282 void FakeControllerPairingController::DeviceLost(const std::string& device_id) {
283 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
284 discovered_devices_.erase(device_id);
285 FOR_EACH_OBSERVER(Observer, observers_, DiscoveredDevicesListChanged());
288 void FakeControllerPairingController::PairingStageChanged(Stage new_stage) {
289 Stage next_stage = STAGE_NONE;
290 switch (new_stage) {
291 case STAGE_DEVICES_DISCOVERY: {
292 discovered_devices_.clear();
293 base::MessageLoop::current()->PostDelayedTask(
294 FROM_HERE,
295 base::Bind(&FakeControllerPairingController::ExecuteDiscoveryEvent,
296 base::Unretained(this),
298 async_duration_);
299 break;
301 case STAGE_ESTABLISHING_CONNECTION: {
302 if (should_fail_on_connecting_) {
303 next_stage = STAGE_ESTABLISHING_CONNECTION_ERROR;
304 should_fail_on_connecting_ = false;
305 } else {
306 confirmation_code_.clear();
307 next_stage = STAGE_WAITING_FOR_CODE_CONFIRMATION;
309 break;
311 case STAGE_HOST_UPDATE_IN_PROGRESS: {
312 next_stage = STAGE_WAITING_FOR_CREDENTIALS;
313 break;
315 case STAGE_HOST_ENROLLMENT_IN_PROGRESS: {
316 if (enrollment_should_fail_) {
317 enrollment_should_fail_ = false;
318 next_stage = STAGE_HOST_ENROLLMENT_ERROR;
319 } else {
320 next_stage = STAGE_PAIRING_DONE;
322 break;
324 case STAGE_HOST_CONNECTION_LOST: {
325 next_stage = connection_lost_end_;
326 connection_lost_end_ = STAGE_NONE;
327 break;
329 default:
330 break;
332 if (new_stage == connection_lost_begin_) {
333 connection_lost_begin_ = STAGE_NONE;
334 next_stage = STAGE_HOST_CONNECTION_LOST;
336 if (next_stage != STAGE_NONE)
337 ChangeStageLater(next_stage);
340 void FakeControllerPairingController::DiscoveredDevicesListChanged() {
343 } // namespace pairing_chromeos