Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: chromeos/pairing/fake_controller_pairing_flow.cc

Issue 343433003: Implemented fake controller pairing flow. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed GCC compilation. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chromeos/pairing/fake_controller_pairing_flow.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "chromeos/pairing/fake_controller_pairing_flow.h"
6
7 #include <map>
8
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"
16
17 namespace chromeos {
18
19 FakeControllerPairingFlow::FakeControllerPairingFlow(const std::string& config)
20 : current_stage_(STAGE_NONE),
21 should_fail_on_connecting_(false),
22 connection_lost_begin_(STAGE_NONE),
23 connection_lost_end_(STAGE_NONE),
24 enrollment_should_fail_(false) {
25 ApplyConfig(config);
26 AddObserver(this);
27 }
28
29 FakeControllerPairingFlow::~FakeControllerPairingFlow() {
30 RemoveObserver(this);
31 }
32
33 void FakeControllerPairingFlow::ApplyConfig(const std::string& config) {
34 typedef std::vector<std::string> Tokens;
35
36 base::StringPairs kv_pairs;
37 CHECK(base::SplitStringIntoKeyValuePairs(config, ':', ',', &kv_pairs))
38 << "Wrong config format.";
39 std::map<std::string, std::string> dict(kv_pairs.begin(), kv_pairs.end());
40
41 if (dict.count("async_duration")) {
42 int ms = 0;
43 CHECK(base::StringToInt(dict["async_duration"], &ms))
44 << "Wrong 'async_duration' format.";
45 async_duration_ = base::TimeDelta::FromMilliseconds(ms);
46 } else {
47 async_duration_ = base::TimeDelta::FromMilliseconds(3000);
48 }
49
50 should_fail_on_connecting_ =
51 dict.count("fail_connecting") && (dict["fail_connecting"] == "1");
52
53 enrollment_should_fail_ =
54 dict.count("fail_enrollment") && (dict["fail_enrollment"] == "1");
55
56 if (dict.count("connection_lost")) {
57 Tokens lost_begin_end;
58 CHECK(Tokenize(dict["connection_lost"], "-", &lost_begin_end) == 2)
59 << "Wrong 'connection_lost' format.";
60 int begin = 0;
61 int end = 0;
62 CHECK(base::StringToInt(lost_begin_end[0], &begin) &&
63 base::StringToInt(lost_begin_end[1], &end))
64 << "Wrong 'connection_lost' format.";
65 CHECK((begin == 0 && end == 0) ||
66 (STAGE_WAITING_FOR_CODE_CONFIRMATION <= begin && begin <= end &&
67 end <= STAGE_HOST_ENROLLMENT_ERROR))
68 << "Wrong 'connection_lost' interval.";
69 connection_lost_begin_ = static_cast<Stage>(begin);
70 connection_lost_end_ = static_cast<Stage>(end);
71 } else {
72 connection_lost_begin_ = connection_lost_end_ = STAGE_NONE;
73 }
74
75 if (!dict.count("discovery")) {
76 dict["discovery"] =
77 "F-Device_1~F-Device_5~F-Device_3~L-Device_3~L-Device_1~F-Device_1";
78 }
79 base::StringPairs events;
80 CHECK(
81 base::SplitStringIntoKeyValuePairs(dict["discovery"], '-', '~', &events))
82 << "Wrong 'discovery' format.";
83 DiscoveryScenario scenario;
84 for (base::StringPairs::const_iterator event = events.begin();
85 event != events.end();
86 ++event) {
87 std::string type = event->first;
88 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));
95 }
96 SetDiscoveryScenario(scenario);
97
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.";
104 }
105
106 void FakeControllerPairingFlow::SetShouldFailOnConnecting() {
107 should_fail_on_connecting_ = true;
108 }
109
110 void FakeControllerPairingFlow::SetShouldLoseConnection(Stage stage_begin,
111 Stage stage_end) {
112 connection_lost_begin_ = stage_begin;
113 connection_lost_end_ = stage_end;
114 }
115
116 void FakeControllerPairingFlow::SetEnrollmentShouldFail() {
117 enrollment_should_fail_ = true;
118 }
119
120 void FakeControllerPairingFlow::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;
132 }
133 case DEVICE_LOST: {
134 CHECK(devices.count(event->second));
135 devices.erase(event->second);
136 break;
137 }
138 case NOTHING_FOUND: {
139 CHECK(++event == discovery_scenario_.end());
140 return;
141 }
142 }
143 }
144 }
145
146 void FakeControllerPairingFlow::AddObserver(Observer* observer) {
147 observers_.AddObserver(observer);
148 }
149
150 void FakeControllerPairingFlow::RemoveObserver(Observer* observer) {
151 observers_.RemoveObserver(observer);
152 }
153
154 ControllerPairingFlow::Stage FakeControllerPairingFlow::GetCurrentStage() {
155 return current_stage_;
156 }
157
158 void FakeControllerPairingFlow::StartFlow() {
159 CHECK(current_stage_ == STAGE_NONE);
160 ChangeStage(STAGE_DEVICES_DISCOVERY);
161 }
162
163 ControllerPairingFlow::DeviceIdList
164 FakeControllerPairingFlow::GetDiscoveredDevices() {
165 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
166 return DeviceIdList(discovered_devices_.begin(), discovered_devices_.end());
167 }
168
169 void FakeControllerPairingFlow::ChooseDeviceForPairing(
170 const std::string& device_id) {
171 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
172 CHECK(discovered_devices_.count(device_id));
173 choosen_device_ = device_id;
174 ChangeStage(STAGE_ESTABLISHING_CONNECTION);
175 }
176
177 void FakeControllerPairingFlow::RepeatDiscovery() {
178 CHECK(current_stage_ == STAGE_DEVICE_NOT_FOUND ||
179 current_stage_ == STAGE_ESTABLISHING_CONNECTION_ERROR ||
180 current_stage_ == STAGE_HOST_ENROLLMENT_ERROR);
181 ChangeStage(STAGE_DEVICES_DISCOVERY);
182 }
183
184 std::string FakeControllerPairingFlow::GetConfirmationCode() {
185 CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION);
186 if (confirmation_code_.empty()) {
187 if (preset_confirmation_code_.empty()) {
188 for (int i = 0; i < 6; ++i)
189 confirmation_code_.push_back(base::RandInt('0', '9'));
190 } else {
191 confirmation_code_ = preset_confirmation_code_;
192 }
193 }
194 return confirmation_code_;
195 }
196
197 void FakeControllerPairingFlow::SetConfirmationCodeIsCorrect(bool correct) {
198 CHECK(current_stage_ == STAGE_WAITING_FOR_CODE_CONFIRMATION);
199 if (correct)
200 ChangeStage(STAGE_HOST_UPDATE_IN_PROGRESS);
201 else
202 ChangeStage(STAGE_DEVICES_DISCOVERY);
203 }
204
205 void FakeControllerPairingFlow::OnAuthenticationDone(
206 const chromeos::UserContext& user_context,
207 content::BrowserContext* browser_context) {
208 CHECK(current_stage_ == STAGE_WAITING_FOR_CREDENTIALS);
209 ChangeStage(STAGE_HOST_ENROLLMENT_IN_PROGRESS);
210 }
211
212 void FakeControllerPairingFlow::StartSession() {
213 CHECK(current_stage_ == STAGE_PAIRING_DONE);
214 ChangeStage(STAGE_FINISHED);
215 }
216
217 void FakeControllerPairingFlow::ChangeStage(Stage new_stage) {
218 if (current_stage_ == new_stage)
219 return;
220 current_stage_ = new_stage;
221 FOR_EACH_OBSERVER(Observer, observers_, PairingStageChanged(new_stage));
222 }
223
224 void FakeControllerPairingFlow::ChangeStageLater(Stage new_stage) {
225 base::MessageLoop::current()->PostDelayedTask(
226 FROM_HERE,
227 base::Bind(&FakeControllerPairingFlow::ChangeStage,
228 base::Unretained(this),
229 new_stage),
230 async_duration_);
231 }
232
233 void FakeControllerPairingFlow::ExecuteDiscoveryEvent(size_t event_position) {
234 if (current_stage_ != STAGE_DEVICES_DISCOVERY)
235 return;
236 CHECK(event_position < discovery_scenario_.size());
237 const DiscoveryEvent& event = discovery_scenario_[event_position];
238 switch (event.first) {
239 case DEVICE_FOUND: {
240 DeviceFound(event.second);
241 break;
242 }
243 case DEVICE_LOST: {
244 DeviceLost(event.second);
245 break;
246 }
247 case NOTHING_FOUND: {
248 ChangeStage(STAGE_DEVICE_NOT_FOUND);
249 break;
250 }
251 }
252 if (++event_position == discovery_scenario_.size()) {
253 return;
254 }
255 base::MessageLoop::current()->PostDelayedTask(
256 FROM_HERE,
257 base::Bind(&FakeControllerPairingFlow::ExecuteDiscoveryEvent,
258 base::Unretained(this),
259 event_position),
260 async_duration_);
261 }
262
263 void FakeControllerPairingFlow::DeviceFound(const std::string& device_id) {
264 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
265 discovered_devices_.insert(device_id);
266 FOR_EACH_OBSERVER(Observer, observers_, DiscoveredDevicesListChanged());
267 }
268
269 void FakeControllerPairingFlow::DeviceLost(const std::string& device_id) {
270 CHECK(current_stage_ == STAGE_DEVICES_DISCOVERY);
271 discovered_devices_.erase(device_id);
272 FOR_EACH_OBSERVER(Observer, observers_, DiscoveredDevicesListChanged());
273 }
274
275 void FakeControllerPairingFlow::PairingStageChanged(Stage new_stage) {
276 Stage next_stage = STAGE_NONE;
277 switch (new_stage) {
278 case STAGE_DEVICES_DISCOVERY: {
279 discovered_devices_.clear();
280 base::MessageLoop::current()->PostDelayedTask(
281 FROM_HERE,
282 base::Bind(&FakeControllerPairingFlow::ExecuteDiscoveryEvent,
283 base::Unretained(this),
284 0),
285 async_duration_);
286 break;
287 }
288 case STAGE_ESTABLISHING_CONNECTION: {
289 if (should_fail_on_connecting_) {
290 next_stage = STAGE_ESTABLISHING_CONNECTION_ERROR;
291 should_fail_on_connecting_ = false;
292 } else {
293 confirmation_code_.clear();
294 next_stage = STAGE_WAITING_FOR_CODE_CONFIRMATION;
295 }
296 break;
297 }
298 case STAGE_HOST_UPDATE_IN_PROGRESS: {
299 next_stage = STAGE_WAITING_FOR_CREDENTIALS;
300 break;
301 }
302 case STAGE_HOST_ENROLLMENT_IN_PROGRESS: {
303 if (enrollment_should_fail_) {
304 enrollment_should_fail_ = false;
305 next_stage = STAGE_HOST_ENROLLMENT_ERROR;
306 } else {
307 next_stage = STAGE_PAIRING_DONE;
308 }
309 break;
310 }
311 case STAGE_HOST_CONNECTION_LOST: {
312 next_stage = connection_lost_end_;
313 connection_lost_end_ = STAGE_NONE;
314 break;
315 }
316 default:
317 break;
318 }
319 if (new_stage == connection_lost_begin_) {
320 connection_lost_begin_ = STAGE_NONE;
321 next_stage = STAGE_HOST_CONNECTION_LOST;
322 }
323 if (next_stage != STAGE_NONE)
324 ChangeStageLater(next_stage);
325 }
326
327 void FakeControllerPairingFlow::DiscoveredDevicesListChanged() {
328 }
329
330 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/pairing/fake_controller_pairing_flow.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698